LCOV - code coverage report
Current view: top level - source3/smbd - statvfs.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 19 20 95.0 %
Date: 2024-04-21 15:09:00 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    VFS API's statvfs abstraction
       4             :    Copyright (C) Alexander Bokovoy                      2005
       5             :    Copyright (C) Steve French                           2005
       6             :    Copyright (C) James Peach                            2006
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "system/filesys.h"
      24             : #include "smbd/smbd.h"
      25             : 
      26             : #if defined(DARWINOS)
      27             : #include <sys/attr.h>
      28             : 
      29             : static int darwin_fs_capabilities(const char * path)
      30             : {
      31             :         int caps = 0;
      32             :         vol_capabilities_attr_t *vcaps;
      33             :         struct attrlist attrlist;
      34             :         char attrbuf[sizeof(u_int32_t) + sizeof(vol_capabilities_attr_t)];
      35             : 
      36             : #define FORMAT_CAP(vinfo, cap) \
      37             :         ( ((vinfo)->valid[VOL_CAPABILITIES_FORMAT] & (cap)) && \
      38             :            ((vinfo)->capabilities[VOL_CAPABILITIES_FORMAT] & (cap)) )
      39             : 
      40             : #define INTERFACE_CAP(vinfo, cap) \
      41             :         ( ((vinfo)->valid[VOL_CAPABILITIES_INTERFACES] & (cap)) && \
      42             :            ((vinfo)->capabilities[VOL_CAPABILITIES_INTERFACES] & (cap)) )
      43             : 
      44             :         ZERO_STRUCT(attrlist);
      45             :         attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
      46             :         attrlist.volattr = ATTR_VOL_CAPABILITIES;
      47             : 
      48             :         if (getattrlist(path, &attrlist, attrbuf, sizeof(attrbuf), 0) != 0) {
      49             :                 DEBUG(0, ("getattrlist for %s capabilities failed: %s\n",
      50             :                             path, strerror(errno)));
      51             :                 /* Return no capabilities on failure. */
      52             :                 return 0;
      53             :         }
      54             : 
      55             :         vcaps =
      56             :             (vol_capabilities_attr_t *)(attrbuf + sizeof(u_int32_t));
      57             : 
      58             :         if (FORMAT_CAP(vcaps, VOL_CAP_FMT_SPARSE_FILES)) {
      59             :                 caps |= FILE_SUPPORTS_SPARSE_FILES;
      60             :         }
      61             : 
      62             :         if (FORMAT_CAP(vcaps, VOL_CAP_FMT_CASE_SENSITIVE)) {
      63             :                 caps |= FILE_CASE_SENSITIVE_SEARCH;
      64             :         }
      65             : 
      66             :         if (FORMAT_CAP(vcaps, VOL_CAP_FMT_CASE_PRESERVING)) {
      67             :                 caps |= FILE_CASE_PRESERVED_NAMES;
      68             :         }
      69             : 
      70             :         if (INTERFACE_CAP(vcaps, VOL_CAP_INT_EXTENDED_SECURITY)) {
      71             :                 caps |= FILE_PERSISTENT_ACLS;
      72             :         }
      73             : 
      74             :         return caps;
      75             : }
      76             : #endif /* DARWINOS */
      77             : 
      78             : #if defined(BSD_STYLE_STATVFS)
      79             : static int bsd_statvfs(const char *path, struct vfs_statvfs_struct *statbuf)
      80             : {
      81             :         struct statfs sbuf;
      82             :         int ret;
      83             : 
      84             :         ret = statfs(path, &sbuf);
      85             :         if (ret == 0) {
      86             :                 statbuf->OptimalTransferSize = sbuf.f_iosize;
      87             :                 statbuf->BlockSize = sbuf.f_bsize;
      88             :                 statbuf->TotalBlocks = sbuf.f_blocks;
      89             :                 statbuf->BlocksAvail = sbuf.f_bfree;
      90             :                 statbuf->UserBlocksAvail = sbuf.f_bavail;
      91             :                 statbuf->TotalFileNodes = sbuf.f_files;
      92             :                 statbuf->FreeFileNodes = sbuf.f_ffree;
      93             :                 statbuf->FsIdentifier =
      94             :                         (((uint64_t) sbuf.f_fsid.val[0] << 32) & 0xffffffff00000000LL) |
      95             :                             (uint64_t) sbuf.f_fsid.val[1];
      96             : #ifdef DARWINOS
      97             :                 statbuf->FsCapabilities = darwin_fs_capabilities(sbuf.f_mntonname);
      98             : #else
      99             :                 /* Try to extrapolate some of the fs flags into the
     100             :                  * capabilities
     101             :                  */
     102             :                 statbuf->FsCapabilities =
     103             :                     FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
     104             : #ifdef MNT_ACLS
     105             :                 if (sbuf.f_flags & MNT_ACLS)
     106             :                         statbuf->FsCapabilities |= FILE_PERSISTENT_ACLS;
     107             : #endif
     108             : #endif
     109             :                 if (sbuf.f_flags & MNT_QUOTA)
     110             :                         statbuf->FsCapabilities |= FILE_VOLUME_QUOTAS;
     111             :                 if (sbuf.f_flags & MNT_RDONLY)
     112             :                         statbuf->FsCapabilities |= FILE_READ_ONLY_VOLUME;
     113             :         }
     114             : 
     115             :         return ret;
     116             : }
     117             : #elif defined(STAT_STATVFS) && defined(HAVE_FSID_INT)
     118       30712 : static int posix_statvfs(const char *path, struct vfs_statvfs_struct *statbuf)
     119             : {
     120         474 :         struct statvfs statvfs_buf;
     121         474 :         int result;
     122             : 
     123       30712 :         result = statvfs(path, &statvfs_buf);
     124             : 
     125       30712 :         if (!result) {
     126             :                 /* statvfs bsize is not the statfs bsize, the naming is terrible,
     127             :                  * see bug 11810 */
     128       30712 :                 statbuf->OptimalTransferSize = statvfs_buf.f_bsize;
     129       30712 :                 statbuf->BlockSize = statvfs_buf.f_frsize;
     130       30712 :                 statbuf->TotalBlocks = statvfs_buf.f_blocks;
     131       30712 :                 statbuf->BlocksAvail = statvfs_buf.f_bfree;
     132       30712 :                 statbuf->UserBlocksAvail = statvfs_buf.f_bavail;
     133       30712 :                 statbuf->TotalFileNodes = statvfs_buf.f_files;
     134       30712 :                 statbuf->FreeFileNodes = statvfs_buf.f_ffree;
     135       30712 :                 statbuf->FsIdentifier = statvfs_buf.f_fsid;
     136             :                 /* Try to extrapolate some of the fs flags into the
     137             :                  * capabilities
     138             :                  */
     139       30712 :                 statbuf->FsCapabilities =
     140             :                     FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
     141             : #ifdef ST_QUOTA
     142             :                 if (statvfs_buf.f_flag & ST_QUOTA)
     143             :                         statbuf->FsCapabilities |= FILE_VOLUME_QUOTAS;
     144             : #endif
     145       30712 :                 if (statvfs_buf.f_flag & ST_RDONLY)
     146           0 :                         statbuf->FsCapabilities |= FILE_READ_ONLY_VOLUME;
     147             : 
     148             : #if defined(HAVE_FALLOC_FL_PUNCH_HOLE) && defined(HAVE_LSEEK_HOLE_DATA)
     149             :                 /*
     150             :                  * Only flag sparse file support if ZERO_DATA can be used to
     151             :                  * deallocate blocks, and SEEK_HOLE / SEEK_DATA can be used
     152             :                  * to provide QUERY_ALLOCATED_RANGES information.
     153             :                  */
     154       30712 :                 statbuf->FsCapabilities |= FILE_SUPPORTS_SPARSE_FILES;
     155             : #endif
     156             :         }
     157       30712 :         return result;
     158             : }
     159             : #endif
     160             : 
     161             : /* 
     162             :  sys_statvfs() is an abstraction layer over system-dependent statvfs()/statfs()
     163             :  for particular POSIX systems. Due to controversy of what is considered more important
     164             :  between LSB and FreeBSD/POSIX.1 (IEEE Std 1003.1-2001) we need to abstract the interface
     165             :  so that particular OS would use its preferred interface.
     166             : */
     167       30712 : int sys_statvfs(const char *path, struct vfs_statvfs_struct *statbuf)
     168             : {
     169             : #if defined(BSD_STYLE_STATVFS)
     170             :         return bsd_statvfs(path, statbuf);
     171             : #elif defined(STAT_STATVFS) && defined(HAVE_FSID_INT)
     172       30712 :         return posix_statvfs(path, statbuf);
     173             : #else
     174             :         /* BB change this to return invalid level */
     175             : #ifdef EOPNOTSUPP
     176             :         return EOPNOTSUPP;
     177             : #else
     178             :         return -1;
     179             : #endif /* EOPNOTSUPP */
     180             : #endif /* LINUX */
     181             : 
     182             : }

Generated by: LCOV version 1.14