summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2013-09-03 09:02:12 +0000
committerMichael Adam <obnox@samba.org>2013-10-16 00:45:43 +0200
commit4263d16f134bd93813a880ccb81503bc998a98f3 (patch)
treee70491a9eab1f6cbbcb4d488b034b6c611cece82
parent00d84ad1928a07bc892e8a37d53e7c35b8628b7f (diff)
downloadsamba-4263d16f134bd93813a880ccb81503bc998a98f3.tar.gz
samba-4263d16f134bd93813a880ccb81503bc998a98f3.tar.bz2
samba-4263d16f134bd93813a880ccb81503bc998a98f3.zip
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@samba.org> Reviewed-by: Michael Adam <obnox@samba.org>
-rw-r--r--source3/smbd/open.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index cd8e2a095b..670de5dff9 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1209,11 +1209,9 @@ static NTSTATUS send_break_message(files_struct *fsp,
* Do internal consistency checks on the share mode for a file.
*/
-static bool find_oplock_types(files_struct *fsp,
- int oplock_request,
- const struct share_mode_lock *lck,
- bool *got_level2,
- bool *got_no_oplock)
+static bool validate_oplock_types(files_struct *fsp,
+ int oplock_request,
+ struct share_mode_lock *lck)
{
struct share_mode_data *d = lck->data;
bool batch = false;
@@ -1222,9 +1220,6 @@ static bool find_oplock_types(files_struct *fsp,
bool no_oplock = false;
uint32_t i;
- *got_level2 = false;
- *got_no_oplock = false;
-
/* Ignore stat or internal opens, as is done in
delay_for_batch_oplocks() and
delay_for_exclusive_oplocks().
@@ -1313,8 +1308,6 @@ static bool find_oplock_types(files_struct *fsp,
return false;
}
- *got_level2 = level2;
- *got_no_oplock = no_oplock;
return true;
}
@@ -1367,12 +1360,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. */
@@ -1399,6 +1393,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.
@@ -1969,8 +1977,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
NTSTATUS status;
char *parent_dir;
SMB_STRUCT_STAT saved_stat = smb_fname->st;
- bool got_level2_oplock = false;
- bool got_a_none_oplock = false;
struct timespec old_write_time;
struct file_id id;
@@ -2311,10 +2317,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
return NT_STATUS_SHARING_VIOLATION;
}
- if (!find_oplock_types(fsp, 0, lck,
- &got_level2_oplock,
- &got_a_none_oplock)) {
- smb_panic("find_oplock_types failed");
+ if (!validate_oplock_types(fsp, 0, lck)) {
+ smb_panic("validate_oplock_types failed");
}
if (delay_for_oplock(fsp, req->mid, 0, lck,
@@ -2402,10 +2406,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
/* Get the types we need to examine. */
- if (!find_oplock_types(fsp, oplock_request, lck,
- &got_level2_oplock,
- &got_a_none_oplock)) {
- smb_panic("find_oplock_types failed");
+ if (!validate_oplock_types(fsp, oplock_request, lck)) {
+ smb_panic("validate_oplock_types failed");
}
if (has_delete_on_close(lck, fsp->name_hash)) {
@@ -2570,10 +2572,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*.....