summaryrefslogtreecommitdiff
path: root/source3/modules/vfs_tsmsm.c
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2016-09-11 12:39:13 +0200
committerVolker Lendecke <vl@samba.org>2016-10-11 11:01:10 +0200
commit6f3b421c4a29e63e87a5987f54c925b8668f813c (patch)
tree743e4898c3ba3a9b2a72fc0efb3c9cb445707afb /source3/modules/vfs_tsmsm.c
parente56fa1f0e3fc42afe725c877d633333add65ec8e (diff)
downloadsamba-6f3b421c4a29e63e87a5987f54c925b8668f813c.tar.gz
s3/vfs: merge offline functionality into DOS attributes handling
The offline VFS functions predate the SMB_VFS_{GET|SET}_DOS_ATTRIBUTES() functions, now that we have these, we can use them for the offline attribute as well. The primary reason for this is: performance. Merging both functions has the benefit that in VFS modules that use same backing store bits for both offline attribute and DOS attributes (like gpfs), we avoid calling the backing store twice in dos_mode() and file_set_dosmode(). This commit modifies all existing users of the offline attribute to adapt to the change, the next commit will then remove the obsolete offline functions. Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'source3/modules/vfs_tsmsm.c')
-rw-r--r--source3/modules/vfs_tsmsm.c102
1 files changed, 93 insertions, 9 deletions
diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c
index 91daa6f5a06..b943515a8fc 100644
--- a/source3/modules/vfs_tsmsm.c
+++ b/source3/modules/vfs_tsmsm.c
@@ -266,6 +266,33 @@ done:
return offline;
}
+static NTSTATUS tsmsm_get_dos_attributes(struct vfs_handle_struct *handle,
+ struct smb_filename *fname,
+ uint32_t *dosmode)
+{
+ bool offline;
+
+ offline = tsmsm_is_offline(handle, fname, &fname->st);
+ if (offline) {
+ *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ }
+
+ return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, fname, dosmode);
+}
+
+static NTSTATUS tsmsm_fget_dos_attributes(struct vfs_handle_struct *handle,
+ files_struct *fsp,
+ uint32_t *dosmode)
+{
+ bool offline;
+
+ offline = tsmsm_is_offline(handle, fsp->fsp_name, &fsp->fsp_name->st);
+ if (offline) {
+ *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ }
+
+ return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
+}
static bool tsmsm_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
{
@@ -467,8 +494,8 @@ static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struc
return result;
}
-static int tsmsm_set_offline(struct vfs_handle_struct *handle,
- const struct smb_filename *fname)
+static NTSTATUS tsmsm_set_offline(struct vfs_handle_struct *handle,
+ const struct smb_filename *fname)
{
struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
int result = 0;
@@ -479,27 +506,82 @@ static int tsmsm_set_offline(struct vfs_handle_struct *handle,
if (tsmd->hsmscript == NULL) {
/* no script enabled */
DEBUG(1, ("tsmsm_set_offline: No 'tsmsm:hsm script' configured\n"));
- return 0;
+ return NT_STATUS_OK;
}
status = get_full_smb_filename(talloc_tos(), fname, &path);
if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return false;
+ return status;
}
/* Now, call the script */
command = talloc_asprintf(tsmd, "%s offline \"%s\"", tsmd->hsmscript, path);
if(!command) {
DEBUG(1, ("tsmsm_set_offline: can't allocate memory to run hsm script"));
- return -1;
+ return NT_STATUS_NO_MEMORY;
}
DEBUG(10, ("tsmsm_set_offline: Running [%s]\n", command));
if((result = smbrun(command, NULL)) != 0) {
DEBUG(1,("tsmsm_set_offline: Running [%s] returned %d\n", command, result));
+ TALLOC_FREE(command);
+ return NT_STATUS_INTERNAL_ERROR;
}
TALLOC_FREE(command);
- return result;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS tsmsm_set_dos_attributes(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uint32_t dosmode)
+{
+ NTSTATUS status;
+ uint32_t old_dosmode;
+ struct smb_filename *fname = NULL;
+
+ /* dos_mode() doesn't like const smb_fname */
+ fname = cp_smb_filename(talloc_tos(), smb_fname);
+ if (fname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ old_dosmode = dos_mode(handle->conn, fname);
+ TALLOC_FREE(fname);
+
+ status = SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle, smb_fname, dosmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (!(old_dosmode & FILE_ATTRIBUTE_OFFLINE) &&
+ (dosmode & FILE_ATTRIBUTE_OFFLINE))
+ {
+ return NT_STATUS_OK;
+ }
+
+ return tsmsm_set_offline(handle, smb_fname);
+}
+
+static NTSTATUS tsmsm_fset_dos_attributes(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t dosmode)
+{
+ NTSTATUS status;
+ uint32_t old_dosmode;
+
+ old_dosmode = dos_mode(handle->conn, fsp->fsp_name);
+
+ status = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (!(old_dosmode & FILE_ATTRIBUTE_OFFLINE) &&
+ (dosmode & FILE_ATTRIBUTE_OFFLINE))
+ {
+ return NT_STATUS_OK;
+ }
+
+ return tsmsm_set_offline(handle, fsp->fsp_name);
}
static uint32_t tsmsm_fs_capabilities(struct vfs_handle_struct *handle,
@@ -519,8 +601,10 @@ static struct vfs_fn_pointers tsmsm_fns = {
.pwrite_send_fn = tsmsm_pwrite_send,
.pwrite_recv_fn = tsmsm_pwrite_recv,
.sendfile_fn = tsmsm_sendfile,
- .is_offline_fn = tsmsm_is_offline,
- .set_offline_fn = tsmsm_set_offline,
+ .set_dos_attributes_fn = tsmsm_set_dos_attributes,
+ .fset_dos_attributes_fn = tsmsm_fset_dos_attributes,
+ .get_dos_attributes_fn = tsmsm_get_dos_attributes,
+ .fget_dos_attributes_fn = tsmsm_fget_dos_attributes,
};
NTSTATUS vfs_tsmsm_init(void);