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 /source4 | |
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)
Diffstat (limited to 'source4')
-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); |