summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2014-07-17 17:22:09 +0200
committerKarolin Seeger <kseeger@samba.org>2014-08-07 16:43:09 +0200
commit9093f2d9d40bbfaf0776926a5f911ff3bc7bd522 (patch)
treef4a6318d45b48b2a0c4d9bd22d856c7228ee6cdf
parent1c8232684a30c1ac1fec1d65b664fc80d2331224 (diff)
downloadsamba-9093f2d9d40bbfaf0776926a5f911ff3bc7bd522.tar.gz
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> (cherry picked from commit 16a040f8ef7f2f594505ef07e6f9b77df8f1d725) Conflicts: source3/modules/vfs_gpfs.c BUG: https://bugzilla.samba.org/show_bug.cgi?id=10741
-rw-r--r--source3/modules/vfs_gpfs.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 614c56d917..a1612e291c 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -1681,7 +1681,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;
}
@@ -1952,14 +1953,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,
@@ -1973,6 +1974,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);
@@ -1991,6 +1993,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);
@@ -2024,11 +2028,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,
@@ -2043,14 +2043,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,
@@ -2064,6 +2064,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);
@@ -2083,6 +2084,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);
@@ -2116,11 +2119,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,