--- /home/stevef/samba-3-trunk/source/include/vfs.h 2005-07-12 17:21:33.000000000 -0500 +++ source/include/vfs.h 2005-08-01 12:02:17.000000000 -0500 @@ -3,7 +3,7 @@ VFS structures and parameters Copyright (C) Jeremy Allison 1999-2005 Copyright (C) Tim Potter 1999 - Copyright (C) Alexander Bokovoy 2002 + Copyright (C) Alexander Bokovoy 2002-2005 Copyright (C) Stefan (metze) Metzmacher 2003 This program is free software; you can redistribute it and/or modify @@ -81,6 +81,7 @@ struct connection_struct; struct files_struct; struct security_descriptor_info; +struct vfs_statvfs_struct; /* Available VFS operations. These values must be in sync with vfs_ops struct @@ -100,7 +101,7 @@ SMB_VFS_OP_GET_QUOTA, SMB_VFS_OP_SET_QUOTA, SMB_VFS_OP_GET_SHADOW_COPY_DATA, - + SMB_VFS_OP_STATVFS, /* Directory operations */ @@ -221,6 +222,7 @@ int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, 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, struct connection_struct *conn, const char *path, struct vfs_statvfs_struct *statbuf); /* Directory operations */ @@ -333,6 +335,7 @@ struct vfs_handle_struct *get_quota; struct vfs_handle_struct *set_quota; struct vfs_handle_struct *get_shadow_copy_data; + struct vfs_handle_struct *statvfs; /* Directory operations */ @@ -494,6 +497,29 @@ } vfs_handle_struct; +typedef struct _vfs_statvfs_struct { + /* For undefined recommended transfer size return -1 in that field */ + uint32 OptimalTransferSize; /* bsize on some os, iosize on other os */ + uint32 BlockSize; + /* The next three fields are in terms of the block size. + (above). If block size is unknown, 4096 would be a + reasonable block size for a server to report. + Note that returning the blocks/blocksavail removes need + to make a second call (to QFSInfo level 0x103 to get this info. + UserBlockAvail is typically less than or equal to BlocksAvail, + if no distinction is made return the same value in each */ + SMB_BIG_UINT TotalBlocks; + SMB_BIG_UINT BlocksAvail; /* bfree */ + SMB_BIG_UINT UserBlocksAvail; /* bavail */ + /* For undefined Node fields or FSID return -1 */ + SMB_BIG_UINT TotalFileNodes; + SMB_BIG_UINT FreeFileNodes; + SMB_BIG_UINT FsIdentifier; /* fsid */ + /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */ + /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */ +} vfs_statvfs_struct; + + #define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \ if (!(handle)||((datap=(type *)(handle)->data)==NULL)) { \ DEBUG(0,("%s() failed to get vfs_handle->data!\n",FUNCTION_MACRO)); \ --- /home/stevef/samba-3-trunk/source/include/vfs_macros.h 2005-07-12 17:21:33.000000000 -0500 +++ source/include/vfs_macros.h 2005-08-01 12:06:32.000000000 -0500 @@ -34,6 +34,7 @@ #define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (conn), (qtype), (id), (qt))) #define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (conn), (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, (conn), (path), (statbuf))) /* Directory operations */ #define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname), (mask), (attr))) @@ -144,6 +145,7 @@ #define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (conn), (qtype), (id), (qt))) #define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (conn), (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, (conn), (path), (statbuf))) /* Directory operations */ #define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname), (mask), (attr))) @@ -254,6 +256,7 @@ #define SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (conn), (qtype), (id), (qt))) #define SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (conn), (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(conn, path, statbuf) ((conn)->vfs_next.ops.statvfs((conn)->vfs_next.handles.statvfs, (conn), (path), (statbuf))) /* Directory operations */ #define SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname), (mask), (attr))) Index: source/Makefile.in =================================================================== --- source/Makefile.in (revision 8175) +++ source/Makefile.in (working copy) @@ -387,7 +387,7 @@ lib/sysquotas_xfs.o lib/sysquotas_4A.o \ smbd/change_trust_pw.o smbd/fake_file.o \ smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \ - $(AFS_SETTOKEN_OBJ) smbd/aio.o \ + $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \ $(MANGLE_OBJ) @VFS_STATIC@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ --- /home/stevef/samba-3-trunk/source/smbd/vfs.c 2005-07-12 17:21:30.000000000 -0500 +++ source/smbd/vfs.c 2005-07-18 11:39:57.000000000 -0500 @@ -57,6 +57,7 @@ vfswrap_get_quota, vfswrap_set_quota, vfswrap_get_shadow_copy_data, + vfswrap_statvfs, /* Directory operations */ --- /home/stevef/samba-3-trunk/source/smbd/vfs-wrap.c 2005-07-12 17:21:30.000000000 -0500 +++ source/smbd/vfs-wrap.c 2005-07-18 11:39:57.000000000 -0500 @@ -86,6 +86,11 @@ return -1; /* Not implemented. */ } +int vfswrap_statvfs(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, vfs_statvfs_struct *statbuf) +{ + return sys_statvfs(path, statbuf); +} + /* Directory operations */ DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr) --- /home/stevef/samba-3-trunk/source/smbd/statvfs.c 1969-12-31 18:00:00.000000000 -0600 +++ smbd/statvfs.c 2005-08-01 15:47:16.000000000 -0500 @@ -0,0 +1,65 @@ +/* + Unix SMB/CIFS implementation. + VFS API's statvfs abstraction + Copyright (C) Alexander Bokovoy 2005 + Copyright (C) Steve French 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#if defined(LINUX) +static int linux_statvfs(const char *path, vfs_statvfs_struct *statbuf) +{ + struct statvfs statvfs_buf; + int result; + + result = statvfs(path, &statvfs_buf); + + if (!result) { + statbuf->OptimalTransferSize = statvfs_buf.f_frsize; + statbuf->BlockSize = statvfs_buf.f_bsize; + statbuf->TotalBlocks = statvfs_buf.f_blocks; + statbuf->BlocksAvail = statvfs_buf.f_bfree; + statbuf->UserBlocksAvail = statvfs_buf.f_bavail; + statbuf->TotalFileNodes = statvfs_buf.f_files; + statbuf->FreeFileNodes = statvfs_buf.f_ffree; + statbuf->FsIdentifier = statvfs_buf.f_fsid; + } + return result; +} +#endif + +/* + sys_statvfs() is an abstraction layer over system-dependent statvfs()/statfs() + for particular POSIX systems. Due to controversy of what is considered more important + between LSB and FreeBSD/POSIX.1 (IEEE Std 1003.1-2001) we need to abstract the interface + so that particular OS would use its preffered interface. +*/ +int sys_statvfs(const char *path, vfs_statvfs_struct *statbuf) +{ +#if defined(LINUX) + return linux_statvfs(path, statbuf); +#else + /* BB change this to return invalid level */ +#ifdef EOPNOTSUPP + return EOPNOTSUPP; +#else + return -1; +#endif /* EOPNOTSUPP */ +#endif /* LINUX */ + +} --- /home/stevef/samba-3-trunk/source/smbd/trans2.c 2005-07-12 17:21:30.000000000 -0500 +++ smbd/trans2.c 2005-08-01 15:56:30.000000000 -0500 @@ -4,6 +4,7 @@ Copyright (C) Jeremy Allison 1994-2003 Copyright (C) Stefan (metze) Metzmacher 2003 Copyright (C) Volker Lendecke 2005 + Copyright (C) Steve French 2005 Extensively modified by Andrew Tridgell, 1995 @@ -2404,6 +2405,38 @@ CIFS_UNIX_POSIX_PATHNAMES_CAP))); /* We have POSIX ACLs and pathname capability. */ break; + case SMB_QUERY_POSIX_FS_INFO: + { + int rc; + vfs_statvfs_struct svfs; + + if (!lp_unix_extensions()) + return ERROR_DOS(ERRDOS,ERRunknownlevel); + + rc = SMB_VFS_STATVFS(conn, ".", &svfs); + + if (!rc) { + data_len = 56; + SIVAL(pdata,0,svfs.OptimalTransferSize); + SIVAL(pdata,4,svfs.BlockSize); + SBIG_UINT(pdata,8,svfs.TotalBlocks); + SBIG_UINT(pdata,16,svfs.BlocksAvail); + SBIG_UINT(pdata,24,svfs.UserBlocksAvail); + SBIG_UINT(pdata,32,svfs.TotalFileNodes); + SBIG_UINT(pdata,40,svfs.FreeFileNodes); + SBIG_UINT(pdata,48,svfs.FsIdentifier); + DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n")); +#ifdef EOPNOTSUPP + } else if (rc == EOPNOTSUPP) { + return ERROR_DOS(ERRDOS, ERRunknownlevel); +#endif /* EOPNOTSUPP */ + } else { + DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn)))); + return ERROR_DOS(ERRSRV,ERRerror); + } + break; + } + case SMB_MAC_QUERY_FS_INFO: /* * Thursby MAC extension... ONLY on NTFS filesystems