Add SMB_VFS_FS_CAPABILITIES
authorVolker Lendecke <vl@samba.org>
Mon, 21 Jan 2008 14:10:44 +0000 (15:10 +0100)
committerVolker Lendecke <vl@samba.org>
Mon, 21 Jan 2008 15:14:27 +0000 (16:14 +0100)
It turns out that this is a necessary operation, separate from statvfs. statvfs
can fail during tcon, so conn->fs_capabilities would never see that we support
streams on a particular share.

James, can you check that I got the darwin variant right? Thanks!
(This used to be commit 3ad798d803b3b023533bb48e6993885f22b96095)

source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_default.c
source3/modules/vfs_streams_depot.c
source3/modules/vfs_streams_xattr.c
source3/smbd/service.c

index cda28a1680bd6352a7e28db982b3b5b7d4d7eb63..ca176aabb2b2f257d19ae384b970f09078db36d3 100644 (file)
@@ -149,6 +149,7 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_SET_QUOTA,
        SMB_VFS_OP_GET_SHADOW_COPY_DATA,
        SMB_VFS_OP_STATVFS,
+       SMB_VFS_OP_FS_CAPABILITIES,
 
        /* Directory operations */
 
@@ -284,6 +285,7 @@ struct vfs_ops {
                int (*set_quota)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
                int (*get_shadow_copy_data)(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels);
                int (*statvfs)(struct vfs_handle_struct *handle, const char *path, struct vfs_statvfs_struct *statbuf);
+               uint32_t (*fs_capabilities)(struct vfs_handle_struct *handle);
 
                /* Directory operations */
 
@@ -435,6 +437,7 @@ struct vfs_ops {
                struct vfs_handle_struct *set_quota;
                struct vfs_handle_struct *get_shadow_copy_data;
                struct vfs_handle_struct *statvfs;
+               struct vfs_handle_struct *fs_capabilities;
 
                /* Directory operations */
 
index 1674f26326411d94fa012b91a882aab0b3a166f0..1e64bd5ac3ef7ca8586c242322dc47b89c502857 100644 (file)
@@ -34,6 +34,7 @@
 #define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (qtype), (id), (qt)))
 #define SMB_VFS_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs.ops.get_shadow_copy_data((fsp)->conn->vfs.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
 #define SMB_VFS_STATVFS(conn, path, statbuf) ((conn)->vfs.ops.statvfs((conn)->vfs.handles.statvfs, (path), (statbuf)))
+#define SMB_VFS_FS_CAPABILITIES(conn) ((conn)->vfs.ops.fs_capabilities((conn)->vfs.handles.fs_capabilities))
 
 /* Directory operations */
 #define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (fname), (mask), (attr)))
 #define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (qtype), (id), (qt)))
 #define SMB_VFS_OPAQUE_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs_opaque.ops.get_shadow_copy_data((fsp)->conn->vfs_opaque.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
 #define SMB_VFS_OPAQUE_STATVFS(conn, path, statbuf) ((conn)->vfs_opaque.ops.statvfs((conn)->vfs_opaque.handles.statvfs, (path), (statbuf)))
+#define SMB_VFS_OPAQUE_FS_CAPABILITIES(conn) ((conn)->vfs_opaque.ops.fs_capabilities((conn)->vfs_opaque.handles.fs_capabilities))
 
 /* Directory operations */
 #define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (fname), (mask), (attr)))
 #define SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (qtype), (id), (qt)))
 #define SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data ,labels) ((handle)->vfs_next.ops.get_shadow_copy_data((handle)->vfs_next.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
 #define SMB_VFS_NEXT_STATVFS(handle, path, statbuf) ((handle)->vfs_next.ops.statvfs((handle)->vfs_next.handles.statvfs, (path), (statbuf)))
+#define SMB_VFS_NEXT_FS_CAPABILITIES(handle) ((handle)->vfs_next.ops.fs_capabilities((handle)->vfs_next.handles.fs_capabilities))
 
 /* Directory operations */
 #define SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (fname), (mask), (attr)))
index 2e620d04cc0ecd4aea6e30ac520acef971cf474c..17d0dfabaffb3705c5e6b1ff133aaaa66033ebf2 100644 (file)
@@ -90,6 +90,17 @@ static int vfswrap_statvfs(struct vfs_handle_struct *handle,  const char *path,
        return sys_statvfs(path, statbuf);
 }
 
+static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle)
+{
+#if defined(DARWINOS)
+       struct statfs sbuf;
+       ZERO_STRUCT(sbuf);
+       sys_statvfs(handle->conn->connectpath, &sbuf);
+       return sbuf.FsCapabilities;
+#endif
+       return FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+}
+
 /* Directory operations */
 
 static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle,  const char *fname, const char *mask, uint32 attr)
