Whamcloud - gitweb
LU-4017 ldiskfs: add project quota support
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs-project-quotas-rhel7.patch
diff --git a/lustre/kernel_patches/patches/vfs-project-quotas-rhel7.patch b/lustre/kernel_patches/patches/vfs-project-quotas-rhel7.patch
new file mode 100644 (file)
index 0000000..493fc92
--- /dev/null
@@ -0,0 +1,199 @@
+From 611406e29293c37b4a8771073030ccdaf0bd4fa5 Mon Sep 17 00:00:00 2001
+From: Li Xi <pkuelelixi@gmail.com>
+Subject: [PATCH] vfs: Add general support to enforce project quota limits
+
+This patch adds support for a new quota type PRJQUOTA for project quota
+enforcement. Also a new method get_projid() is added into dquot_operations
+structure.
+
+Signed-off-by: Li Xi <lixi@ddn.com>
+Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jan Kara <jack@suse.cz>
+----
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index d7d5a0a..6b80f11 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -1152,8 +1152,8 @@ static int need_print_warning(struct dquot_warn *warn)
+                       return uid_eq(current_fsuid(), warn->w_dq_id.uid);
+               case GRPQUOTA:
+                       return in_group_p(warn->w_dq_id.gid);
+-              case PRJQUOTA:  /* Never taken... Just make gcc happy */
+-                      return 0;
++              case PRJQUOTA:
++                      return 1;
+       }
+       return 0;
+ }
+@@ -1392,6 +1392,9 @@ static void __dquot_initialize(struct inode *inode, int type)
+       /* First get references to structures we might need. */
+       for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+               struct kqid qid;
++              kprojid_t projid;
++              int rc;
++
+               got[cnt] = NULL;
+               if (type != -1 && cnt != type)
+                       continue;
+@@ -1402,6 +1405,10 @@ static void __dquot_initialize(struct inode *inode, int type)
+                */
+               if (inode->i_dquot[cnt])
+                       continue;
++
++              if (!sb_has_quota_active(sb, cnt))
++                      continue;
++
+               init_needed = 1;
+               switch (cnt) {
+@@ -1411,6 +1418,12 @@ static void __dquot_initialize(struct inode *inode, int type)
+               case GRPQUOTA:
+                       qid = make_kqid_gid(inode->i_gid);
+                       break;
++              case PRJQUOTA:
++                      rc = inode->i_sb->dq_op->get_projid(inode, &projid);
++                      if (rc)
++                              continue;
++                      qid = make_kqid_projid(projid);
++                      break;
+               }
+               got[cnt] = dqget(sb, qid);
+       }
+@@ -2154,7 +2167,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
+               error = -EROFS;
+               goto out_fmt;
+       }
+-      if (!sb->s_op->quota_write || !sb->s_op->quota_read) {
++      if (!sb->s_op->quota_write || !sb->s_op->quota_read ||
++          (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) {
+               error = -EINVAL;
+               goto out_fmt;
+       }
+diff --git a/fs/quota/quotaio_v2.h b/fs/quota/quotaio_v2.h
+index f1966b4..4e95430 100644
+--- a/fs/quota/quotaio_v2.h
++++ b/fs/quota/quotaio_v2.h
+@@ -13,12 +13,14 @@
+  */
+ #define V2_INITQMAGICS {\
+       0xd9c01f11,     /* USRQUOTA */\
+-      0xd9c01927      /* GRPQUOTA */\
++      0xd9c01927,     /* GRPQUOTA */\
++      0xd9c03f14,     /* PRJQUOTA */\
+ }
+ #define V2_INITQVERSIONS {\
+       1,              /* USRQUOTA */\
+-      1               /* GRPQUOTA */\
++      1,              /* GRPQUOTA */\
++      1,              /* PRJQUOTA */\
+ }
+ /* First generic header */
+diff --git a/include/linux/quota.h b/include/linux/quota.h
+index 99932a5..0d20c39 100644
+--- a/include/linux/quota.h
++++ b/include/linux/quota.h
+@@ -52,6 +52,7 @@
+ #undef USRQUOTA
+ #undef GRPQUOTA
++#undef PRJQUOTA
+ enum quota_type {
+       USRQUOTA = 0,           /* element used for user quotas */
+       GRPQUOTA = 1,           /* element used for group quotas */
+@@ -314,6 +315,7 @@ struct dquot_operations {
+       /* get reserved quota for delayed alloc, value returned is managed by
+        * quota code only */
+       qsize_t *(*get_reserved_space) (struct inode *);
++      int (*get_projid) (struct inode *, kprojid_t *);/* Get project ID */
+ };
+ struct path;
+diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
+index 83d19df..418e9dd 100644
+--- a/include/uapi/linux/fs.h
++++ b/include/uapi/linux/fs.h
+@@ -58,6 +58,36 @@ struct inodes_stat_t {
+       int dummy[5];           /* padding for sysctl ABI compatibility */
+ };
++/*
++ * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
++ */
++struct fsxattr {
++      __u32           fsx_xflags;     /* xflags field value (get/set) */
++      __u32           fsx_extsize;    /* extsize field value (get/set)*/
++      __u32           fsx_nextents;   /* nextents field value (get)   */
++      __u32           fsx_projid;     /* project identifier (get/set) */
++      unsigned char   fsx_pad[12];
++};
++#define HAVE_FSXATTR          1
++
++/*
++ * Flags for the fsx_xflags field
++ */
++#define FS_XFLAG_REALTIME     0x00000001      /* data in realtime volume */
++#define FS_XFLAG_PREALLOC     0x00000002      /* preallocated file extents */
++#define FS_XFLAG_IMMUTABLE    0x00000008      /* file cannot be modified */
++#define FS_XFLAG_APPEND               0x00000010      /* all writes append */
++#define FS_XFLAG_SYNC         0x00000020      /* all writes synchronous */
++#define FS_XFLAG_NOATIME      0x00000040      /* do not update access time */
++#define FS_XFLAG_NODUMP               0x00000080      /* do not include in backups */
++#define FS_XFLAG_RTINHERIT    0x00000100      /* create with rt bit set */
++#define FS_XFLAG_PROJINHERIT  0x00000200      /* create with parents projid */
++#define FS_XFLAG_NOSYMLINKS   0x00000400      /* disallow symlink creation */
++#define FS_XFLAG_EXTSIZE      0x00000800      /* extent size allocator hint */
++#define FS_XFLAG_EXTSZINHERIT 0x00001000      /* inherit inode extent size */
++#define FS_XFLAG_NODEFRAG     0x00002000      /* do not defragment */
++#define FS_XFLAG_FILESTREAM   0x00004000      /* use filestream allocator */
++#define FS_XFLAG_HASATTR      0x80000000      /* no DIFLAG for this */
+ #define NR_FILE  8192 /* this can well be larger on a larger system */
+@@ -163,6 +193,8 @@ struct inodes_stat_t {
+ #define       FS_IOC_GETVERSION               _IOR('v', 1, long)
+ #define       FS_IOC_SETVERSION               _IOW('v', 2, long)
+ #define FS_IOC_FIEMAP                 _IOWR('f', 11, struct fiemap)
++#define FS_IOC_FSGETXATTR             _IOR('X', 31, struct fsxattr)
++#define FS_IOC_FSSETXATTR             _IOW('X', 32, struct fsxattr)
+ #define FS_IOC32_GETFLAGS             _IOR('f', 1, int)
+ #define FS_IOC32_SETFLAGS             _IOW('f', 2, int)
+ #define FS_IOC32_GETVERSION           _IOR('v', 1, int)
+@@ -195,6 +227,7 @@ struct inodes_stat_t {
+ #define FS_EXTENT_FL                  0x00080000 /* Extents */
+ #define FS_DIRECTIO_FL                        0x00100000 /* Use direct i/o */
+ #define FS_NOCOW_FL                   0x00800000 /* Do not cow file */
++#define FS_PROJINHERIT_FL             0x20000000 /* Create with parents projid */
+ #define FS_RESERVED_FL                        0x80000000 /* reserved for ext2 lib */
+ #define FS_FL_USER_VISIBLE            0x0003DFFF /* User visible flags */
+diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h
+index 3b6cfbe..b2d9486 100644
+--- a/include/uapi/linux/quota.h
++++ b/include/uapi/linux/quota.h
+@@ -36,11 +36,12 @@
+ #include <linux/errno.h>
+ #include <linux/types.h>
+-#define __DQUOT_VERSION__     "dquot_6.5.2"
++#define __DQUOT_VERSION__     "dquot_6.6.0"
+-#define MAXQUOTAS 2
++#define MAXQUOTAS 3
+ #define USRQUOTA  0           /* element used for user quotas */
+ #define GRPQUOTA  1           /* element used for group quotas */
++#define PRJQUOTA  2           /* element used for project quotas */
+ /*
+  * Definitions for the default names of the quotas files.
+@@ -48,6 +49,7 @@
+ #define INITQFNAMES { \
+       "user",    /* USRQUOTA */ \
+       "group",   /* GRPQUOTA */ \
++      "project", /* PRJQUOTA */ \
+       "undefined", \
+ };