1
0
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:
Volker Lendecke 2013-04-26 15:05:50 +02:00 committed by Jeremy Allison
parent 8da5a0f1e3
commit a7e803485d
8 changed files with 2 additions and 226 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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.
********************************************************************/

View File

@ -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,

View File

@ -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.

View 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;

View File

@ -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,

View File

@ -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);