| OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \
                                         | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \
                                         | OCFS2_FEATURE_INCOMPAT_XATTR)
-#define OCFS2_FEATURE_RO_COMPAT_SUPP   OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
+#define OCFS2_FEATURE_RO_COMPAT_SUPP   (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN)
 
 /*
  * Heartbeat-only devices are missing journals and other files.  The
  */
 #define OCFS2_FEATURE_RO_COMPAT_UNWRITTEN      0x0001
 
+/*
+ * Maintain quota information for this filesystem
+ */
+#define OCFS2_FEATURE_RO_COMPAT_USRQUOTA       0x0002
+#define OCFS2_FEATURE_RO_COMPAT_GRPQUOTA       0x0004
+
 /* The byte offset of the first backup block will be 1G.
  * The following will be 4G, 16G, 64G, 256G and 1T.
  */
 #define OCFS2_HEARTBEAT_FL     (0x00000200)    /* Heartbeat area */
 #define OCFS2_CHAIN_FL         (0x00000400)    /* Chain allocator */
 #define OCFS2_DEALLOC_FL       (0x00000800)    /* Truncate log */
+#define OCFS2_QUOTA_FL         (0x00001000)    /* Quota file */
 
 /*
  * Flags on ocfs2_dinode.i_dyn_features
 #define OCFS2_FIRST_ONLINE_SYSTEM_INODE SLOT_MAP_SYSTEM_INODE
        HEARTBEAT_SYSTEM_INODE,
        GLOBAL_BITMAP_SYSTEM_INODE,
-#define OCFS2_LAST_GLOBAL_SYSTEM_INODE GLOBAL_BITMAP_SYSTEM_INODE
+       USER_QUOTA_SYSTEM_INODE,
+       GROUP_QUOTA_SYSTEM_INODE,
+#define OCFS2_LAST_GLOBAL_SYSTEM_INODE GROUP_QUOTA_SYSTEM_INODE
        ORPHAN_DIR_SYSTEM_INODE,
        EXTENT_ALLOC_SYSTEM_INODE,
        INODE_ALLOC_SYSTEM_INODE,
        JOURNAL_SYSTEM_INODE,
        LOCAL_ALLOC_SYSTEM_INODE,
        TRUNCATE_LOG_SYSTEM_INODE,
+       LOCAL_USER_QUOTA_SYSTEM_INODE,
+       LOCAL_GROUP_QUOTA_SYSTEM_INODE,
        NUM_SYSTEM_INODES
 };
 
        [SLOT_MAP_SYSTEM_INODE]                 = { "slot_map", 0, S_IFREG | 0644 },
        [HEARTBEAT_SYSTEM_INODE]                = { "heartbeat", OCFS2_HEARTBEAT_FL, S_IFREG | 0644 },
        [GLOBAL_BITMAP_SYSTEM_INODE]            = { "global_bitmap", 0, S_IFREG | 0644 },
+       [USER_QUOTA_SYSTEM_INODE]               = { "aquota.user", OCFS2_QUOTA_FL, S_IFREG | 0644 },
+       [GROUP_QUOTA_SYSTEM_INODE]              = { "aquota.group", OCFS2_QUOTA_FL, S_IFREG | 0644 },
 
        /* Slot-specific system inodes (one copy per slot) */
        [ORPHAN_DIR_SYSTEM_INODE]               = { "orphan_dir:%04d", 0, S_IFDIR | 0755 },
        [INODE_ALLOC_SYSTEM_INODE]              = { "inode_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_CHAIN_FL, S_IFREG | 0644 },
        [JOURNAL_SYSTEM_INODE]                  = { "journal:%04d", OCFS2_JOURNAL_FL, S_IFREG | 0644 },
        [LOCAL_ALLOC_SYSTEM_INODE]              = { "local_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_LOCAL_ALLOC_FL, S_IFREG | 0644 },
-       [TRUNCATE_LOG_SYSTEM_INODE]             = { "truncate_log:%04d", OCFS2_DEALLOC_FL, S_IFREG | 0644 }
+       [TRUNCATE_LOG_SYSTEM_INODE]             = { "truncate_log:%04d", OCFS2_DEALLOC_FL, S_IFREG | 0644 },
+       [LOCAL_USER_QUOTA_SYSTEM_INODE]         = { "aquota.user:%04d", OCFS2_QUOTA_FL, S_IFREG | 0644 },
+       [LOCAL_GROUP_QUOTA_SYSTEM_INODE]        = { "aquota.group:%04d", OCFS2_QUOTA_FL, S_IFREG | 0644 },
 };
 
 /* Parameter passed from mount.ocfs2 to module */
 
        return 0;
 }
 
+static int ocfs2_need_system_inode(struct ocfs2_super *osb, int ino)
+{
+       if (!OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, OCFS2_FEATURE_RO_COMPAT_USRQUOTA)
+           && (ino == USER_QUOTA_SYSTEM_INODE
+               || ino == LOCAL_USER_QUOTA_SYSTEM_INODE))
+               return 0;
+       if (!OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
+           && (ino == GROUP_QUOTA_SYSTEM_INODE
+               || ino == LOCAL_GROUP_QUOTA_SYSTEM_INODE))
+               return 0;
+       return 1;
+}
+
 static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb)
 {
        struct inode *new = NULL;
 
        for (i = OCFS2_FIRST_ONLINE_SYSTEM_INODE;
             i <= OCFS2_LAST_GLOBAL_SYSTEM_INODE; i++) {
+               if (!ocfs2_need_system_inode(osb, i))
+                       continue;
                new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
                if (!new) {
                        ocfs2_release_system_inodes(osb);
        for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1;
             i < NUM_SYSTEM_INODES;
             i++) {
+               if (!ocfs2_need_system_inode(osb, i))
+                       continue;
                new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
                if (!new) {
                        ocfs2_release_system_inodes(osb);