2 Unix SMB/CIFS implementation.
3 System QUOTA function wrappers
4 Copyright (C) Stefan (metze) Metzmacher 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #ifdef HAVE_SYS_QUOTAS
28 #if defined(HAVE_QUOTACTL_4A)
29 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
30 /* this is used by: linux,HPUX,IRIX */
32 /****************************************************************************
33 Abstract out the old and new Linux quota get calls.
34 ****************************************************************************/
35 static int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
40 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
42 if (!path
||!bdev
||!dp
)
43 smb_panic("sys_get_vfs_quota: called with NULL pointer");
50 case SMB_USER_QUOTA_TYPE
:
51 /* we use id.uid == 0 for default quotas */
57 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))) {
61 if ((D
.dqb_curblocks
==0)&&
62 (D
.dqb_bsoftlimit
==0)&&
63 (D
.dqb_bhardlimit
==0)) {
64 /* the upper layer functions don't want empty quota records...*/
69 #ifdef HAVE_GROUP_QUOTA
70 case SMB_GROUP_QUOTA_TYPE
:
71 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
))) {
75 if ((D
.dqb_curblocks
==0)&&
76 (D
.dqb_bsoftlimit
==0)&&
77 (D
.dqb_bhardlimit
==0)) {
78 /* the upper layer functions don't want empty quota records...*/
83 #endif /* HAVE_GROUP_QUOTA */
84 case SMB_USER_FS_QUOTA_TYPE
:
87 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
))==0) {
88 qflags
|= QUOTAS_DENY_DISK
;
91 /* get the default quotas stored in the root's (uid =0) record */
92 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, 0, (CADDR_T
)&D
))) {
104 dp
->softlimit
= (SMB_BIG_UINT
)D
.dqb_bsoftlimit
;
105 dp
->hardlimit
= (SMB_BIG_UINT
)D
.dqb_bhardlimit
;
106 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.dqb_ihardlimit
;
107 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.dqb_isoftlimit
;
108 dp
->curinodes
= (SMB_BIG_UINT
)D
.dqb_curinodes
;
109 dp
->curblocks
= (SMB_BIG_UINT
)D
.dqb_curblocks
;
117 /****************************************************************************
118 Abstract out the old and new Linux quota set calls.
119 ****************************************************************************/
121 static int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
126 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
128 if (!path
||!bdev
||!dp
)
129 smb_panic("sys_set_vfs_quota: called with NULL pointer");
133 if (bsize
== dp
->bsize
) {
134 D
.dqb_bsoftlimit
= dp
->softlimit
;
135 D
.dqb_bhardlimit
= dp
->hardlimit
;
136 D
.dqb_ihardlimit
= dp
->ihardlimit
;
137 D
.dqb_isoftlimit
= dp
->isoftlimit
;
139 D
.dqb_bsoftlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
140 D
.dqb_bhardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
141 D
.dqb_ihardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
142 D
.dqb_isoftlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
148 case SMB_USER_QUOTA_TYPE
:
149 /* we use id.uid == 0 for default quotas */
151 ret
= quotactl(QCMD(Q_SETQLIM
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
154 #ifdef HAVE_GROUP_QUOTA
155 case SMB_GROUP_QUOTA_TYPE
:
156 ret
= quotactl(QCMD(Q_SETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
);
158 #endif /* HAVE_GROUP_QUOTA */
159 case SMB_USER_FS_QUOTA_TYPE
:
160 /* this stuff didn't work as it should:
161 * switching on/off quota via quotactl()
163 * So we only set the default limits
166 * On HPUX we didn't have the mount path,
167 * we need to fix sys_path_to_bdev()
173 ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), bdev
, uid
, (CADDR_T
)&D
);
175 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
177 char *quota_file
= NULL
;
179 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,USERQUOTAFILE_EXTENSION
);
180 if (quota_file
== NULL
) {
181 DEBUG(0,("asprintf() failed!\n"));
186 ret
= quotactl(QCMD(Q_QUOTAON
,USRQUOTA
), bdev
, -1,(CADDR_T
)quota_file
);
193 ret
= quotactl(QCMD(Q_QUOTAOFF
,USRQUOTA
), bdev
, -1, (CADDR_T
)0);
199 DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
200 ret
,errno
,strerror(errno
),uid
,bdev
));
203 /* we use uid == 0 for default quotas */
204 ret
= quotactl(QCMD(Q_SETQLIM
,USRQUOTA
), bdev
, 0, (CADDR_T
)&D
);
216 /*#endif HAVE_QUOTACTL_4A */
217 #elif defined(HAVE_QUOTACTL_4B)
219 #error HAVE_QUOTACTL_4B not implemeted
221 /*#endif HAVE_QUOTACTL_4B */
222 #elif defined(HAVE_QUOTACTL_3)
224 #error HAVE_QUOTACTL_3 not implemented
226 /* #endif HAVE_QUOTACTL_3 */
227 #else /* NO_QUOTACTL_USED */
229 static int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
233 if (!path
||!bdev
||!dp
)
234 smb_panic("sys_get_vfs_quota: called with NULL pointer");
241 static int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
245 if (!path
||!bdev
||!dp
)
246 smb_panic("sys_set_vfs_quota: called with NULL pointer");
253 #endif /* NO_QUOTACTL_USED */
256 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
264 /* find the block device file */
266 if (!path
||!mntpath
||!bdev
||!fs
)
267 smb_panic("sys_path_to_bdev: called with NULL pointer");
273 if ( sys_stat(path
, &S
) == -1 )
278 fp
= setmntent(MOUNTED
,"r");
280 while ((mnt
= getmntent(fp
))) {
281 if ( sys_stat(mnt
->mnt_dir
,&S
) == -1 )
284 if (S
.st_dev
== devno
) {
285 (*mntpath
) = strdup(mnt
->mnt_dir
);
286 (*bdev
) = strdup(mnt
->mnt_fsname
);
287 (*fs
) = strdup(mnt
->mnt_type
);
288 if ((*mntpath
)&&(*bdev
)&&(*fs
)) {
305 /* #endif HAVE_MNTENT */
306 #elif defined(HAVE_DEVNM)
308 /* we have this on HPUX, ... */
309 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
315 if (!path
||!mntpath
||!bdev
||!fs
)
316 smb_panic("sys_path_to_bdev: called with NULL pointer");
322 /* find the block device file */
324 if ((ret
=sys_stat(path
, &S
))!=0) {
328 if ((ret
=devnm(S_IFBLK
, S
.st_dev
, dev_disk
, 256, 1))!=0) {
332 /* we should get the mntpath right...
333 * but I don't know how
336 (*mntpath
) = strdup(path
);
337 (*bdev
) = strdup(dev_disk
);
338 if ((*mntpath
)&&(*bdev
)) {
350 /* #endif HAVE_DEVNM */
352 /* we should fake this up...*/
353 static int sys_path_to_bdev(const char *path
, char **mntpath
, char **bdev
, char **fs
)
357 if (!path
||!mntpath
||!bdev
||!fs
)
358 smb_panic("sys_path_to_bdev: called with NULL pointer");
364 (*mntpath
) = strdup(path
);
377 /*********************************************************
378 if we have XFS QUOTAS we should use them
379 *********************************************************/
380 #ifdef HAVE_XFS_QUOTA
381 /****************************************************************************
382 Abstract out the XFS Quota Manager quota get call.
383 ****************************************************************************/
384 static int sys_get_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
388 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
389 struct fs_disk_quota D
;
390 struct fs_quota_stat F
;
395 smb_panic("sys_get_xfs_quota: called with NULL pointer");
401 case SMB_USER_QUOTA_TYPE
:
402 /* we use id.uid == 0 for default quotas */
407 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
)))
410 #ifdef HAVE_GROUP_QUOTA
411 case SMB_GROUP_QUOTA_TYPE
:
412 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
)))
415 #endif /* HAVE_GROUP_QUOTA */
416 case SMB_USER_FS_QUOTA_TYPE
:
417 /* TODO: get quota status from quotactl() ... */
418 if ((ret
= quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (CADDR_T
)&F
)))
421 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
422 qflags
|= QUOTAS_DENY_DISK
;
424 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
425 qflags
|= QUOTAS_ENABLED
;
428 /* we use uid == 0 for default quotas */
429 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, 0, (CADDR_T
)&D
)))
439 dp
->softlimit
= (SMB_BIG_UINT
)D
.d_blk_softlimit
;
440 dp
->hardlimit
= (SMB_BIG_UINT
)D
.d_blk_hardlimit
;
441 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.d_ino_hardlimit
;
442 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.d_ino_softlimit
;
443 dp
->curinodes
= (SMB_BIG_UINT
)D
.d_icount
;
444 dp
->curblocks
= (SMB_BIG_UINT
)D
.d_bcount
;
450 /****************************************************************************
451 Abstract out the XFS Quota Manager quota set call.
452 ****************************************************************************/
453 static int sys_set_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
457 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
458 struct fs_disk_quota D
;
459 struct fs_quota_stat F
;
466 smb_panic("sys_set_xfs_quota: called with NULL pointer");
468 if (bsize
== dp
->bsize
) {
469 D
.d_blk_softlimit
= dp
->softlimit
;
470 D
.d_blk_hardlimit
= dp
->hardlimit
;
471 D
.d_ino_hardlimit
= dp
->ihardlimit
;
472 D
.d_ino_softlimit
= dp
->isoftlimit
;
474 D
.d_blk_softlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
475 D
.d_blk_hardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
476 D
.d_ino_hardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
477 D
.d_ino_softlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
483 case SMB_USER_QUOTA_TYPE
:
484 /* we use uid == 0 for default quotas */
486 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
487 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, id
.uid
, (CADDR_T
)&D
);
490 #ifdef HAVE_GROUP_QUOTA
491 case SMB_GROUP_QUOTA_TYPE
:
492 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
493 ret
= quotactl(QCMD(Q_XSETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (CADDR_T
)&D
);
495 #endif /* HAVE_GROUP_QUOTA */
496 case SMB_USER_FS_QUOTA_TYPE
:
498 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (CADDR_T
)&F
);
500 if (qflags
& QUOTAS_DENY_DISK
) {
501 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
502 q_on
|= XFS_QUOTA_UDQ_ENFD
;
503 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
504 q_on
|= XFS_QUOTA_UDQ_ACCT
;
507 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
510 } else if (qflags
& QUOTAS_ENABLED
) {
511 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
512 q_off
|= XFS_QUOTA_UDQ_ENFD
;
515 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
518 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
519 q_on
|= XFS_QUOTA_UDQ_ACCT
;
522 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_on
);
526 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
527 * only swittching off XFS_QUOTA_UDQ_ACCT work
529 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
530 q_off
|= XFS_QUOTA_UDQ_ENFD
;
531 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
532 q_off
|= XFS_QUOTA_UDQ_ACCT
;
535 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (CADDR_T
)&q_off
);
540 /* we use uid == 0 for default quotas */
541 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
542 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, 0, (CADDR_T
)&D
);
551 #endif /* HAVE_XFS_QUOTA */
567 /*********************************************************************
568 Now the list of all filesystem specific quota systems we have found
569 **********************************************************************/
572 int (*get_quota
)(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
);
573 int (*set_quota
)(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
);
574 } sys_quota_backends
[] = {
575 #ifdef HAVE_XFS_QUOTA
576 {"xfs", sys_get_xfs_quota
, sys_set_xfs_quota
},
577 #endif /* HAVE_XFS_QUOTA */
581 static int command_get_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
583 const char *get_quota_command
;
585 get_quota_command
= lp_get_quota_command();
586 if (get_quota_command
&& *get_quota_command
) {
594 case SMB_USER_QUOTA_TYPE
:
595 case SMB_USER_FS_QUOTA_TYPE
:
598 case SMB_GROUP_QUOTA_TYPE
:
599 case SMB_GROUP_FS_QUOTA_TYPE
:
603 DEBUG(0,("invalid quota type.\n"));
607 slprintf(syscmd
, sizeof(syscmd
)-1,
609 get_quota_command
, path
, qtype
, _id
);
611 DEBUG (3, ("get_quota: Running command %s\n", syscmd
));
613 lines
= file_lines_pload(syscmd
, NULL
);
615 char *line
= lines
[0];
617 DEBUG (3, ("Read output from get_quota, \"r%s\"\n", line
));
619 /* we need to deal with long long unsigned here, if supported */
621 dp
->qflags
= (enum SMB_QUOTA_TYPE
)strtoul(line
, &p2
, 10);
623 while (p
&& *p
&& isspace(*p
))
626 dp
->curblocks
= STR_TO_SMB_BIG_UINT(p
, &p
);
629 while (p
&& *p
&& isspace(*p
))
632 dp
->softlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
635 while (p
&& *p
&& isspace(*p
))
638 dp
->hardlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
641 while (p
&& *p
&& isspace(*p
))
644 dp
->curinodes
= STR_TO_SMB_BIG_UINT(p
, &p
);
647 while (p
&& *p
&& isspace(*p
))
650 dp
->isoftlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
653 while (p
&& *p
&& isspace(*p
))
656 dp
->ihardlimit
= STR_TO_SMB_BIG_UINT(p
, &p
);
659 while (p
&& *p
&& isspace(*p
))
662 dp
->bsize
= STR_TO_SMB_BIG_UINT(p
, NULL
);
665 file_lines_free(lines
);
666 DEBUG (3, ("Parsed output of get_quota, ...\n"));
668 #ifdef LARGE_SMB_OFF_T
670 "qflags:%u curblocks:%llu softlimit:%llu hardlimit:%llu\n"
671 "curinodes:%llu isoftlimit:%llu ihardlimit:%llu bsize:%llu\n",
672 dp
->qflags
,(long long unsigned)dp
->curblocks
,
673 (long long unsigned)dp
->softlimit
,(long long unsigned)dp
->hardlimit
,
674 (long long unsigned)dp
->curinodes
,
675 (long long unsigned)dp
->isoftlimit
,(long long unsigned)dp
->ihardlimit
,
676 (long long unsigned)dp
->bsize
));
677 #else /* LARGE_SMB_OFF_T */
679 "qflags:%u curblocks:%lu softlimit:%lu hardlimit:%lu\n"
680 "curinodes:%lu isoftlimit:%lu ihardlimit:%lu bsize:%lu\n",
681 dp
->qflags
,(long unsigned)dp
->curblocks
,
682 (long unsigned)dp
->softlimit
,(long unsigned)dp
->hardlimit
,
683 (long unsigned)dp
->curinodes
,
684 (long unsigned)dp
->isoftlimit
,(long unsigned)dp
->ihardlimit
,
685 (long unsigned)dp
->bsize
));
686 #endif /* LARGE_SMB_OFF_T */
690 DEBUG (0, ("get_quota_command failed!\n"));
698 DEBUG(0,("The output of get_quota_command is invalid!\n"));
702 static int command_set_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
704 const char *set_quota_command
;
706 set_quota_command
= lp_set_quota_command();
707 if (set_quota_command
&& *set_quota_command
) {
713 case SMB_USER_QUOTA_TYPE
:
714 case SMB_USER_FS_QUOTA_TYPE
:
717 case SMB_GROUP_QUOTA_TYPE
:
718 case SMB_GROUP_FS_QUOTA_TYPE
:
725 #ifdef LARGE_SMB_OFF_T
726 slprintf(syscmd
, sizeof(syscmd
)-1,
730 set_quota_command
, path
, qtype
, _id
, dp
->qflags
,
731 (long long unsigned)dp
->softlimit
,(long long unsigned)dp
->hardlimit
,
732 (long long unsigned)dp
->isoftlimit
,(long long unsigned)dp
->ihardlimit
,
733 (long long unsigned)dp
->bsize
);
734 #else /* LARGE_SMB_OFF_T */
735 slprintf(syscmd
, sizeof(syscmd
)-1,
739 set_quota_command
, path
, qtype
, _id
, dp
->qflags
,
740 (long unsigned)dp
->softlimit
,(long unsigned)dp
->hardlimit
,
741 (long unsigned)dp
->isoftlimit
,(long unsigned)dp
->ihardlimit
,
742 (long unsigned)dp
->bsize
);
743 #endif /* LARGE_SMB_OFF_T */
747 DEBUG (3, ("get_quota: Running command %s\n", syscmd
));
749 lines
= file_lines_pload(syscmd
, NULL
);
751 char *line
= lines
[0];
753 DEBUG (3, ("Read output from set_quota, \"%s\"\n", line
));
755 file_lines_free(lines
);
759 DEBUG (0, ("set_quota_command failed!\n"));
767 int sys_get_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
772 char *mntpath
= NULL
;
777 smb_panic("sys_get_quota: called with NULL pointer");
779 if (command_get_quota(path
, qtype
, id
, dp
)==0) {
781 } else if (errno
!= ENOSYS
) {
785 if ((ret
=sys_path_to_bdev(path
,&mntpath
,&bdev
,&fs
))!=0) {
789 for (i
=0;(fs
&& sys_quota_backends
[i
].name
&& sys_quota_backends
[i
].get_quota
);i
++) {
790 if (strcmp(fs
,sys_quota_backends
[i
].name
)==0) {
791 ret
= sys_quota_backends
[i
].get_quota(mntpath
, bdev
, qtype
, id
, dp
);
798 /* use the default vfs quota functions */
799 ret
= sys_get_vfs_quota(mntpath
, bdev
, qtype
, id
, dp
);
806 if ((ret
!=0)&& (errno
== EDQUOT
)) {
813 int sys_set_quota(const char *path
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
818 char *mntpath
= NULL
;
822 /* find the block device file */
825 smb_panic("get_smb_quota: called with NULL pointer");
827 if (command_set_quota(path
, qtype
, id
, dp
)==0) {
829 } else if (errno
!= ENOSYS
) {
833 if ((ret
=sys_path_to_bdev(path
,&mntpath
,&bdev
,&fs
))!=0) {
837 for (i
=0;(fs
&& sys_quota_backends
[i
].name
&& sys_quota_backends
[i
].set_quota
);i
++) {
838 if (strcmp(fs
,sys_quota_backends
[i
].name
)==0) {
839 ret
= sys_quota_backends
[i
].set_quota(mntpath
, bdev
, qtype
, id
, dp
);
846 /* use the default vfs quota functions */
847 ret
=sys_set_vfs_quota(mntpath
, bdev
, qtype
, id
, dp
);
854 if ((ret
!=0)&& (errno
== EDQUOT
)) {
861 #else /* HAVE_SYS_QUOTAS */
862 void dummy_sysquotas_c(void)
866 #endif /* HAVE_SYS_QUOTAS */
868 #else /* ! AUTOCONF_TEST */
869 /* this is the autoconf driver to test witch quota system we should use */
871 #if defined(HAVE_QUOTACTL_4A)
872 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
874 #ifdef HAVE_SYS_TYPES_H
875 #include <sys/types.h>
878 #ifdef HAVE_ASM_TYPES_H
879 #include <asm/types.h>
882 #if defined(HAVE_LINUX_QUOTA_H)
883 # include <linux/quota.h>
884 # if defined(HAVE_STRUCT_IF_DQBLK)
885 # define SYS_DQBLK if_dqblk
886 # elif defined(HAVE_STRUCT_MEM_DQBLK)
887 # define SYS_DQBLK mem_dqblk
889 #elif defined(HAVE_SYS_QUOTA_H)
890 # include <sys/quota.h>
894 #define SYS_DQBLK dqblk
897 int autoconf_quota(void)
902 ret
= quotactl(Q_GETQUOTA
,"/dev/hda1",0,(void *)&D
);
907 #elif defined(HAVE_QUOTACTL_4B)
908 /* int quotactl(const char *path, int cmd, int id, char *addr); */
910 #ifdef HAVE_SYS_QUOTA_H
911 #include <sys/quota.h>
913 #include <sys/types.h>
914 #include <ufs/ufs/quota.h>
915 #include <machine/param.h>
918 int autoconf_quota(void)
923 ret
= quotactl("/",Q_GETQUOTA
,0,(char *) &D
);
928 #elif defined(HAVE_QUOTACTL_3)
929 /* int quotactl (char *spec, int request, char *arg); */
931 #ifdef HAVE_SYS_TYPES_H
932 #include <sys/types.h>
934 #ifdef HAVE_SYS_QUOTA_H
935 #include <sys/quota.h>
938 int autoconf_quota(void)
941 struct q_request request
;
943 ret
= quotactl("/", Q_GETQUOTA
, &request
);
948 #elif defined(HAVE_QUOTACTL_2)
950 #error HAVE_QUOTACTL_2 not implemented
954 #error Unknow QUOTACTL prototype
963 #endif /* AUTOCONF_TEST */