FILE_ATTRIBUTE_HIDDEN|\
FILE_ATTRIBUTE_SYSTEM|\
FILE_ATTRIBUTE_DIRECTORY|\
- FILE_ATTRIBUTE_ARCHIVE)
+ FILE_ATTRIBUTE_ARCHIVE|\
+ FILE_ATTRIBUTE_OFFLINE)
/* File type flags */
#define FILE_TYPE_DISK 0
return NT_STATUS_NOT_SUPPORTED;
}
+static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
+ const struct smb_filename *fname,
+ SMB_STRUCT_STAT *sbuf);
+
static NTSTATUS vfswrap_get_dos_attributes(struct vfs_handle_struct *handle,
struct smb_filename *smb_fname,
uint32_t *dosmode)
{
+ bool offline;
+
+ offline = vfswrap_is_offline(handle, smb_fname, &smb_fname->st);
+ if (offline) {
+ *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ }
+
return get_ea_dos_attribute(handle->conn, smb_fname, dosmode);
}
struct files_struct *fsp,
uint32_t *dosmode)
{
+ bool offline;
+
+ offline = vfswrap_is_offline(handle, fsp->fsp_name, &fsp->fsp_name->st);
+ if (offline) {
+ *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ }
+
return get_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
}
return offline;
}
-static int vfswrap_set_offline(struct vfs_handle_struct *handle,
- const struct smb_filename *fname)
-{
- /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
-#if defined(ENOTSUP)
- errno = ENOTSUP;
-#endif
- return -1;
-}
-
static NTSTATUS vfswrap_durable_cookie(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *mem_ctx,
/* aio operations */
.aio_force_fn = vfswrap_aio_force,
- /* offline operations */
- .is_offline_fn = vfswrap_is_offline,
- .set_offline_fn = vfswrap_set_offline,
-
/* durable handle operations */
.durable_cookie_fn = vfswrap_durable_cookie,
.durable_disconnect_fn = vfswrap_durable_disconnect,
if (winattrs & GPFS_WINATTR_SPARSE_FILE) {
dosmode |= FILE_ATTRIBUTE_SPARSE;
}
+ if (winattrs & GPFS_WINATTR_OFFLINE) {
+ dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ }
return dosmode;
}
if (dosmode & FILE_ATTRIBUTE_SPARSE) {
winattrs |= GPFS_WINATTR_SPARSE_FILE;
}
+ if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
+ winattrs |= GPFS_WINATTR_OFFLINE;
+ }
return winattrs;
}
FILE_SUPPORTS_REMOTE_STORAGE;
}
-static bool offline_is_offline(struct vfs_handle_struct *handle,
- const struct smb_filename *fname,
- SMB_STRUCT_STAT *stbuf)
+static NTSTATUS offline_get_dos_attributes(struct vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ uint32_t *dosmode)
{
- return true;
+ *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, smb_fname, dosmode);
+}
+
+static NTSTATUS offline_fget_dos_attributes(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t *dosmode)
+{
+ *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
}
static struct vfs_fn_pointers offline_fns = {
.fs_capabilities_fn = offline_fs_capabilities,
- .is_offline_fn = offline_is_offline,
+ .get_dos_attributes_fn = offline_get_dos_attributes,
+ .fget_dos_attributes_fn = offline_fget_dos_attributes,
};
NTSTATUS vfs_offline_init(void);
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)
{
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;
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,
.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);
return NT_STATUS_NOT_IMPLEMENTED;
}
+ /*
+ * Don't store FILE_ATTRIBUTE_OFFLINE, it's dealt with in
+ * vfs_default via DMAPI if that is enabled.
+ */
+ dosmode &= ~FILE_ATTRIBUTE_OFFLINE;
+
ZERO_STRUCT(dosattrib);
ZERO_STRUCT(blob);
uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
{
uint32_t result = 0;
- bool offline;
NTSTATUS status = NT_STATUS_OK;
DEBUG(8,("dos_mode: %s\n", smb_fname_str_dbg(smb_fname)));
result |= dos_mode_from_sbuf(conn, smb_fname);
}
- offline = SMB_VFS_IS_OFFLINE(conn, smb_fname, &smb_fname->st);
- if (S_ISREG(smb_fname->st.st_ex_mode) && offline) {
- result |= FILE_ATTRIBUTE_OFFLINE;
- }
-
if (conn->fs_capabilities & FILE_FILE_COMPRESSION) {
bool compressed = false;
status = dos_mode_check_compressed(conn, smb_fname,
mode_t tmp;
mode_t unixmode;
int ret = -1, lret = -1;
- uint32_t old_mode;
- struct timespec new_create_timespec;
files_struct *fsp = NULL;
bool need_close = false;
NTSTATUS status;
return -1;
}
- /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
- dosmode &= (SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE);
+ dosmode &= SAMBA_ATTRIBUTES_MASK;
DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n",
dosmode, smb_fname_str_dbg(smb_fname)));
else
dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
- new_create_timespec = smb_fname->st.st_ex_btime;
-
- old_mode = dos_mode(conn, smb_fname);
-
- if ((dosmode & FILE_ATTRIBUTE_OFFLINE) &&
- !(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
- lret = SMB_VFS_SET_OFFLINE(conn, smb_fname);
- if (lret == -1) {
- if (errno == ENOTSUP) {
- DEBUG(10, ("Setting FILE_ATTRIBUTE_OFFLINE for "
- "%s/%s is not supported.\n",
- parent_dir,
- smb_fname_str_dbg(smb_fname)));
- } else {
- DEBUG(0, ("An error occurred while setting "
- "FILE_ATTRIBUTE_OFFLINE for "
- "%s/%s: %s", parent_dir,
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- }
- }
- }
-
- dosmode &= ~FILE_ATTRIBUTE_OFFLINE;
- old_mode &= ~FILE_ATTRIBUTE_OFFLINE;
-
- smb_fname->st.st_ex_btime = new_create_timespec;
-
/* Store the DOS attributes in an EA by preference. */
status = SMB_VFS_SET_DOS_ATTRIBUTES(conn, smb_fname, dosmode);
if (NT_STATUS_IS_OK(status)) {