2005-10-20 22:15:44 +04:00
/*
Unix SMB / CIFS implementation .
VFS API ' s statvfs abstraction
Copyright ( C ) Alexander Bokovoy 2005
Copyright ( C ) Steve French 2005
2007-10-16 01:03:40 +04:00
Copyright ( C ) James Peach 2006
2005-10-20 22:15:44 +04:00
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-10-20 22:15:44 +04:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-10-20 22:15:44 +04:00
*/
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2005-10-20 22:15:44 +04:00
2006-07-11 22:01:26 +04:00
# if defined(LINUX) && defined(HAVE_FSID_INT)
2005-10-20 22:15:44 +04:00
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 ;
2007-10-16 01:03:40 +04:00
/* Good defaults for Linux filesystems are case sensitive
* and case preserving .
*/
statbuf - > FsCapabilities =
2007-12-20 19:31:27 +03:00
FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES ;
2005-10-20 22:15:44 +04:00
}
return result ;
}
# endif
2007-10-16 01:03:40 +04:00
# if defined(DARWINOS)
# include <sys/attr.h>
static int darwin_fs_capabilities ( const char * path )
{
int caps = 0 ;
vol_capabilities_attr_t * vcaps ;
struct attrlist attrlist ;
char attrbuf [ sizeof ( u_int32_t ) + sizeof ( vol_capabilities_attr_t ) ] ;
# define FORMAT_CAP(vinfo, cap) \
( ( ( vinfo ) - > valid [ VOL_CAPABILITIES_FORMAT ] & ( cap ) ) & & \
( ( vinfo ) - > capabilities [ VOL_CAPABILITIES_FORMAT ] & ( cap ) ) )
# define INTERFACE_CAP(vinfo, cap) \
( ( ( vinfo ) - > valid [ VOL_CAPABILITIES_INTERFACES ] & ( cap ) ) & & \
( ( vinfo ) - > capabilities [ VOL_CAPABILITIES_INTERFACES ] & ( cap ) ) )
ZERO_STRUCT ( attrlist ) ;
attrlist . bitmapcount = ATTR_BIT_MAP_COUNT ;
attrlist . volattr = ATTR_VOL_CAPABILITIES ;
if ( getattrlist ( path , & attrlist , attrbuf , sizeof ( attrbuf ) , 0 ) ! = 0 ) {
DEBUG ( 0 , ( " getattrlist for %s capabilities failed: %s \n " ,
path , strerror ( errno ) ) ) ;
/* Return no capabilities on failure. */
return 0 ;
}
vcaps =
( vol_capabilities_attr_t * ) ( attrbuf + sizeof ( u_int32_t ) ) ;
if ( FORMAT_CAP ( vcaps , VOL_CAP_FMT_SPARSE_FILES ) ) {
caps | = FILE_SUPPORTS_SPARSE_FILES ;
}
if ( FORMAT_CAP ( vcaps , VOL_CAP_FMT_CASE_SENSITIVE ) ) {
caps | = FILE_CASE_SENSITIVE_SEARCH ;
}
if ( FORMAT_CAP ( vcaps , VOL_CAP_FMT_CASE_PRESERVING ) ) {
caps | = FILE_CASE_PRESERVED_NAMES ;
}
if ( INTERFACE_CAP ( vcaps , VOL_CAP_INT_EXTENDED_SECURITY ) ) {
caps | = FILE_PERSISTENT_ACLS ;
}
return caps ;
}
static int darwin_statvfs ( const char * path , vfs_statvfs_struct * statbuf )
{
struct statfs sbuf ;
int ret ;
ret = statfs ( path , & sbuf ) ;
if ( ret ! = 0 ) {
return ret ;
}
statbuf - > OptimalTransferSize = sbuf . f_iosize ;
statbuf - > BlockSize = sbuf . f_bsize ;
statbuf - > TotalBlocks = sbuf . f_blocks ;
statbuf - > BlocksAvail = sbuf . f_bfree ;
statbuf - > UserBlocksAvail = sbuf . f_bavail ;
statbuf - > TotalFileNodes = sbuf . f_files ;
statbuf - > FreeFileNodes = sbuf . f_ffree ;
2008-10-14 03:59:36 +04:00
statbuf - > FsIdentifier = * ( uint64_t * ) ( & sbuf . f_fsid ) ; /* Ick. */
2007-10-16 01:03:40 +04:00
statbuf - > FsCapabilities = darwin_fs_capabilities ( sbuf . f_mntonname ) ;
return 0 ;
}
# endif
2005-10-20 22:15:44 +04:00
/*
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 )
{
2006-07-11 22:01:26 +04:00
# if defined(LINUX) && defined(HAVE_FSID_INT)
2005-10-20 22:15:44 +04:00
return linux_statvfs ( path , statbuf ) ;
2007-10-16 01:03:40 +04:00
# elif defined(DARWINOS)
return darwin_statvfs ( path , statbuf ) ;
2005-10-20 22:15:44 +04:00
# else
/* BB change this to return invalid level */
# ifdef EOPNOTSUPP
return EOPNOTSUPP ;
# else
return - 1 ;
# endif /* EOPNOTSUPP */
# endif /* LINUX */
}