diff options
author | Michael Adam <obnox@samba.org> | 2014-07-17 17:22:09 +0200 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2014-07-24 11:56:09 +0200 |
commit | 16a040f8ef7f2f594505ef07e6f9b77df8f1d725 (patch) | |
tree | 1ee45c1e34d8dc911c67e453108387d926387119 /source3/modules/vfs_gpfs.c | |
parent | 44e9ab21ddfdf0e82a0ed9a884d411af66408962 (diff) | |
download | samba-16a040f8ef7f2f594505ef07e6f9b77df8f1d725.tar.gz samba-16a040f8ef7f2f594505ef07e6f9b77df8f1d725.tar.xz samba-16a040f8ef7f2f594505ef07e6f9b77df8f1d725.zip |
s3:vfs:gpfs: Remove all reading uses of stat_ex.vfs_private from vfs_gfs.
This was used as a cache for offline-info in the stat buffer.
But as the implementation of gpfs_is_offline() showed, this cache
does not always carry valid information when the stat itself is valid
(since at least one call goes to fstatat() directly, circumventing
the vfs).
So the correct thing is to always call SMB_VFS_IS_OFFLINE()
when checking whether a file is offline. For the pread and pwrite
calls, we need to call IS_OFFLINE before the actual read
and check afterwards if the file was offline before (as a basis
whether to send notifications).
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Christof Schmitt <cs@samba.org>
Diffstat (limited to 'source3/modules/vfs_gpfs.c')
-rw-r--r-- | source3/modules/vfs_gpfs.c | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 9fcce78a68..8049cb779b 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1848,7 +1848,8 @@ static ssize_t vfs_gpfs_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, const DATA_BLOB *hdr, off_t offset, size_t n) { - if ((fsp->fsp_name->st.vfs_private & GPFS_WINATTR_OFFLINE) != 0) { + if (SMB_VFS_IS_OFFLINE(handle->conn, fsp->fsp_name, &fsp->fsp_name->st)) + { errno = ENOSYS; return -1; } @@ -2115,8 +2116,8 @@ static int vfs_gpfs_open(struct vfs_handle_struct *handle, return -1); if (config->hsm && !config->recalls) { - if (VALID_STAT(smb_fname->st) && - (smb_fname->st.vfs_private & GPFS_WINATTR_OFFLINE)) { + if (SMB_VFS_IS_OFFLINE(handle->conn, smb_fname, &smb_fname->st)) + { DEBUG(10, ("Refusing access to offline file %s\n", fsp_str_dbg(fsp))); errno = EACCES; @@ -2134,14 +2135,14 @@ static ssize_t vfs_gpfs_pread(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n, off_t offset) { ssize_t ret; + bool was_offline; - ret = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); + was_offline = SMB_VFS_IS_OFFLINE(handle->conn, fsp->fsp_name, + &fsp->fsp_name->st); - DEBUG(10, ("vfs_private = %x\n", - (unsigned int)fsp->fsp_name->st.vfs_private)); + ret = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); - if ((ret != -1) && - ((fsp->fsp_name->st.vfs_private & GPFS_WINATTR_OFFLINE) != 0)) { + if ((ret != -1) && was_offline) { fsp->fsp_name->st.vfs_private &= ~GPFS_WINATTR_OFFLINE; notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, @@ -2155,6 +2156,7 @@ struct vfs_gpfs_pread_state { struct files_struct *fsp; ssize_t ret; int err; + bool was_offline; }; static void vfs_gpfs_pread_done(struct tevent_req *subreq); @@ -2173,6 +2175,8 @@ static struct tevent_req *vfs_gpfs_pread_send(struct vfs_handle_struct *handle, if (req == NULL) { return NULL; } + state->was_offline = SMB_VFS_IS_OFFLINE(handle->conn, fsp->fsp_name, + &fsp->fsp_name->st); state->fsp = fsp; subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data, n, offset); @@ -2206,11 +2210,7 @@ static ssize_t vfs_gpfs_pread_recv(struct tevent_req *req, int *err) } *err = state->err; - DEBUG(10, ("vfs_private = %x\n", - (unsigned int)fsp->fsp_name->st.vfs_private)); - - if ((state->ret != -1) && - ((fsp->fsp_name->st.vfs_private & GPFS_WINATTR_OFFLINE) != 0)) { + if ((state->ret != -1) && state->was_offline) { fsp->fsp_name->st.vfs_private &= ~GPFS_WINATTR_OFFLINE; DEBUG(10, ("sending notify\n")); notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, @@ -2225,14 +2225,14 @@ static ssize_t vfs_gpfs_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n, off_t offset) { ssize_t ret; + bool was_offline; - ret = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); + was_offline = SMB_VFS_IS_OFFLINE(handle->conn, fsp->fsp_name, + &fsp->fsp_name->st); - DEBUG(10, ("vfs_private = %x\n", - (unsigned int)fsp->fsp_name->st.vfs_private)); + ret = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); - if ((ret != -1) && - ((fsp->fsp_name->st.vfs_private & GPFS_WINATTR_OFFLINE) != 0)) { + if ((ret != -1) && was_offline) { fsp->fsp_name->st.vfs_private &= ~GPFS_WINATTR_OFFLINE; notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, @@ -2246,6 +2246,7 @@ struct vfs_gpfs_pwrite_state { struct files_struct *fsp; ssize_t ret; int err; + bool was_offline; }; static void vfs_gpfs_pwrite_done(struct tevent_req *subreq); @@ -2265,6 +2266,8 @@ static struct tevent_req *vfs_gpfs_pwrite_send( if (req == NULL) { return NULL; } + state->was_offline = SMB_VFS_IS_OFFLINE(handle->conn, fsp->fsp_name, + &fsp->fsp_name->st); state->fsp = fsp; subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data, n, offset); @@ -2298,11 +2301,7 @@ static ssize_t vfs_gpfs_pwrite_recv(struct tevent_req *req, int *err) } *err = state->err; - DEBUG(10, ("vfs_private = %x\n", - (unsigned int)fsp->fsp_name->st.vfs_private)); - - if ((state->ret != -1) && - ((fsp->fsp_name->st.vfs_private & GPFS_WINATTR_OFFLINE) != 0)) { + if ((state->ret != -1) && state->was_offline) { fsp->fsp_name->st.vfs_private &= ~GPFS_WINATTR_OFFLINE; DEBUG(10, ("sending notify\n")); notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, |