diff -Naur samba-2.2.1a/source/smbd/quotas.c samba-2.2.1a+ns/source/smbd/quotas.c --- samba-2.2.1a/source/smbd/quotas.c Thu Jul 5 21:02:03 2001 +++ samba-2.2.1a+ns/source/smbd/quotas.c Sun Sep 9 09:29:58 2001 @@ -44,13 +44,10 @@ #ifdef LINUX #include -#include +#include #include - #include -#include - -_syscall4(int, quotactl, int, cmd, const char *, special, int, id, caddr_t, addr); +#include "quotas.h" /**************************************************************************** try to get the disk space from disk quotas (LINUX version) @@ -59,18 +56,20 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; - struct dqblk D; + v1_kern_dqblk_t D1; + v2_kern_dqblk_t D2; + fs_disk_quota_t DX; SMB_STRUCT_STAT S; FILE *fp; struct mntent *mnt; SMB_DEV_T devno; int found; uid_t euser_id; + static int version = 1; /* VFS quota version */ euser_id = geteuid(); - + /* find the block device file */ - if ( sys_stat(path, &S) == -1 ) { return(False) ; } @@ -91,47 +90,109 @@ endmntent(fp) ; if (!found) { - return(False); - } + return(False); + } save_re_uid(); set_effective_uid(0); - r=quotactl(QCMD(Q_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D); + if (strcmp(mnt->mnt_type, "xfs") == 0) + r = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&DX); + else { + if (version == 1) { + r = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D1); + if (r == EINVAL) + version = 2; + } + if (version == 2) + r = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D2); + } restore_re_uid(); - /* Use softlimit to determine disk space, except when it has been exceeded */ - *bsize = 1024; if (r) - { - if (errno == EDQUOT) - { - *dfree =0; - *dsize =D.dqb_curblocks; - return (True); - } - else return(False); + return(False); + + if (version == 1) + { + *bsize = 1024; + /* Use softlimit to determine disk space, except when its been exceeded */ + if ( + (D1.dqb_bsoftlimit && D1.dqb_curblocks>=D1.dqb_bsoftlimit) || + (D1.dqb_bhardlimit && D1.dqb_curblocks>=D1.dqb_bhardlimit) || + (D1.dqb_isoftlimit && D1.dqb_curinodes>=D1.dqb_isoftlimit) || + (D1.dqb_ihardlimit && D1.dqb_curinodes>=D1.dqb_ihardlimit) + ) + { + *dfree = 0; + *dsize = D1.dqb_curblocks; + } + else if (D1.dqb_bsoftlimit==0 && D1.dqb_bhardlimit==0) + { + return(False); + } + else + { + if (D1.dqb_bsoftlimit == 0) + D1.dqb_bsoftlimit = D1.dqb_bhardlimit; + *dfree = D1.dqb_bsoftlimit - D1.dqb_curblocks; + *dsize = D1.dqb_bsoftlimit; + } + } + else if (version == 2) + { + *bsize = 1024; + D2.dqb_curspace >>= 10; /* bytes to Kbytes */ + /* Use softlimit to determine disk space, except when its been exceeded */ + if ( + (D2.dqb_bsoftlimit && D2.dqb_curspace >=D2.dqb_bsoftlimit) || + (D2.dqb_bhardlimit && D2.dqb_curspace >=D2.dqb_bhardlimit) || + (D2.dqb_isoftlimit && D2.dqb_curinodes>=D2.dqb_isoftlimit) || + (D2.dqb_ihardlimit && D2.dqb_curinodes>=D2.dqb_ihardlimit) + ) + { + *dfree = 0; + *dsize = D2.dqb_curspace; + } + else if (D2.dqb_bsoftlimit==0 && D2.dqb_bhardlimit==0) + { + return(False); + } + else + { + if (D2.dqb_bsoftlimit == 0) + D2.dqb_bsoftlimit = D2.dqb_bhardlimit; + *dfree = D2.dqb_bsoftlimit - D2.dqb_curspace; + *dsize = D2.dqb_bsoftlimit; + } } - /* Use softlimit to determine disk space, except when it has been exceeded */ - if ( - (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) || - (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) || - (D.dqb_isoftlimit && D.dqb_curinodes>=D.dqb_isoftlimit) || - (D.dqb_ihardlimit && D.dqb_curinodes>=D.dqb_ihardlimit) - ) + else if (strcmp(mnt->mnt_type, "xfs") == 0) + { + *bsize = 512; + /* Use softlimit to determine disk space, except when its been exceeded */ + if ( + (DX.d_blk_softlimit && DX.d_bcount>=DX.d_blk_softlimit) || + (DX.d_blk_hardlimit && DX.d_bcount>=DX.d_blk_hardlimit) || + (DX.d_ino_softlimit && DX.d_icount>=DX.d_ino_softlimit) || + (DX.d_ino_hardlimit && DX.d_icount>=DX.d_ino_hardlimit) + ) { *dfree = 0; - *dsize = D.dqb_curblocks; + *dsize = DX.d_bcount; } - else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0) + else if (DX.d_blk_softlimit==0 && DX.d_blk_hardlimit==0) { return(False); } - else { - if (D.dqb_bsoftlimit == 0) - D.dqb_bsoftlimit = D.dqb_bhardlimit; - *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; - *dsize = D.dqb_bsoftlimit; + else + { + *dfree = (DX.d_blk_softlimit - DX.d_bcount); + *dsize = DX.d_blk_softlimit; + } } + else + { + return(False); + } + return (True); } diff -Naur samba-2.2.1a/source/smbd/quotas.h samba-2.2.1a+ns/source/smbd/quotas.h --- samba-2.2.1a/source/smbd/quotas.h Wed Dec 31 19:00:00 1969 +++ samba-2.2.1a+ns/source/smbd/quotas.h Sun Sep 9 09:29:58 2001 @@ -0,0 +1,58 @@ +#ifdef LINUX + +#define Q_V1_GETQUOTA 0x0300 /* VFS quota, version 1 */ +#define Q_V2_GETQUOTA 0x0D00 /* VFS quota, version 2 */ +#define Q_XGETQUOTA (('X'<<8)+0x3) /* XFS quota */ + +/* struct for Q_V1_GETQUOTA */ +typedef struct v1_kern_dqblk { + u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ + u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */ + u_int32_t dqb_curblocks; /* current block count */ + u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */ + u_int32_t dqb_isoftlimit; /* preferred inode limit */ + u_int32_t dqb_curinodes; /* current # allocated inodes */ + time_t dqb_btime; /* time limit for excessive disk use */ + time_t dqb_itime; /* time limit for excessive files */ +} v1_kern_dqblk_t; + +/* struct for Q_V2_GETQUOTA */ +typedef u_int64_t qsize_t; +typedef struct v2_kern_dqblk { + unsigned int dqb_ihardlimit; + unsigned int dqb_isoftlimit; + unsigned int dqb_curinodes; + unsigned int dqb_bhardlimit; + unsigned int dqb_bsoftlimit; + qsize_t dqb_curspace; + time_t dqb_btime; + time_t dqb_itime; +} v2_kern_dqblk_t; + +/* struct for Q_XGETQUOTA */ +typedef struct fs_disk_quota { + __s8 d_version; /* version of this structure */ + __s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */ + __u16 d_fieldmask; /* field specifier */ + __u32 d_id; /* user, project, or group ID */ + __u64 d_blk_hardlimit; /* absolute limit on disk blks */ + __u64 d_blk_softlimit; /* preferred limit on disk blks */ + __u64 d_ino_hardlimit; /* maximum # allocated inodes */ + __u64 d_ino_softlimit; /* preferred inode limit */ + __u64 d_bcount; /* # disk blocks owned by the user */ + __u64 d_icount; /* # inodes owned by the user */ + __s32 d_itimer; /* zero if within inode limits */ + __s32 d_btimer; /* similar to above; for disk blocks */ + __u16 d_iwarns; /* # warnings issued wrt num inodes */ + __u16 d_bwarns; /* # warnings issued wrt disk blocks */ + __s32 d_padding2; /* padding2 - for future use */ + __u64 d_rtb_hardlimit; /* absolute limit on realtime blks */ + __u64 d_rtb_softlimit; /* preferred limit on RT disk blks */ + __u64 d_rtbcount; /* # realtime blocks owned */ + __s32 d_rtbtimer; /* similar to above; for RT disk blks */ + __u16 d_rtbwarns; /* # warnings issued wrt RT disk blks */ + __s16 d_padding3; /* padding3 - for future use */ + char d_padding4[8]; /* yet more padding */ +} fs_disk_quota_t; + +#endif /* LINUX */