aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/ocfs2/inode.c2
-rw-r--r--fs/ocfs2/ocfs2_fs.h21
-rw-r--r--fs/ocfs2/super.c17
4 files changed, 39 insertions, 3 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index c1ce3d8831d8..f9b6e2979aaa 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -189,6 +189,8 @@ config OCFS2_FS
189 select CONFIGFS_FS 189 select CONFIGFS_FS
190 select JBD2 190 select JBD2
191 select CRC32 191 select CRC32
192 select QUOTA
193 select QUOTA_TREE
192 help 194 help
193 OCFS2 is a general purpose extent based shared disk cluster file 195 OCFS2 is a general purpose extent based shared disk cluster file
194 system with many similarities to ext3. It supports 64 bit inode 196 system with many similarities to ext3. It supports 64 bit inode
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index ec3497bafda6..ec25d9984192 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -283,6 +283,8 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
283 mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino); 283 mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino);
284 } else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) { 284 } else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) {
285 OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; 285 OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
286 } else if (fe->i_flags & cpu_to_le32(OCFS2_QUOTA_FL)) {
287 inode->i_flags |= S_NOQUOTA;
286 } else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) { 288 } else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) {
287 mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino); 289 mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino);
288 /* we can't actually hit this as read_inode can't 290 /* we can't actually hit this as read_inode can't
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 5e0c0d0aef7d..06e3bd632ff3 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -94,7 +94,7 @@
94 | OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \ 94 | OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \
95 | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \ 95 | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \
96 | OCFS2_FEATURE_INCOMPAT_XATTR) 96 | OCFS2_FEATURE_INCOMPAT_XATTR)
97#define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN 97#define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN)
98 98
99/* 99/*
100 * Heartbeat-only devices are missing journals and other files. The 100 * Heartbeat-only devices are missing journals and other files. The
@@ -163,6 +163,12 @@
163 */ 163 */
164#define OCFS2_FEATURE_RO_COMPAT_UNWRITTEN 0x0001 164#define OCFS2_FEATURE_RO_COMPAT_UNWRITTEN 0x0001
165 165
166/*
167 * Maintain quota information for this filesystem
168 */
169#define OCFS2_FEATURE_RO_COMPAT_USRQUOTA 0x0002
170#define OCFS2_FEATURE_RO_COMPAT_GRPQUOTA 0x0004
171
166/* The byte offset of the first backup block will be 1G. 172/* The byte offset of the first backup block will be 1G.
167 * The following will be 4G, 16G, 64G, 256G and 1T. 173 * The following will be 4G, 16G, 64G, 256G and 1T.
168 */ 174 */
@@ -192,6 +198,7 @@
192#define OCFS2_HEARTBEAT_FL (0x00000200) /* Heartbeat area */ 198#define OCFS2_HEARTBEAT_FL (0x00000200) /* Heartbeat area */
193#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */ 199#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */
194#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */ 200#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */
201#define OCFS2_QUOTA_FL (0x00001000) /* Quota file */
195 202
196/* 203/*
197 * Flags on ocfs2_dinode.i_dyn_features 204 * Flags on ocfs2_dinode.i_dyn_features
@@ -329,13 +336,17 @@ enum {
329#define OCFS2_FIRST_ONLINE_SYSTEM_INODE SLOT_MAP_SYSTEM_INODE 336#define OCFS2_FIRST_ONLINE_SYSTEM_INODE SLOT_MAP_SYSTEM_INODE
330 HEARTBEAT_SYSTEM_INODE, 337 HEARTBEAT_SYSTEM_INODE,
331 GLOBAL_BITMAP_SYSTEM_INODE, 338 GLOBAL_BITMAP_SYSTEM_INODE,
332#define OCFS2_LAST_GLOBAL_SYSTEM_INODE GLOBAL_BITMAP_SYSTEM_INODE 339 USER_QUOTA_SYSTEM_INODE,
340 GROUP_QUOTA_SYSTEM_INODE,
341#define OCFS2_LAST_GLOBAL_SYSTEM_INODE GROUP_QUOTA_SYSTEM_INODE
333 ORPHAN_DIR_SYSTEM_INODE, 342 ORPHAN_DIR_SYSTEM_INODE,
334 EXTENT_ALLOC_SYSTEM_INODE, 343 EXTENT_ALLOC_SYSTEM_INODE,
335 INODE_ALLOC_SYSTEM_INODE, 344 INODE_ALLOC_SYSTEM_INODE,
336 JOURNAL_SYSTEM_INODE, 345 JOURNAL_SYSTEM_INODE,
337 LOCAL_ALLOC_SYSTEM_INODE, 346 LOCAL_ALLOC_SYSTEM_INODE,
338 TRUNCATE_LOG_SYSTEM_INODE, 347 TRUNCATE_LOG_SYSTEM_INODE,
348 LOCAL_USER_QUOTA_SYSTEM_INODE,
349 LOCAL_GROUP_QUOTA_SYSTEM_INODE,
339 NUM_SYSTEM_INODES 350 NUM_SYSTEM_INODES
340}; 351};
341 352
@@ -349,6 +360,8 @@ static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = {
349 [SLOT_MAP_SYSTEM_INODE] = { "slot_map", 0, S_IFREG | 0644 }, 360 [SLOT_MAP_SYSTEM_INODE] = { "slot_map", 0, S_IFREG | 0644 },
350 [HEARTBEAT_SYSTEM_INODE] = { "heartbeat", OCFS2_HEARTBEAT_FL, S_IFREG | 0644 }, 361 [HEARTBEAT_SYSTEM_INODE] = { "heartbeat", OCFS2_HEARTBEAT_FL, S_IFREG | 0644 },
351 [GLOBAL_BITMAP_SYSTEM_INODE] = { "global_bitmap", 0, S_IFREG | 0644 }, 362 [GLOBAL_BITMAP_SYSTEM_INODE] = { "global_bitmap", 0, S_IFREG | 0644 },
363 [USER_QUOTA_SYSTEM_INODE] = { "aquota.user", OCFS2_QUOTA_FL, S_IFREG | 0644 },
364 [GROUP_QUOTA_SYSTEM_INODE] = { "aquota.group", OCFS2_QUOTA_FL, S_IFREG | 0644 },
352 365
353 /* Slot-specific system inodes (one copy per slot) */ 366 /* Slot-specific system inodes (one copy per slot) */
354 [ORPHAN_DIR_SYSTEM_INODE] = { "orphan_dir:%04d", 0, S_IFDIR | 0755 }, 367 [ORPHAN_DIR_SYSTEM_INODE] = { "orphan_dir:%04d", 0, S_IFDIR | 0755 },
@@ -356,7 +369,9 @@ static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = {
356 [INODE_ALLOC_SYSTEM_INODE] = { "inode_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_CHAIN_FL, S_IFREG | 0644 }, 369 [INODE_ALLOC_SYSTEM_INODE] = { "inode_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_CHAIN_FL, S_IFREG | 0644 },
357 [JOURNAL_SYSTEM_INODE] = { "journal:%04d", OCFS2_JOURNAL_FL, S_IFREG | 0644 }, 370 [JOURNAL_SYSTEM_INODE] = { "journal:%04d", OCFS2_JOURNAL_FL, S_IFREG | 0644 },
358 [LOCAL_ALLOC_SYSTEM_INODE] = { "local_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_LOCAL_ALLOC_FL, S_IFREG | 0644 }, 371 [LOCAL_ALLOC_SYSTEM_INODE] = { "local_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_LOCAL_ALLOC_FL, S_IFREG | 0644 },
359 [TRUNCATE_LOG_SYSTEM_INODE] = { "truncate_log:%04d", OCFS2_DEALLOC_FL, S_IFREG | 0644 } 372 [TRUNCATE_LOG_SYSTEM_INODE] = { "truncate_log:%04d", OCFS2_DEALLOC_FL, S_IFREG | 0644 },
373 [LOCAL_USER_QUOTA_SYSTEM_INODE] = { "aquota.user:%04d", OCFS2_QUOTA_FL, S_IFREG | 0644 },
374 [LOCAL_GROUP_QUOTA_SYSTEM_INODE] = { "aquota.group:%04d", OCFS2_QUOTA_FL, S_IFREG | 0644 },
360}; 375};
361 376
362/* Parameter passed from mount.ocfs2 to module */ 377/* Parameter passed from mount.ocfs2 to module */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 9e7accc68b4b..41bb0197cf4c 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -225,6 +225,19 @@ static int ocfs2_sync_fs(struct super_block *sb, int wait)
225 return 0; 225 return 0;
226} 226}
227 227
228static int ocfs2_need_system_inode(struct ocfs2_super *osb, int ino)
229{
230 if (!OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, OCFS2_FEATURE_RO_COMPAT_USRQUOTA)
231 && (ino == USER_QUOTA_SYSTEM_INODE
232 || ino == LOCAL_USER_QUOTA_SYSTEM_INODE))
233 return 0;
234 if (!OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
235 && (ino == GROUP_QUOTA_SYSTEM_INODE
236 || ino == LOCAL_GROUP_QUOTA_SYSTEM_INODE))
237 return 0;
238 return 1;
239}
240
228static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb) 241static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb)
229{ 242{
230 struct inode *new = NULL; 243 struct inode *new = NULL;
@@ -251,6 +264,8 @@ static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb)
251 264
252 for (i = OCFS2_FIRST_ONLINE_SYSTEM_INODE; 265 for (i = OCFS2_FIRST_ONLINE_SYSTEM_INODE;
253 i <= OCFS2_LAST_GLOBAL_SYSTEM_INODE; i++) { 266 i <= OCFS2_LAST_GLOBAL_SYSTEM_INODE; i++) {
267 if (!ocfs2_need_system_inode(osb, i))
268 continue;
254 new = ocfs2_get_system_file_inode(osb, i, osb->slot_num); 269 new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
255 if (!new) { 270 if (!new) {
256 ocfs2_release_system_inodes(osb); 271 ocfs2_release_system_inodes(osb);
@@ -281,6 +296,8 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb)
281 for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1; 296 for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1;
282 i < NUM_SYSTEM_INODES; 297 i < NUM_SYSTEM_INODES;
283 i++) { 298 i++) {
299 if (!ocfs2_need_system_inode(osb, i))
300 continue;
284 new = ocfs2_get_system_file_inode(osb, i, osb->slot_num); 301 new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
285 if (!new) { 302 if (!new) {
286 ocfs2_release_system_inodes(osb); 303 ocfs2_release_system_inodes(osb);