summaryrefslogtreecommitdiff
path: root/source3/smbd/nttrans.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@sernet.de>2007-12-07 12:57:11 +0100
committerVolker Lendecke <vl@sernet.de>2007-12-07 14:05:06 +0100
commitca4eee5bbe477af2abcdbed542c5e8f7ef5eb610 (patch)
tree8722d8371bf038a6907ff0ea3a1534a8e11c4ae6 /source3/smbd/nttrans.c
parentce535b4dd8c410d91f9c0fa2d1d973b4326af64d (diff)
downloadsamba-ca4eee5bbe477af2abcdbed542c5e8f7ef5eb610.tar.gz
samba-ca4eee5bbe477af2abcdbed542c5e8f7ef5eb610.tar.bz2
samba-ca4eee5bbe477af2abcdbed542c5e8f7ef5eb610.zip
Pass only internal oplock request values to create_file
Other callers (e.g. reply_open_and_X) might have other ideas of the bit shuffling (This used to be commit 6a58d823e51ccc8efd6682005e367c9096abc993)
Diffstat (limited to 'source3/smbd/nttrans.c')
-rw-r--r--source3/smbd/nttrans.c70
1 files changed, 66 insertions, 4 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index a8afd580b3..716f682c1a 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -433,6 +433,7 @@ void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req)
struct timespec a_timespec;
struct timespec m_timespec;
NTSTATUS status;
+ int oplock_request;
uint8_t oplock_granted = NO_OPLOCK_RETURN;
TALLOC_CTX *ctx = talloc_tos();
@@ -497,11 +498,16 @@ void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req)
}
}
+ oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+ if (oplock_request) {
+ oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
+ ? BATCH_OPLOCK : 0;
+ }
+
status = create_file(conn, req, root_dir_fid, fname,
access_mask, share_access, create_disposition,
create_options, file_attributes, flags,
- allocation_size, NULL, NULL,
- &fsp, &info, &oplock_granted, &sbuf);
+ allocation_size, NULL, NULL, &fsp, &info, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
@@ -519,6 +525,31 @@ void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req)
return;
}
+ /*
+ * If the caller set the extended oplock request bit
+ * and we granted one (by whatever means) - set the
+ * correct bit for extended oplock reply.
+ */
+
+ if (oplock_request &&
+ (lp_fake_oplocks(SNUM(conn))
+ || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
+
+ /*
+ * Exclusive oplock granted
+ */
+
+ if (flags & REQUEST_BATCH_OPLOCK) {
+ oplock_granted = BATCH_OPLOCK_RETURN;
+ } else {
+ oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
+ }
+ } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
+ oplock_granted = LEVEL_II_OPLOCK_RETURN;
+ } else {
+ oplock_granted = NO_OPLOCK_RETURN;
+ }
+
file_len = sbuf.st_size;
fattr = dos_mode(conn,fname,&sbuf);
if (fattr == 0) {
@@ -834,6 +865,7 @@ static void call_nt_transact_create(connection_struct *conn,
NTSTATUS status;
size_t param_len;
SMB_BIG_UINT allocation_size;
+ int oplock_request;
uint8_t oplock_granted;
TALLOC_CTX *ctx = talloc_tos();
@@ -941,11 +973,16 @@ static void call_nt_transact_create(connection_struct *conn,
return;
}
+ oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+ if (oplock_request) {
+ oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
+ ? BATCH_OPLOCK : 0;
+ }
+
status = create_file(conn, req, root_dir_fid, fname,
access_mask, share_access, create_disposition,
create_options, file_attributes, flags,
- allocation_size, sd, ea_list,
- &fsp, &info, &oplock_granted, &sbuf);
+ allocation_size, sd, ea_list, &fsp, &info, &sbuf);
if(!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
@@ -961,6 +998,31 @@ static void call_nt_transact_create(connection_struct *conn,
return;
}
+ /*
+ * If the caller set the extended oplock request bit
+ * and we granted one (by whatever means) - set the
+ * correct bit for extended oplock reply.
+ */
+
+ if (oplock_request &&
+ (lp_fake_oplocks(SNUM(conn))
+ || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
+
+ /*
+ * Exclusive oplock granted
+ */
+
+ if (flags & REQUEST_BATCH_OPLOCK) {
+ oplock_granted = BATCH_OPLOCK_RETURN;
+ } else {
+ oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
+ }
+ } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
+ oplock_granted = LEVEL_II_OPLOCK_RETURN;
+ } else {
+ oplock_granted = NO_OPLOCK_RETURN;
+ }
+
file_len = sbuf.st_size;
fattr = dos_mode(conn,fname,&sbuf);
if (fattr == 0) {