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
2012-03-02 03:45:51 +04:00
# if defined(DARWINOS)
2007-10-16 01:03:40 +04:00
# 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 ;
}
2012-06-28 23:34:40 +04:00
# endif /* DARWINOS */
2007-10-16 01:03:40 +04:00
2012-06-28 23:34:40 +04:00
# if defined(BSD_STYLE_STATVFS)
static int bsd_statvfs ( const char * path , vfs_statvfs_struct * statbuf )
2007-10-16 01:03:40 +04:00
{
struct statfs sbuf ;
int ret ;
ret = statfs ( path , & sbuf ) ;
2012-06-29 19:01:47 +04:00
if ( ret = = 0 ) {
2012-06-28 23:34:40 +04:00
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 ;
statbuf - > FsIdentifier =
( ( ( uint64_t ) sbuf . f_fsid . val [ 0 ] < < 32 ) & 0xffffffff00000000LL ) |
( uint64_t ) sbuf . f_fsid . val [ 1 ] ;
# ifdef DARWINOS
statbuf - > FsCapabilities = darwin_fs_capabilities ( sbuf . f_mntonname ) ;
# else
/* Try to extrapolate some of the fs flags into the
* capabilities
*/
statbuf - > FsCapabilities =
FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES ;
2012-02-25 12:28:43 +04:00
# ifdef MNT_ACLS
2012-06-28 23:34:40 +04:00
if ( sbuf . f_flags & MNT_ACLS )
statbuf - > FsCapabilities | = FILE_PERSISTENT_ACLS ;
2012-07-05 13:43:16 +04:00
# endif
2012-02-25 12:28:43 +04:00
# endif
2012-06-28 23:34:40 +04:00
if ( sbuf . f_flags & MNT_QUOTA )
statbuf - > FsCapabilities | = FILE_VOLUME_QUOTAS ;
if ( sbuf . f_flags & MNT_RDONLY )
statbuf - > FsCapabilities | = FILE_READ_ONLY_VOLUME ;
}
2012-02-25 12:28:43 +04:00
2012-06-28 23:34:40 +04:00
return ret ;
2012-02-25 12:28:43 +04:00
}
2012-03-02 03:45:51 +04:00
# elif defined(STAT_STATVFS) && defined(HAVE_FSID_INT)
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 ;
2012-03-10 22:16:06 +04:00
/* Try to extrapolate some of the fs flags into the
* capabilities
2012-03-02 03:45:51 +04:00
*/
statbuf - > FsCapabilities =
FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES ;
2012-03-10 22:16:06 +04:00
# ifdef ST_QUOTA
if ( statvfs_buf . f_flag & ST_QUOTA )
statbuf - > FsCapabilities | = FILE_VOLUME_QUOTAS ;
# endif
if ( statvfs_buf . f_flag & ST_RDONLY )
statbuf - > FsCapabilities | = FILE_READ_ONLY_VOLUME ;
2015-02-19 18:46:56 +03:00
# if defined(HAVE_FALLOC_FL_PUNCH_HOLE) && defined(HAVE_LSEEK_HOLE_DATA)
/*
* Only flag sparse file support if ZERO_DATA can be used to
* deallocate blocks , and SEEK_HOLE / SEEK_DATA can be used
* to provide QUERY_ALLOCATED_RANGES information .
*/
statbuf - > FsCapabilities | = FILE_SUPPORTS_SPARSE_FILES ;
# endif
2012-03-02 03:45:51 +04:00
}
return result ;
}
2007-10-16 01:03:40 +04:00
# 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
2014-03-30 06:05:09 +04:00
so that particular OS would use its preferred interface .
2005-10-20 22:15:44 +04:00
*/
int sys_statvfs ( const char * path , vfs_statvfs_struct * statbuf )
{
2012-06-28 23:34:40 +04:00
# if defined(BSD_STYLE_STATVFS)
2012-02-25 12:28:43 +04:00
return bsd_statvfs ( path , statbuf ) ;
2012-03-02 03:45:51 +04:00
# elif defined(STAT_STATVFS) && defined(HAVE_FSID_INT)
return linux_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 */
}