summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmin Azez <azez@ufomechanic.net>2008-01-29 16:10:48 +0000
committerStefan Metzmacher <metze@samba.org>2008-02-12 14:17:41 +0100
commitcb2f8d6cf4e6739f9dd5b4a9b21c9fbb4fb59609 (patch)
treeea622ffa102abf9c76fb062f780e6f2697db6291
parent1ed346fcb37f302341f528e2f8465d389f586742 (diff)
downloadsamba-cb2f8d6cf4e6739f9dd5b4a9b21c9fbb4fb59609.tar.gz
samba-cb2f8d6cf4e6739f9dd5b4a9b21c9fbb4fb59609.tar.bz2
samba-cb2f8d6cf4e6739f9dd5b4a9b21c9fbb4fb59609.zip
Fix open file tracking in vfs_cifs so that oplock breaks can propagate
Oplock breaks were not propagating because the list of open files was not being maintained. This fixes that based on best-guess of how it should work. It has been tested manually with windows XP client obtaining an oplock from a windows 2003 server, which then broke the lock when smbclient read the same file. Previously the smbclient read blocked until the oplock timed out (This used to be commit 1a53aeff9a9e8fe83fde5a617463a5b363c45313)
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index 910401f157..901dd2cf7c 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -64,12 +64,16 @@ struct async_info {
#define SETUP_PID private->tree->session->pid = req->smbpid
-#define SETUP_FILE do { \
- struct cvfs_file *f; \
+#define SETUP_FILE_HERE(f) do { \
f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \
if (!f) return NT_STATUS_INVALID_HANDLE; \
io->generic.in.file.fnum = f->fnum; \
-} while (0)
+} while (0)
+
+#define SETUP_FILE do { \
+ struct cvfs_file *f; \
+ SETUP_FILE_HERE(f); \
+} while (0)
#define SETUP_PID_AND_FILE do { \
SETUP_PID; \
@@ -484,6 +488,7 @@ static void async_open(struct smbcli_request *c_req)
req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f);
if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed;
file->ntvfs = f->h;
+ DLIST_ADD(cvfs->files, f);
failed:
req->async_states->send_fn(req);
}
@@ -526,6 +531,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs,
status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f);
NT_STATUS_NOT_OK_RETURN(status);
file->ntvfs = f->h;
+ DLIST_ADD(private->files, f);
return NT_STATUS_OK;
}
@@ -752,6 +758,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
+ struct cvfs_file *f;
SETUP_PID;
@@ -759,7 +766,12 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
private->map_generic) {
return ntvfs_map_close(ntvfs, req, io);
}
- SETUP_FILE;
+ SETUP_FILE_HERE(f);
+ /* Note, we aren't free-ing f, or it's h here. Should we?
+ even if file-close fails, we'll remove it from the list,
+ what else would we do? Maybe we should not remove until
+ after the proxied call completes? */
+ DLIST_REMOVE(private->files, f);
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
return smb_raw_close(private->tree, io);