[SCM] Samba Shared Repository - branch master updated
Michael Adam
obnox at samba.org
Tue Oct 15 18:52:02 MDT 2013
The branch, master has been updated
via a1fcd71 smbd: Simplify open_file_ntcreate
via 4c0cf9f smbd: Remove "file_existed" handling from open_mode_check
via 4263d16 smbd: Decouple grant_fsp_oplock_type from oplock validation
via 00d84ad smbd: Reduce the complexity of open_file_ntcreate
via c938a10 smbd: Factor out remove_stale_share_mode_entries
via 4d85f91 smbd: Make find_oplock_types return bool
via 0f71730 smbd: Make loop index type match loop limit
via 388bf36 smbd: Unify delay_for_*_oplocks
via c33015c smbd: Simplify find_oplock_types a bit
from f50b6da s4:torture: add smb2.session.reauth6 : test failing reauth
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit a1fcd71f9aad98428e33bc2e31cf6d077b0c02fc
Author: Volker Lendecke <vl at samba.org>
Date: Thu Sep 26 15:20:36 2013 -0700
smbd: Simplify open_file_ntcreate
Only one call to delay_for_oplocks left. Metze showed me the new logic:
BATCH is broken if we have a sharing violation. Exclusive is broken
otherwise. That's it.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
Autobuild-User(master): Michael Adam <obnox at samba.org>
Autobuild-Date(master): Wed Oct 16 02:51:53 CEST 2013 on sn-devel-104
commit 4c0cf9fade8e9118c8da31cf3db3a4497321294b
Author: Volker Lendecke <vl at samba.org>
Date: Thu Sep 26 14:32:09 2013 -0700
smbd: Remove "file_existed" handling from open_mode_check
No clue what this does. In open_directory, "dir_existed" is not used after
open_mode_check. In open_file_ntcreate it's used, but I can't think of a case
right now where we would find a formerly nonexisting file to exist suddenly.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 4263d16f134bd93813a880ccb81503bc998a98f3
Author: Volker Lendecke <vl at samba.org>
Date: Tue Sep 3 09:02:12 2013 +0000
smbd: Decouple grant_fsp_oplock_type from oplock validation
This makes grant_fsp_oplock_type independent from the values computed
in validate_oplock_types. It *might* make oplock calculation a bit
slower for heavily shared files, as we are walking the share mode array
twice. But we are doing so much stuff in open that I doubt the difference
is measurable. It clears up the code for me however, and I think that's
worth it.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 00d84ad1928a07bc892e8a37d53e7c35b8628b7f
Author: Volker Lendecke <vl at samba.org>
Date: Mon Sep 2 12:25:07 2013 +0000
smbd: Reduce the complexity of open_file_ntcreate
This removes two variables in open_file_ntcreate based on the observation
that for exclusive and batch oplocks there can only be one entry. So
in these cases we don't need to keep pointers from find_oplock_types to
delay_for_oplocks. We can just reference the only share mode entry around.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit c938a1065fed2a001da69b6a6d826ef31be75003
Author: Volker Lendecke <vl at samba.org>
Date: Mon Sep 2 11:37:57 2013 +0000
smbd: Factor out remove_stale_share_mode_entries
Will be used in the next commit
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 4d85f91a5b309fac76ed8b0ed2a18132c18b2659
Author: Volker Lendecke <vl at samba.org>
Date: Tue Oct 15 10:01:54 2013 +0000
smbd: Make find_oplock_types return bool
smb_panic() does not take a printf style argument. This improves debug
output by easily printing the index that we fell over. Also, doing
smb_panic deep down is bad style IMHO.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 0f71730d1bd1e60b439a45e56d5e68423706c897
Author: Volker Lendecke <vl at samba.org>
Date: Tue Oct 15 09:56:21 2013 +0000
smbd: Make loop index type match loop limit
share_mode_data.num_share_modes is a uint32.
48 bytes less in .o text size for -O3 :-)
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 388bf3643d4c0254dbc6e9f77b15a8911405c4e6
Author: Volker Lendecke <vl at samba.org>
Date: Tue Aug 20 11:58:15 2013 +0000
smbd: Unify delay_for_*_oplocks
This is the same code in both routines
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit c33015c069de285cf6e14bacb1e3a7937e466ef3
Author: Volker Lendecke <vl at samba.org>
Date: Mon Sep 2 12:33:40 2013 +0000
smbd: Simplify find_oplock_types a bit
Define a variable to dereference lck->data just once. Believe it or not,
this saves a few bytes .o with -O3 :-)
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/locking/locking.c | 16 +++
source3/locking/proto.h | 1 +
source3/locking/share_mode_lock.c | 15 +--
source3/smbd/open.c | 241 +++++++++++++++++++------------------
4 files changed, 142 insertions(+), 131 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 7ac04a4..b5d4f24 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -693,6 +693,22 @@ bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
return true;
}
+void remove_stale_share_mode_entries(struct share_mode_data *d)
+{
+ uint32_t i;
+
+ i = 0;
+ while (i < d->num_share_modes) {
+ if (d->share_modes[i].stale) {
+ struct share_mode_entry *m = d->share_modes;
+ m[i] = m[d->num_share_modes-1];
+ d->num_share_modes -= 1;
+ } else {
+ i += 1;
+ }
+ }
+}
+
bool set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
uid_t uid, uint64_t mid, uint16 op_type)
{
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index f6ae462..2c9654c 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -176,6 +176,7 @@ bool is_valid_share_mode_entry(const struct share_mode_entry *e);
bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx);
bool set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
uid_t uid, uint64_t mid, uint16 op_type);
+void remove_stale_share_mode_entries(struct share_mode_data *d);
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);
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index 342f910..5d7a08c 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -171,26 +171,13 @@ static TDB_DATA unparse_share_modes(struct share_mode_data *d)
{
DATA_BLOB blob;
enum ndr_err_code ndr_err;
- uint32_t i;
if (DEBUGLEVEL >= 10) {
DEBUG(10, ("unparse_share_modes:\n"));
NDR_PRINT_DEBUG(share_mode_data, d);
}
- i = 0;
- while (i < d->num_share_modes) {
- if (d->share_modes[i].stale) {
- /*
- * Remove the stale entries before storing
- */
- struct share_mode_entry *m = d->share_modes;
- m[i] = m[d->num_share_modes-1];
- d->num_share_modes -= 1;
- } else {
- i += 1;
- }
- }
+ remove_stale_share_mode_entries(d);
if (d->num_share_modes == 0) {
DEBUG(10, ("No used share mode found\n"));
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 93b69d5..fa52fcc 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1114,8 +1114,7 @@ static bool has_delete_on_close(struct share_mode_lock *lck,
static NTSTATUS open_mode_check(connection_struct *conn,
struct share_mode_lock *lck,
uint32 access_mask,
- uint32 share_access,
- bool *file_existed)
+ uint32 share_access)
{
int i;
@@ -1156,16 +1155,10 @@ static NTSTATUS open_mode_check(connection_struct *conn,
continue;
}
- *file_existed = true;
-
return NT_STATUS_SHARING_VIOLATION;
}
}
- if (lck->data->num_share_modes != 0) {
- *file_existed = true;
- }
-
return NT_STATUS_OK;
}
@@ -1209,31 +1202,27 @@ static NTSTATUS send_break_message(files_struct *fsp,
* Do internal consistency checks on the share mode for a file.
*/
-static void find_oplock_types(files_struct *fsp,
- int oplock_request,
- const struct share_mode_lock *lck,
- struct share_mode_entry **pp_batch,
- struct share_mode_entry **pp_ex_or_batch,
- bool *got_level2,
- bool *got_no_oplock)
+static bool validate_oplock_types(files_struct *fsp,
+ int oplock_request,
+ struct share_mode_lock *lck)
{
- int i;
-
- *pp_batch = NULL;
- *pp_ex_or_batch = NULL;
- *got_level2 = false;
- *got_no_oplock = false;
+ struct share_mode_data *d = lck->data;
+ bool batch = false;
+ bool ex_or_batch = false;
+ bool level2 = false;
+ bool no_oplock = false;
+ uint32_t i;
/* Ignore stat or internal opens, as is done in
delay_for_batch_oplocks() and
delay_for_exclusive_oplocks().
*/
if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
- return;
+ return true;
}
- for (i=0; i<lck->data->num_share_modes; i++) {
- struct share_mode_entry *e = &lck->data->share_modes[i];
+ for (i=0; i<d->num_share_modes; i++) {
+ struct share_mode_entry *e = &d->share_modes[i];
if (!is_valid_share_mode_entry(e)) {
continue;
@@ -1248,67 +1237,94 @@ static void find_oplock_types(files_struct *fsp,
if (BATCH_OPLOCK_TYPE(e->op_type)) {
/* batch - can only be one. */
- if (share_mode_stale_pid(lck->data, i)) {
+ if (share_mode_stale_pid(d, i)) {
DEBUG(10, ("Found stale batch oplock\n"));
continue;
}
- if (*pp_ex_or_batch || *pp_batch || *got_level2 || *got_no_oplock) {
- smb_panic("Bad batch oplock entry.");
+ if (ex_or_batch || batch || level2 || no_oplock) {
+ DEBUG(0, ("Bad batch oplock entry %u.",
+ (unsigned)i));
+ return false;
}
- *pp_batch = e;
+ batch = true;
}
if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
- if (share_mode_stale_pid(lck->data, i)) {
+ if (share_mode_stale_pid(d, i)) {
DEBUG(10, ("Found stale duplicate oplock\n"));
continue;
}
/* Exclusive or batch - can only be one. */
- if (*pp_ex_or_batch || *got_level2 || *got_no_oplock) {
- smb_panic("Bad exclusive or batch oplock entry.");
+ if (ex_or_batch || level2 || no_oplock) {
+ DEBUG(0, ("Bad exclusive or batch oplock "
+ "entry %u.", (unsigned)i));
+ return false;
}
- *pp_ex_or_batch = e;
+ ex_or_batch = true;
}
if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
- if (*pp_batch || *pp_ex_or_batch) {
- if (share_mode_stale_pid(lck->data, i)) {
+ if (batch || ex_or_batch) {
+ if (share_mode_stale_pid(d, i)) {
DEBUG(10, ("Found stale LevelII "
"oplock\n"));
continue;
}
- smb_panic("Bad levelII oplock entry.");
+ DEBUG(0, ("Bad levelII oplock entry %u.",
+ (unsigned)i));
+ return false;
}
- *got_level2 = true;
+ level2 = true;
}
if (e->op_type == NO_OPLOCK) {
- if (*pp_batch || *pp_ex_or_batch) {
- if (share_mode_stale_pid(lck->data, i)) {
+ if (batch || ex_or_batch) {
+ if (share_mode_stale_pid(d, i)) {
DEBUG(10, ("Found stale NO_OPLOCK "
"entry\n"));
continue;
}
- smb_panic("Bad no oplock entry.");
+ DEBUG(0, ("Bad no oplock entry %u.",
+ (unsigned)i));
+ return false;
}
- *got_no_oplock = true;
+ no_oplock = true;
}
}
+
+ remove_stale_share_mode_entries(d);
+
+ if ((batch || ex_or_batch) && (d->num_share_modes != 1)) {
+ DEBUG(1, ("got batch (%d) or ex (%d) non-exclusively (%d)\n",
+ (int)batch, (int)ex_or_batch,
+ (int)d->num_share_modes));
+ return false;
+ }
+
+ return true;
}
-static bool delay_for_batch_oplocks(files_struct *fsp,
- uint64_t mid,
- int oplock_request,
- struct share_mode_entry *batch_entry)
+static bool delay_for_oplock(files_struct *fsp,
+ uint64_t mid,
+ int oplock_request,
+ struct share_mode_lock *lck,
+ bool have_sharing_violation)
{
+ struct share_mode_data *d = lck->data;
+ struct share_mode_entry *entry;
+
if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
return false;
}
- if (batch_entry == NULL) {
+ if (lck->data->num_share_modes != 1) {
+ /*
+ * More than one. There can't be any exclusive or batch left.
+ */
return false;
}
+ entry = &d->share_modes[0];
- if (server_id_is_disconnected(&batch_entry->pid)) {
+ if (server_id_is_disconnected(&entry->pid)) {
/*
* TODO: clean up.
* This could be achieved by sending a break message
@@ -1321,33 +1337,31 @@ static bool delay_for_batch_oplocks(files_struct *fsp,
return false;
}
- /* Found a batch oplock */
- send_break_message(fsp, batch_entry, mid, oplock_request);
- return true;
-}
-
-static bool delay_for_exclusive_oplocks(files_struct *fsp,
- uint64_t mid,
- int oplock_request,
- struct share_mode_entry *ex_entry)
-{
- if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
- return false;
+ if (have_sharing_violation && (entry->op_type & BATCH_OPLOCK)) {
+ if (share_mode_stale_pid(d, 0)) {
+ return false;
+ }
+ send_break_message(fsp, entry, mid, oplock_request);
+ return true;
}
- if (ex_entry == NULL) {
+ if (have_sharing_violation) {
+ /*
+ * Non-batch exclusive is not broken if we have a sharing
+ * violation
+ */
return false;
}
-
- if (server_id_is_disconnected(&ex_entry->pid)) {
+ if (!EXCLUSIVE_OPLOCK_TYPE(entry->op_type)) {
/*
- * since only durable handles can get disconnected,
- * and we can only get durable handles with batch oplocks,
- * this should actually never be reached...
+ * No break for NO_OPLOCK or LEVEL2_OPLOCK oplocks
*/
return false;
}
+ if (share_mode_stale_pid(d, 0)) {
+ return false;
+ }
- send_break_message(fsp, ex_entry, mid, oplock_request);
+ send_break_message(fsp, entry, mid, oplock_request);
return true;
}
@@ -1363,12 +1377,13 @@ static bool file_has_brlocks(files_struct *fsp)
}
static void grant_fsp_oplock_type(files_struct *fsp,
- int oplock_request,
- bool got_level2_oplock,
- bool got_a_none_oplock)
+ struct share_mode_lock *lck,
+ int oplock_request)
{
bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
lp_level2_oplocks(SNUM(fsp->conn));
+ bool got_level2_oplock, got_a_none_oplock;
+ uint32_t i;
/* Start by granting what the client asked for,
but ensure no SAMBA_PRIVATE bits can be set. */
@@ -1395,6 +1410,20 @@ static void grant_fsp_oplock_type(files_struct *fsp,
return;
}
+ got_level2_oplock = false;
+ got_a_none_oplock = false;
+
+ for (i=0; i<lck->data->num_share_modes; i++) {
+ int op_type = lck->data->share_modes[i].op_type;
+
+ if (LEVEL_II_OPLOCK_TYPE(op_type)) {
+ got_level2_oplock = true;
+ }
+ if (op_type == NO_OPLOCK) {
+ got_a_none_oplock = true;
+ }
+ }
+
/*
* Match what was requested (fsp->oplock_type) with
* what was found in the existing share modes.
@@ -1965,10 +1994,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
NTSTATUS status;
char *parent_dir;
SMB_STRUCT_STAT saved_stat = smb_fname->st;
- struct share_mode_entry *batch_entry = NULL;
- struct share_mode_entry *exclusive_entry = NULL;
- bool got_level2_oplock = false;
- bool got_a_none_oplock = false;
struct timespec old_write_time;
struct file_id id;
@@ -2309,12 +2334,11 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
return NT_STATUS_SHARING_VIOLATION;
}
- find_oplock_types(fsp, 0, lck, &batch_entry, &exclusive_entry,
- &got_level2_oplock, &got_a_none_oplock);
+ if (!validate_oplock_types(fsp, 0, lck)) {
+ smb_panic("validate_oplock_types failed");
+ }
- if (delay_for_batch_oplocks(fsp, req->mid, 0, batch_entry) ||
- delay_for_exclusive_oplocks(fsp, req->mid, 0,
- exclusive_entry)) {
+ if (delay_for_oplock(fsp, req->mid, 0, lck, false)) {
schedule_defer_open(lck, request_time, req);
TALLOC_FREE(lck);
DEBUG(10, ("Sent oplock break request to kernel "
@@ -2398,13 +2422,9 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
/* Get the types we need to examine. */
- find_oplock_types(fsp,
- oplock_request,
- lck,
- &batch_entry,
- &exclusive_entry,
- &got_level2_oplock,
- &got_a_none_oplock);
+ if (!validate_oplock_types(fsp, oplock_request, lck)) {
+ smb_panic("validate_oplock_types failed");
+ }
if (has_delete_on_close(lck, fsp->name_hash)) {
TALLOC_FREE(lck);
@@ -2412,40 +2432,31 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
return NT_STATUS_DELETE_PENDING;
}
- /* First pass - send break only on batch oplocks. */
+ status = open_mode_check(conn, lck,
+ access_mask, share_access);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+ (lck->data->num_share_modes > 0)) {
+ /*
+ * This comes from ancient times out of open_mode_check. I
+ * have no clue whether this is still necessary. I can't think
+ * of a case where this would actually matter further down in
+ * this function. I leave it here for further investigation
+ * :-)
+ */
+ file_existed = true;
+ }
+
if ((req != NULL) &&
- delay_for_batch_oplocks(fsp,
- req->mid,
- oplock_request,
- batch_entry)) {
+ delay_for_oplock(
+ fsp, req->mid, oplock_request, lck,
+ NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION))) {
schedule_defer_open(lck, request_time, req);
TALLOC_FREE(lck);
fd_close(fsp);
return NT_STATUS_SHARING_VIOLATION;
}
- status = open_mode_check(conn, lck,
- access_mask, share_access,
- &file_existed);
-
- if (NT_STATUS_IS_OK(status)) {
- /* We might be going to allow this open. Check oplock
- * status again. */
- /* Second pass - send break for both batch or
- * exclusive oplocks. */
- if ((req != NULL) &&
- delay_for_exclusive_oplocks(
- fsp,
- req->mid,
- oplock_request,
- exclusive_entry)) {
- schedule_defer_open(lck, request_time, req);
- TALLOC_FREE(lck);
- fd_close(fsp);
- return NT_STATUS_SHARING_VIOLATION;
- }
- }
-
if (!NT_STATUS_IS_OK(status)) {
uint32 can_access_mask;
bool can_access = True;
@@ -2573,10 +2584,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
return status;
}
- grant_fsp_oplock_type(fsp,
- oplock_request,
- got_level2_oplock,
- got_a_none_oplock);
+ grant_fsp_oplock_type(fsp, lck, oplock_request);
/*
* We have the share entry *locked*.....
@@ -3163,8 +3171,7 @@ static NTSTATUS open_directory(connection_struct *conn,
}
status = open_mode_check(conn, lck,
- access_mask, share_access,
- &dir_existed);
+ access_mask, share_access);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
--
Samba Shared Repository
More information about the samba-cvs
mailing list