diff options
author | Amin Azez <azez@ufomechanic.net> | 2008-01-29 16:10:48 +0000 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2008-02-12 14:17:41 +0100 |
commit | cb2f8d6cf4e6739f9dd5b4a9b21c9fbb4fb59609 (patch) | |
tree | ea622ffa102abf9c76fb062f780e6f2697db6291 | |
parent | 1ed346fcb37f302341f528e2f8465d389f586742 (diff) | |
download | samba-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.c | 20 |
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); |