mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
smbd: We don't use DEFERRED_OPEN_ENTRY anymore
Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
8da5a0f1e3
commit
a7e803485d
@ -673,12 +673,12 @@ enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT,
|
||||
#define FAKE_LEVEL_II_OPLOCK 0x10 /* Client requested no_oplock, but we have to
|
||||
* inform potential level2 holders on
|
||||
* write. */
|
||||
#define DEFERRED_OPEN_ENTRY 0x20
|
||||
/* #define DEFERRED_OPEN_ENTRY 0x20 */ /* Not used anymore */
|
||||
/* #define UNUSED_SHARE_MODE_ENTRY 0x40 */ /* Not used anymore */
|
||||
#define FORCE_OPLOCK_BREAK_TO_NONE 0x80
|
||||
|
||||
/* None of the following should ever appear in fsp->oplock_request. */
|
||||
#define SAMBA_PRIVATE_OPLOCK_MASK (INTERNAL_OPEN_ONLY|DEFERRED_OPEN_ENTRY|FORCE_OPLOCK_BREAK_TO_NONE)
|
||||
#define SAMBA_PRIVATE_OPLOCK_MASK (INTERNAL_OPEN_ONLY|FORCE_OPLOCK_BREAK_TO_NONE)
|
||||
|
||||
#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)EXCLUSIVE_OPLOCK|(unsigned int)BATCH_OPLOCK))
|
||||
#define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK)
|
||||
|
@ -270,11 +270,6 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
|
||||
continue; /* No longer exists. */
|
||||
}
|
||||
|
||||
/* Ignore deferred open entries. */
|
||||
if (share->op_type == DEFERRED_OPEN_ENTRY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Copy into the external list. */
|
||||
sme->dev = share->id.devid;
|
||||
sme->ino = share->id.inode;
|
||||
|
@ -627,11 +627,6 @@ bool is_valid_share_mode_entry(const struct share_mode_entry *e)
|
||||
return (num_props != 0);
|
||||
}
|
||||
|
||||
bool is_deferred_open_entry(const struct share_mode_entry *e)
|
||||
{
|
||||
return (e->op_type == DEFERRED_OPEN_ENTRY);
|
||||
}
|
||||
|
||||
/*
|
||||
* In case d->share_modes[i] conflicts with something or otherwise is
|
||||
* being used, we need to make sure the corresponding process still
|
||||
@ -699,23 +694,6 @@ static void fill_share_mode_entry(struct share_mode_entry *e,
|
||||
e->name_hash = fsp->name_hash;
|
||||
}
|
||||
|
||||
static void fill_deferred_open_entry(struct share_mode_entry *e,
|
||||
const struct timeval request_time,
|
||||
struct file_id id,
|
||||
struct server_id pid,
|
||||
uint64_t mid)
|
||||
{
|
||||
ZERO_STRUCTP(e);
|
||||
e->pid = pid;
|
||||
e->op_mid = mid;
|
||||
e->op_type = DEFERRED_OPEN_ENTRY;
|
||||
e->time.tv_sec = request_time.tv_sec;
|
||||
e->time.tv_usec = request_time.tv_usec;
|
||||
e->id = id;
|
||||
e->uid = (uint32)-1;
|
||||
e->flags = 0;
|
||||
}
|
||||
|
||||
static void add_share_mode_entry(struct share_mode_data *d,
|
||||
const struct share_mode_entry *entry)
|
||||
{
|
||||
@ -732,15 +710,6 @@ void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
|
||||
add_share_mode_entry(lck->data, &entry);
|
||||
}
|
||||
|
||||
void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
|
||||
struct timeval request_time,
|
||||
struct server_id pid, struct file_id id)
|
||||
{
|
||||
struct share_mode_entry entry;
|
||||
fill_deferred_open_entry(&entry, request_time, id, pid, mid);
|
||||
add_share_mode_entry(lck->data, &entry);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Check if two share mode entries are identical, ignoring oplock
|
||||
and mid info and desired_access. (Removed paranoia test - it's
|
||||
@ -760,14 +729,6 @@ static bool share_modes_identical(struct share_mode_entry *e1,
|
||||
e1->share_file_id == e2->share_file_id );
|
||||
}
|
||||
|
||||
static bool deferred_open_identical(struct share_mode_entry *e1,
|
||||
struct share_mode_entry *e2)
|
||||
{
|
||||
return (serverid_equal(&e1->pid, &e2->pid) &&
|
||||
(e1->op_mid == e2->op_mid) &&
|
||||
file_id_equal(&e1->id, &e2->id));
|
||||
}
|
||||
|
||||
static struct share_mode_entry *find_share_mode_entry(struct share_mode_data *d,
|
||||
struct share_mode_entry *entry)
|
||||
{
|
||||
@ -780,11 +741,6 @@ static struct share_mode_entry *find_share_mode_entry(struct share_mode_data *d,
|
||||
share_modes_identical(e, entry)) {
|
||||
return e;
|
||||
}
|
||||
if (is_deferred_open_entry(entry) &&
|
||||
is_deferred_open_entry(e) &&
|
||||
deferred_open_identical(e, entry)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -849,23 +805,6 @@ bool mark_share_mode_disconnected(struct share_mode_lock *lck,
|
||||
return true;
|
||||
}
|
||||
|
||||
void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
|
||||
struct server_id pid)
|
||||
{
|
||||
struct share_mode_entry entry, *e;
|
||||
|
||||
fill_deferred_open_entry(&entry, timeval_zero(),
|
||||
lck->data->id, pid, mid);
|
||||
|
||||
e = find_share_mode_entry(lck->data, &entry);
|
||||
if (e == NULL) {
|
||||
return;
|
||||
}
|
||||
*e = lck->data->share_modes[lck->data->num_share_modes-1];
|
||||
lck->data->num_share_modes -= 1;
|
||||
lck->data->modified = True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Remove an oplock mid and mode entry from a share mode.
|
||||
********************************************************************/
|
||||
|
@ -170,18 +170,12 @@ void get_file_infos(struct file_id id,
|
||||
bool *delete_on_close,
|
||||
struct timespec *write_time);
|
||||
bool is_valid_share_mode_entry(const struct share_mode_entry *e);
|
||||
bool is_deferred_open_entry(const struct share_mode_entry *e);
|
||||
bool share_mode_stale_pid(struct share_mode_data *d, unsigned i);
|
||||
void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
|
||||
uid_t uid, uint64_t mid, uint16 op_type);
|
||||
void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
|
||||
struct timeval request_time,
|
||||
struct server_id pid, struct file_id id);
|
||||
bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp);
|
||||
bool mark_share_mode_disconnected(struct share_mode_lock *lck,
|
||||
struct files_struct *fsp);
|
||||
void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
|
||||
struct server_id pid);
|
||||
bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp);
|
||||
bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp);
|
||||
bool get_delete_on_close_token(struct share_mode_lock *lck,
|
||||
|
@ -164,88 +164,6 @@ static int compare_share_mode_times(const void *p1, const void *p2)
|
||||
return timeval_compare(&s1->time, &s2->time);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
If any deferred opens are waiting on this close, notify them.
|
||||
****************************************************************************/
|
||||
|
||||
static void notify_deferred_opens(struct smbd_server_connection *sconn,
|
||||
struct share_mode_lock *lck)
|
||||
{
|
||||
struct server_id self = messaging_server_id(sconn->msg_ctx);
|
||||
uint32_t i, num_deferred;
|
||||
struct share_mode_entry *deferred;
|
||||
|
||||
if (!should_notify_deferred_opens(sconn)) {
|
||||
return;
|
||||
}
|
||||
|
||||
num_deferred = 0;
|
||||
for (i=0; i<lck->data->num_share_modes; i++) {
|
||||
struct share_mode_entry *e = &lck->data->share_modes[i];
|
||||
|
||||
if (!is_deferred_open_entry(e)) {
|
||||
continue;
|
||||
}
|
||||
if (share_mode_stale_pid(lck->data, i)) {
|
||||
continue;
|
||||
}
|
||||
num_deferred += 1;
|
||||
}
|
||||
if (num_deferred == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
deferred = talloc_array(talloc_tos(), struct share_mode_entry,
|
||||
num_deferred);
|
||||
if (deferred == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
num_deferred = 0;
|
||||
for (i=0; i<lck->data->num_share_modes; i++) {
|
||||
struct share_mode_entry *e = &lck->data->share_modes[i];
|
||||
if (is_deferred_open_entry(e)) {
|
||||
deferred[num_deferred] = *e;
|
||||
num_deferred += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to sort the notifications by initial request time. Imagine
|
||||
* two opens come in asyncronously, both conflicting with the open we
|
||||
* just close here. If we don't sort the notifications, the one that
|
||||
* came in last might get the response before the one that came in
|
||||
* first. This is demonstrated with the smbtorture4 raw.mux test.
|
||||
*
|
||||
* As long as we had the UNUSED_SHARE_MODE_ENTRY, we happened to
|
||||
* survive this particular test. Without UNUSED_SHARE_MODE_ENTRY, we
|
||||
* shuffle the share mode entries around a bit, so that we do not
|
||||
* survive raw.mux anymore.
|
||||
*
|
||||
* We could have kept the ordering in del_share_mode, but as the
|
||||
* ordering was never formalized I think it is better to do it here
|
||||
* where it is necessary.
|
||||
*/
|
||||
|
||||
qsort(deferred, num_deferred, sizeof(struct share_mode_entry),
|
||||
compare_share_mode_times);
|
||||
|
||||
for (i=0; i<num_deferred; i++) {
|
||||
struct share_mode_entry *e = &deferred[i];
|
||||
|
||||
if (serverid_equal(&self, &e->pid)) {
|
||||
/*
|
||||
* We need to notify ourself to retry the open. Do
|
||||
* this by finding the queued SMB record, moving it to
|
||||
* the head of the queue and changing the wait time to
|
||||
* zero.
|
||||
*/
|
||||
schedule_deferred_open_message_smb(sconn, e->op_mid);
|
||||
}
|
||||
}
|
||||
TALLOC_FREE(deferred);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Delete all streams
|
||||
****************************************************************************/
|
||||
@ -431,9 +349,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify any deferred opens waiting on this close. */
|
||||
notify_deferred_opens(conn->sconn, lck);
|
||||
|
||||
/*
|
||||
* NT can set delete_on_close of the last open
|
||||
* reference to a file.
|
||||
|
@ -1025,16 +1025,6 @@ static void validate_my_share_entries(struct smbd_server_connection *sconn,
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_deferred_open_entry(share_entry) &&
|
||||
!open_was_deferred(sconn, share_entry->op_mid))
|
||||
{
|
||||
char *str = talloc_asprintf(talloc_tos(),
|
||||
"Got a deferred entry without a request: "
|
||||
"PANIC: %s\n",
|
||||
share_mode_str(talloc_tos(), num, share_entry));
|
||||
smb_panic(str);
|
||||
}
|
||||
|
||||
if (!is_valid_share_mode_entry(share_entry)) {
|
||||
return;
|
||||
}
|
||||
@ -1048,10 +1038,6 @@ static void validate_my_share_entries(struct smbd_server_connection *sconn,
|
||||
"share entry with an open file\n");
|
||||
}
|
||||
|
||||
if (is_deferred_open_entry(share_entry)) {
|
||||
goto panic;
|
||||
}
|
||||
|
||||
if ((share_entry->op_type == NO_OPLOCK) &&
|
||||
(fsp->oplock_type == FAKE_LEVEL_II_OPLOCK))
|
||||
{
|
||||
@ -1475,30 +1461,6 @@ static void defer_open(struct share_mode_lock *lck,
|
||||
struct smb_request *req,
|
||||
struct deferred_open_record *state)
|
||||
{
|
||||
struct server_id self = messaging_server_id(req->sconn->msg_ctx);
|
||||
|
||||
/* Paranoia check */
|
||||
|
||||
if (lck) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<lck->data->num_share_modes; i++) {
|
||||
struct share_mode_entry *e = &lck->data->share_modes[i];
|
||||
|
||||
if (is_deferred_open_entry(e) &&
|
||||
serverid_equal(&self, &e->pid) &&
|
||||
(e->op_mid == req->mid)) {
|
||||
DEBUG(0, ("Trying to defer an already deferred "
|
||||
"request: mid=%llu, exiting\n",
|
||||
(unsigned long long)req->mid));
|
||||
TALLOC_FREE(lck);
|
||||
exit_server("attempt to defer a deferred request");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End paranoia check */
|
||||
|
||||
DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
|
||||
"open entry for mid %llu\n",
|
||||
(unsigned int)request_time.tv_sec,
|
||||
@ -1867,19 +1829,6 @@ NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
|
||||
Remove the deferred open entry under lock.
|
||||
****************************************************************************/
|
||||
|
||||
void remove_deferred_open_entry(struct file_id id, uint64_t mid,
|
||||
struct server_id pid)
|
||||
{
|
||||
struct share_mode_lock *lck = get_existing_share_mode_lock(
|
||||
talloc_tos(), id);
|
||||
if (lck == NULL) {
|
||||
DEBUG(0, ("could not get share mode lock\n"));
|
||||
return;
|
||||
}
|
||||
del_deferred_open_entry(lck, mid, pid);
|
||||
TALLOC_FREE(lck);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Return true if this is a state pointer to an asynchronous create.
|
||||
****************************************************************************/
|
||||
@ -2115,12 +2064,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
if (is_deferred_open_async(ptr)) {
|
||||
SET_STAT_INVALID(smb_fname->st);
|
||||
file_existed = false;
|
||||
} else {
|
||||
struct deferred_open_record *state = (struct deferred_open_record *)ptr;
|
||||
/* Remove the deferred open entry under lock. */
|
||||
remove_deferred_open_entry(
|
||||
state->id, req->mid,
|
||||
messaging_server_id(req->sconn->msg_ctx));
|
||||
}
|
||||
|
||||
/* Ensure we don't reprocess this message. */
|
||||
@ -2833,12 +2776,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
(unsigned int)new_unx_mode));
|
||||
}
|
||||
|
||||
/* If this is a successful open, we must remove any deferred open
|
||||
* records. */
|
||||
if (req != NULL) {
|
||||
del_deferred_open_entry(lck, req->mid,
|
||||
messaging_server_id(req->sconn->msg_ctx));
|
||||
}
|
||||
TALLOC_FREE(lck);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
@ -620,8 +620,6 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf);
|
||||
bool is_stat_open(uint32 access_mask);
|
||||
void remove_deferred_open_entry(struct file_id id, uint64_t mid,
|
||||
struct server_id pid);
|
||||
bool is_deferred_open_async(const void *ptr);
|
||||
NTSTATUS open_file_fchmod(connection_struct *conn,
|
||||
struct smb_filename *smb_fname,
|
||||
|
@ -1361,8 +1361,6 @@ static bool smbd_smb2_create_cancel(struct tevent_req *req)
|
||||
return false;
|
||||
}
|
||||
|
||||
remove_deferred_open_entry(state->id, mid,
|
||||
messaging_server_id(smb2req->sconn->msg_ctx));
|
||||
remove_deferred_open_message_smb2_internal(smb2req, mid);
|
||||
|
||||
tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user