return -1;
}
+static int skel_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static uint32_t skel_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
{
.set_quota_fn = skel_set_quota,
.get_shadow_copy_data_fn = skel_get_shadow_copy_data,
.statvfs_fn = skel_statvfs,
+ .fstatvfs_fn = skel_fstatvfs,
.fs_capabilities_fn = skel_fs_capabilities,
.get_dfs_referrals_fn = skel_get_dfs_referrals,
.create_dfs_pathat_fn = skel_create_dfs_pathat,
return SMB_VFS_NEXT_STATVFS(handle, smb_fname, statbuf);
}
+static int skel_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ return SMB_VFS_NEXT_FSTATVFS(handle, fsp, statbuf);
+}
+
static uint32_t skel_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
{
.set_quota_fn = skel_set_quota,
.get_shadow_copy_data_fn = skel_get_shadow_copy_data,
.statvfs_fn = skel_statvfs,
+ .fstatvfs_fn = skel_fstatvfs,
.fs_capabilities_fn = skel_fs_capabilities,
.get_dfs_referrals_fn = skel_get_dfs_referrals,
.create_dfs_pathat_fn = skel_create_dfs_pathat,
* Version 52 - Add VFS_OPEN_HOW_RESOLVE_NO_XDEV for SMB_VFS_OPENAT()
* Change to Version 53 - will ship with 4.25
* Version 53 - Change DISK_FREE to take a fsp instead of a name
+ * Version 53 - Add fstatvfs
*/
#define SMB_VFS_INTERFACE_VERSION 53
int (*statvfs_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
struct vfs_statvfs_struct *statbuf);
+ int (*fstatvfs_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf);
uint32_t (*fs_capabilities_fn)(struct vfs_handle_struct *handle, enum timestamp_set_resolution *p_ts_res);
/*
int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
struct vfs_statvfs_struct *statbuf);
+int smb_vfs_call_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf);
uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res);
/*
int vfs_not_implemented_statvfs(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
struct vfs_statvfs_struct *statbuf);
+int vfs_not_implemented_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf);
uint32_t vfs_not_implemented_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res);
NTSTATUS vfs_not_implemented_get_dfs_referrals(struct vfs_handle_struct *handle,
#define SMB_VFS_NEXT_STATVFS(handle, smb_fname, statbuf) \
smb_vfs_call_statvfs((handle)->next, (smb_fname), (statbuf))
+#define SMB_VFS_FSTATVFS(conn, fsp, statbuf) \
+ smb_vfs_call_fstatvfs((conn)->vfs_handles, (fsp), (statbuf))
+#define SMB_VFS_NEXT_FSTATVFS(handle, fsp, statbuf) \
+ smb_vfs_call_fstatvfs((handle)->next, (fsp), (statbuf))
+
#define SMB_VFS_FS_CAPABILITIES(conn, p_ts_res) \
smb_vfs_call_fs_capabilities((conn)->vfs_handles, (p_ts_res))
#define SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) \
return ret;
}
+static int cephwrap_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ return cephwrap_statvfs(handle, fsp->fsp_name, statbuf);
+}
+
static uint32_t cephwrap_fs_capabilities(
struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
.get_quota_fn = vfs_not_implemented_get_quota,
.set_quota_fn = vfs_not_implemented_set_quota,
.statvfs_fn = cephwrap_statvfs,
+ .fstatvfs_fn = cephwrap_fstatvfs,
.fs_capabilities_fn = cephwrap_fs_capabilities,
/* Directory operations */
return status_code(ret);
}
+static int vfs_ceph_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ return vfs_ceph_statvfs(handle, fsp->fsp_name, statbuf);
+}
+
static uint32_t vfs_ceph_fs_capabilities(
struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
.get_quota_fn = vfs_not_implemented_get_quota,
.set_quota_fn = vfs_not_implemented_set_quota,
.statvfs_fn = vfs_ceph_statvfs,
+ .fstatvfs_fn = vfs_ceph_fstatvfs,
.fs_capabilities_fn = vfs_ceph_fs_capabilities,
/* Directory operations */
return sys_statvfs(smb_fname->base_name, statbuf);
}
+static int vfswrap_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ int ret, fd;
+
+ fd = fsp_get_pathref_fd(fsp);
+
+ ret = sys_fstatvfs(fd, statbuf);
+ return ret;
+}
+
static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
{
.set_quota_fn = vfswrap_set_quota,
.get_shadow_copy_data_fn = vfswrap_get_shadow_copy_data,
.statvfs_fn = vfswrap_statvfs,
+ .fstatvfs_fn = vfswrap_fstatvfs,
.fs_capabilities_fn = vfswrap_fs_capabilities,
.get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
.create_dfs_pathat_fn = vfswrap_create_dfs_pathat,
SMB_VFS_OP_SET_QUOTA,
SMB_VFS_OP_GET_SHADOW_COPY_DATA,
SMB_VFS_OP_STATVFS,
+ SMB_VFS_OP_FSTATVFS,
SMB_VFS_OP_FS_CAPABILITIES,
SMB_VFS_OP_GET_DFS_REFERRALS,
SMB_VFS_OP_CREATE_DFS_PATHAT,
{ SMB_VFS_OP_SET_QUOTA, "set_quota" },
{ SMB_VFS_OP_GET_SHADOW_COPY_DATA, "get_shadow_copy_data" },
{ SMB_VFS_OP_STATVFS, "statvfs" },
+ { SMB_VFS_OP_FSTATVFS, "fstatvfs" },
{ SMB_VFS_OP_FS_CAPABILITIES, "fs_capabilities" },
{ SMB_VFS_OP_GET_DFS_REFERRALS, "get_dfs_referrals" },
{ SMB_VFS_OP_CREATE_DFS_PATHAT, "create_dfs_pathat" },
return result;
}
+static int smb_full_audit_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ int result;
+
+ result = SMB_VFS_NEXT_FSTATVFS(handle, fsp, statbuf);
+
+ do_log(SMB_VFS_OP_FSTATVFS, errmsg_unix(result), handle, "");
+
+ return result;
+}
+
static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle, enum timestamp_set_resolution *p_ts_res)
{
int result;
.set_quota_fn = smb_full_audit_set_quota,
.get_shadow_copy_data_fn = smb_full_audit_get_shadow_copy_data,
.statvfs_fn = smb_full_audit_statvfs,
+ .fstatvfs_fn = smb_full_audit_fstatvfs,
.fs_capabilities_fn = smb_full_audit_fs_capabilities,
.get_dfs_referrals_fn = smb_full_audit_get_dfs_referrals,
.create_dfs_pathat_fn = smb_full_audit_create_dfs_pathat,
return ret;
}
+static int vfs_gluster_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *vfs_statvfs)
+{
+ return vfs_gluster_statvfs(handle, fsp->fsp_name, vfs_statvfs);
+}
+
static uint32_t vfs_gluster_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
{
.get_quota_fn = vfs_gluster_get_quota,
.set_quota_fn = vfs_gluster_set_quota,
.statvfs_fn = vfs_gluster_statvfs,
+ .fstatvfs_fn = vfs_gluster_fstatvfs,
.fs_capabilities_fn = vfs_gluster_fs_capabilities,
.get_dfs_referrals_fn = NULL,
return status;
}
+/*
+ * Success: return 0
+ * Failure: set errno, return -1
+ */
+static int mh_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ struct smb_filename *smb_fname = fsp->fsp_name;
+ char *clientPath = NULL;
+ struct smb_filename *clientFname = NULL;
+ NTSTATUS status;
+ int ret;
+
+ DEBUG(MH_INFO_DEBUG, ("Entering with path '%s'\n",
+ fsp_str_dbg(fsp)));
+
+ if (!is_in_media_files(smb_fname->base_name)) {
+ ret = SMB_VFS_NEXT_FSTATVFS(handle, fsp, statbuf);
+ return ret;
+ }
+
+ ret = alloc_get_client_path(handle,
+ talloc_tos(),
+ smb_fname->base_name,
+ &clientPath);
+ if (ret != 0) {
+ goto err;
+ }
+
+ status = synthetic_pathref(talloc_tos(),
+ handle->conn->cwd_fsp,
+ clientPath,
+ smb_fname->stream_name,
+ NULL,
+ smb_fname->twrp,
+ smb_fname->flags,
+ &clientFname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ ret = -1;
+ goto err;
+ }
+
+ ret = SMB_VFS_NEXT_FSTATVFS(handle, clientFname->fsp, statbuf);
+
+err:
+ {
+ int err = errno;
+ TALLOC_FREE(clientFname);
+
+ DEBUG(MH_INFO_DEBUG, ("Leaving with path '%s'\n",
+ fsp_str_dbg(fsp)));
+
+ errno = err;
+ }
+
+ return ret;
+}
+
static int alloc_set_client_dirinfo(vfs_handle_struct *handle,
const char *fname,
struct mh_dirinfo_struct **dirInfo)
/* Disk operations */
.statvfs_fn = mh_statvfs,
+ .fstatvfs_fn = mh_fstatvfs,
/* Directory operations */
return -1;
}
+_PUBLIC_
+int vfs_not_implemented_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
_PUBLIC_
uint32_t vfs_not_implemented_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
.set_quota_fn = vfs_not_implemented_set_quota,
.get_shadow_copy_data_fn = vfs_not_implemented_get_shadow_copy_data,
.statvfs_fn = vfs_not_implemented_statvfs,
+ .fstatvfs_fn = vfs_not_implemented_fstatvfs,
.fs_capabilities_fn = vfs_not_implemented_fs_capabilities,
.get_dfs_referrals_fn = vfs_not_implemented_get_dfs_referrals,
.create_dfs_pathat_fn = vfs_not_implemented_create_dfs_pathat,
return result;
}
+static int smb_time_audit_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ int result;
+ struct timespec ts1, ts2;
+ double timediff;
+
+ clock_gettime_mono(&ts1);
+ result = SMB_VFS_NEXT_FSTATVFS(handle, fsp, statbuf);
+ clock_gettime_mono(&ts2);
+ timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
+
+ if (timediff > audit_timeout) {
+ smb_time_audit_log_fname("fstatvfs",
+ timediff,
+ fsp_str_dbg(fsp));
+ }
+
+ return result;
+}
+
static uint32_t smb_time_audit_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
{
.set_quota_fn = smb_time_audit_set_quota,
.get_shadow_copy_data_fn = smb_time_audit_get_shadow_copy_data,
.statvfs_fn = smb_time_audit_statvfs,
+ .fstatvfs_fn = smb_time_audit_fstatvfs,
.fs_capabilities_fn = smb_time_audit_fs_capabilities,
.get_dfs_referrals_fn = smb_time_audit_get_dfs_referrals,
.create_dfs_pathat_fn = smb_time_audit_create_dfs_pathat,
return status;
}
+/*
+ * Success: return 0
+ * Failure: set errno, return -1
+ */
+static int um_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ struct smb_filename *smb_fname = fsp->fsp_name;
+ char *clientPath = NULL;
+ struct smb_filename *clientFname = NULL;
+ NTSTATUS status;
+ int ret;
+
+ DBG_DEBUG("Entering with path '%s'\n", fsp_str_dbg(fsp));
+
+ if (!is_in_media_files(smb_fname->base_name)) {
+ ret = SMB_VFS_NEXT_FSTATVFS(handle, fsp, statbuf);
+ return ret;
+ }
+
+ ret = alloc_get_client_path(handle,
+ talloc_tos(),
+ smb_fname->base_name,
+ &clientPath);
+ if (ret != 0) {
+ goto err;
+ }
+
+ status = synthetic_pathref(talloc_tos(),
+ handle->conn->cwd_fsp,
+ clientPath,
+ smb_fname->stream_name,
+ NULL,
+ smb_fname->twrp,
+ smb_fname->flags,
+ &clientFname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ ret = -1;
+ goto err;
+ }
+
+ ret = SMB_VFS_NEXT_FSTATVFS(handle, clientFname->fsp, statbuf);
+
+err:
+ {
+ int err = errno;
+ TALLOC_FREE(clientFname);
+
+ DBG_DEBUG("Leaving with path '%s'\n", fsp_str_dbg(fsp));
+ errno = err;
+ }
+
+ return ret;
+}
+
static DIR *um_fdopendir(vfs_handle_struct *handle,
files_struct *fsp,
const char *mask,
/* Disk operations */
.statvfs_fn = um_statvfs,
+ .fstatvfs_fn = um_fstatvfs,
/* Directory operations */
return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
}
+int smb_vfs_call_fstatvfs(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct vfs_statvfs_struct *statbuf)
+{
+ VFS_FIND(fstatvfs);
+ return handle->fns->fstatvfs_fn(handle, fsp, statbuf);
+}
+
uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
enum timestamp_set_resolution *p_ts_res)
{