aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/ocfs2.h3
-rw-r--r--fs/ocfs2/ocfs2_fs.h5
-rw-r--r--fs/ocfs2/super.c20
-rw-r--r--fs/ocfs2/sysfile.c60
4 files changed, 73 insertions, 15 deletions
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 65739b3b3276..687e291d73f2 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -284,7 +284,8 @@ struct ocfs2_super
284 struct super_block *sb; 284 struct super_block *sb;
285 struct inode *root_inode; 285 struct inode *root_inode;
286 struct inode *sys_root_inode; 286 struct inode *sys_root_inode;
287 struct inode *system_inodes[NUM_SYSTEM_INODES]; 287 struct inode *global_system_inodes[NUM_GLOBAL_SYSTEM_INODES];
288 struct inode **local_system_inodes;
288 289
289 struct ocfs2_slot_info *slot_info; 290 struct ocfs2_slot_info *slot_info;
290 291
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 33f1c9a8258d..723b20dac414 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -309,6 +309,7 @@ enum {
309 USER_QUOTA_SYSTEM_INODE, 309 USER_QUOTA_SYSTEM_INODE,
310 GROUP_QUOTA_SYSTEM_INODE, 310 GROUP_QUOTA_SYSTEM_INODE,
311#define OCFS2_LAST_GLOBAL_SYSTEM_INODE GROUP_QUOTA_SYSTEM_INODE 311#define OCFS2_LAST_GLOBAL_SYSTEM_INODE GROUP_QUOTA_SYSTEM_INODE
312#define OCFS2_FIRST_LOCAL_SYSTEM_INODE ORPHAN_DIR_SYSTEM_INODE
312 ORPHAN_DIR_SYSTEM_INODE, 313 ORPHAN_DIR_SYSTEM_INODE,
313 EXTENT_ALLOC_SYSTEM_INODE, 314 EXTENT_ALLOC_SYSTEM_INODE,
314 INODE_ALLOC_SYSTEM_INODE, 315 INODE_ALLOC_SYSTEM_INODE,
@@ -317,8 +318,12 @@ enum {
317 TRUNCATE_LOG_SYSTEM_INODE, 318 TRUNCATE_LOG_SYSTEM_INODE,
318 LOCAL_USER_QUOTA_SYSTEM_INODE, 319 LOCAL_USER_QUOTA_SYSTEM_INODE,
319 LOCAL_GROUP_QUOTA_SYSTEM_INODE, 320 LOCAL_GROUP_QUOTA_SYSTEM_INODE,
321#define OCFS2_LAST_LOCAL_SYSTEM_INODE LOCAL_GROUP_QUOTA_SYSTEM_INODE
320 NUM_SYSTEM_INODES 322 NUM_SYSTEM_INODES
321}; 323};
324#define NUM_GLOBAL_SYSTEM_INODES OCFS2_LAST_GLOBAL_SYSTEM_INODE
325#define NUM_LOCAL_SYSTEM_INODES \
326 (NUM_SYSTEM_INODES - OCFS2_FIRST_LOCAL_SYSTEM_INODE)
322 327
323static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = { 328static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = {
324 /* Global system inodes (single copy) */ 329 /* Global system inodes (single copy) */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 47415398d56a..350e8b5a9396 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -514,11 +514,11 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
514 514
515 mlog_entry_void(); 515 mlog_entry_void();
516 516
517 for (i = 0; i < NUM_SYSTEM_INODES; i++) { 517 for (i = 0; i < NUM_GLOBAL_SYSTEM_INODES; i++) {
518 inode = osb->system_inodes[i]; 518 inode = osb->global_system_inodes[i];
519 if (inode) { 519 if (inode) {
520 iput(inode); 520 iput(inode);
521 osb->system_inodes[i] = NULL; 521 osb->global_system_inodes[i] = NULL;
522 } 522 }
523 } 523 }
524 524
@@ -534,6 +534,20 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
534 osb->root_inode = NULL; 534 osb->root_inode = NULL;
535 } 535 }
536 536
537 if (!osb->local_system_inodes)
538 goto out;
539
540 for (i = 0; i < NUM_LOCAL_SYSTEM_INODES * osb->max_slots; i++) {
541 if (osb->local_system_inodes[i]) {
542 iput(osb->local_system_inodes[i]);
543 osb->local_system_inodes[i] = NULL;
544 }
545 }
546
547 kfree(osb->local_system_inodes);
548 osb->local_system_inodes = NULL;
549
550out:
537 mlog_exit(0); 551 mlog_exit(0);
538} 552}
539 553
diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c
index bfe7190cdbf1..902efb23b6a6 100644
--- a/fs/ocfs2/sysfile.c
+++ b/fs/ocfs2/sysfile.c
@@ -44,11 +44,6 @@ static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb,
44 int type, 44 int type,
45 u32 slot); 45 u32 slot);
46 46
47static inline int is_global_system_inode(int type);
48static inline int is_in_system_inode_array(struct ocfs2_super *osb,
49 int type,
50 u32 slot);
51
52#ifdef CONFIG_DEBUG_LOCK_ALLOC 47#ifdef CONFIG_DEBUG_LOCK_ALLOC
53static struct lock_class_key ocfs2_sysfile_cluster_lock_key[NUM_SYSTEM_INODES]; 48static struct lock_class_key ocfs2_sysfile_cluster_lock_key[NUM_SYSTEM_INODES];
54#endif 49#endif
@@ -59,11 +54,52 @@ static inline int is_global_system_inode(int type)
59 type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE; 54 type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE;
60} 55}
61 56
62static inline int is_in_system_inode_array(struct ocfs2_super *osb, 57static struct inode **get_local_system_inode(struct ocfs2_super *osb,
63 int type, 58 int type,
64 u32 slot) 59 u32 slot)
65{ 60{
66 return slot == osb->slot_num || is_global_system_inode(type); 61 int index;
62 struct inode **local_system_inodes, **free = NULL;
63
64 BUG_ON(slot == OCFS2_INVALID_SLOT);
65 BUG_ON(type < OCFS2_FIRST_LOCAL_SYSTEM_INODE ||
66 type > OCFS2_LAST_LOCAL_SYSTEM_INODE);
67
68 spin_lock(&osb->osb_lock);
69 local_system_inodes = osb->local_system_inodes;
70 spin_unlock(&osb->osb_lock);
71
72 if (unlikely(!local_system_inodes)) {
73 local_system_inodes = kzalloc(sizeof(struct inode *) *
74 NUM_LOCAL_SYSTEM_INODES *
75 osb->max_slots,
76 GFP_NOFS);
77 if (!local_system_inodes) {
78 mlog_errno(-ENOMEM);
79 /*
80 * return NULL here so that ocfs2_get_sytem_file_inodes
81 * will try to create an inode and use it. We will try
82 * to initialize local_system_inodes next time.
83 */
84 return NULL;
85 }
86
87 spin_lock(&osb->osb_lock);
88 if (osb->local_system_inodes) {
89 /* Someone has initialized it for us. */
90 free = local_system_inodes;
91 local_system_inodes = osb->local_system_inodes;
92 } else
93 osb->local_system_inodes = local_system_inodes;
94 spin_unlock(&osb->osb_lock);
95 if (unlikely(free))
96 kfree(free);
97 }
98
99 index = (slot * NUM_LOCAL_SYSTEM_INODES) +
100 (type - OCFS2_FIRST_LOCAL_SYSTEM_INODE);
101
102 return &local_system_inodes[index];
67} 103}
68 104
69struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb, 105struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb,
@@ -74,8 +110,10 @@ struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb,
74 struct inode **arr = NULL; 110 struct inode **arr = NULL;
75 111
76 /* avoid the lookup if cached in local system file array */ 112 /* avoid the lookup if cached in local system file array */
77 if (is_in_system_inode_array(osb, type, slot)) 113 if (is_global_system_inode(type)) {
78 arr = &(osb->system_inodes[type]); 114 arr = &(osb->global_system_inodes[type]);
115 } else
116 arr = get_local_system_inode(osb, type, slot);
79 117
80 if (arr && ((inode = *arr) != NULL)) { 118 if (arr && ((inode = *arr) != NULL)) {
81 /* get a ref in addition to the array ref */ 119 /* get a ref in addition to the array ref */