@@ -1330,6 +1341,8 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_statvfs),   SMB_VFS_OP_STATVFS,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_fs_capabilities), SMB_VFS_OP_FS_CAPABILITIES,
+        SMB_VFS_LAYER_OPAQUE},
 
        /* Directory operations */
 
index 68e7a75947b78aae48023c29eb205dcaa0a27e10..fa85ea4a57ee086cbb2128ab1379b3cb136568b3 100644 (file)
@@ -610,22 +610,15 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
-static int streams_depot_statvfs(struct vfs_handle_struct *handle,
-                                const char *path,
-                                struct vfs_statvfs_struct *statbuf)
+static uint32_t streams_depot_fs_capabilities(struct vfs_handle_struct *handle)
 {
-       int ret;
-
-       ret = SMB_VFS_NEXT_STATVFS(handle, path, statbuf);
-       statbuf->FsCapabilities |= FILE_NAMED_STREAMS;
-       return ret;
-
+       return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
 }
 
 /* VFS operations structure */
 
 static vfs_op_tuple streams_depot_ops[] = {
-       {SMB_VFS_OP(streams_depot_statvfs), SMB_VFS_OP_STATVFS,
+       {SMB_VFS_OP(streams_depot_fs_capabilities), SMB_VFS_OP_FS_CAPABILITIES,
         SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(streams_depot_open), SMB_VFS_OP_OPEN,
         SMB_VFS_LAYER_TRANSPARENT},
index 7ce90ab30bec54ce7b0a7ca7e1aa35e56328638b..965d57ff88d72c8906ea01caf75c88fb8170a39e 100644 (file)
@@ -560,16 +560,9 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
-static int streams_xattr_statvfs(struct vfs_handle_struct *handle,
-                                const char *path,
-                                struct vfs_statvfs_struct *statbuf)
+static uint32_t streams_xattr_fs_capabilities(struct vfs_handle_struct *handle)
 {
-       int ret;
-
-       ret = SMB_VFS_NEXT_STATVFS(handle, path, statbuf);
-       statbuf->FsCapabilities |= FILE_NAMED_STREAMS;
-       return ret;
-
+       return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
 }
 
 static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
@@ -663,7 +656,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
 /* VFS operations structure */
 
 static vfs_op_tuple streams_xattr_ops[] = {
-       {SMB_VFS_OP(streams_xattr_statvfs), SMB_VFS_OP_STATVFS,
+       {SMB_VFS_OP(streams_xattr_fs_capabilities), SMB_VFS_OP_FS_CAPABILITIES,
         SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(streams_xattr_open), SMB_VFS_OP_OPEN,
         SMB_VFS_LAYER_TRANSPARENT},
index ed8061e2f79c6e90b51b7eac7ab9bea42fc6541e..a8aa25405a9d81d1450dc2c3d76b68976f5ffb8f 100644 (file)
@@ -1171,16 +1171,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
         * assumes that all the filesystem mounted withing a share path have
         * the same characteristics, which is likely but not guaranteed.
         */
-       {
-               vfs_statvfs_struct svfs;
-
-               conn->fs_capabilities =
-                   FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
 
-               if (SMB_VFS_STATVFS(conn, conn->connectpath, &svfs) == 0) {
-                       conn->fs_capabilities = svfs.FsCapabilities;
-               }
-       }
+       conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn);
 
        /*
         * Print out the 'connected as' stuff here as we need