smbd: dfree - ignore quota if not enforced
authorUri Simchoni <uri@samba.org>
Wed, 27 Apr 2016 20:22:25 +0000 (23:22 +0300)
committerJeremy Allison <jra@samba.org>
Fri, 27 May 2016 22:09:05 +0000 (00:09 +0200)
When calculating free disk space, do not take user quota
into account if quota is globally not enforced on the file
system.

This is meant to fix a specific problem with XFS. One might
say "why don't you fix the XFS-specific code instead?". The
reason for that is that getting and setting quota must not
be affected by whether quota is actually enforced. NTFS has
the same notion of separating quota accounting (and being
able to configure / retrieve configured quota), from quota
enforcement.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11937

Signed-off-by: Uri Simchoni <uri@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat May 28 00:09:05 CEST 2016 on sn-devel-144

selftest/knownfail
source3/smbd/quotas.c

index fd86a9c998f4208684f3c2f5c32e2d5798b0672d..2f2d6bffbaedce844550289a50ac5ed06e1ea137 100644 (file)
 # ad_dc requires signing
 #
 ^samba4.smb.signing.*disabled.*signing=off.*\(ad_dc\)
-#new disk-free tests fail the code
-^samba3.blackbox.dfree_quota \(fileserver\).Test dfree share root quota not enforced\(fileserver\)
index 58d8460641c2bc1a0fa54ca051608dfa640aadff..20f74b4acebc299e2d51288627375edfe194e69f 100644 (file)
@@ -489,9 +489,24 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
        SMB_DISK_QUOTA D;
        unid_t id;
 
-       id.uid = geteuid();
+       /*
+        * First of all, check whether user quota is
+        * enforced. If the call fails, assume it is
+        * not enforced.
+        */
+       ZERO_STRUCT(D);
+       id.uid = -1;
+       r = SMB_VFS_GET_QUOTA(conn, path, SMB_USER_FS_QUOTA_TYPE, id, &D);
+       if (r == -1 && errno != ENOSYS) {
+               goto try_group_quota;
+       }
+       if (r == 0 && (D.qflags & QUOTAS_DENY_DISK) == 0) {
+               goto try_group_quota;
+       }
 
        ZERO_STRUCT(D);
+       id.uid = geteuid();
+
        r = SMB_VFS_GET_QUOTA(conn, path, SMB_USER_QUOTA_TYPE, id, &D);
 
        /* Use softlimit to determine disk space, except when it has been exceeded */
@@ -528,6 +543,21 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
        return True;
        
 try_group_quota:
+       /*
+        * First of all, check whether group quota is
+        * enforced. If the call fails, assume it is
+        * not enforced.
+        */
+       ZERO_STRUCT(D);
+       id.gid = -1;
+       r = SMB_VFS_GET_QUOTA(conn, path, SMB_GROUP_FS_QUOTA_TYPE, id, &D);
+       if (r == -1 && errno != ENOSYS) {
+               return false;
+       }
+       if (r == 0 && (D.qflags & QUOTAS_DENY_DISK) == 0) {
+               return false;
+       }
+
        id.gid = getegid();
 
        ZERO_STRUCT(D);