diff options
-rw-r--r-- | fs/ocfs2/ocfs2.h | 3 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2_fs.h | 5 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 20 | ||||
-rw-r--r-- | fs/ocfs2/sysfile.c | 60 |
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 | ||
323 | static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = { | 328 | static 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 | |||
550 | out: | ||
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 | ||
47 | static inline int is_global_system_inode(int type); | ||
48 | static 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 |
53 | static struct lock_class_key ocfs2_sysfile_cluster_lock_key[NUM_SYSTEM_INODES]; | 48 | static 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 | ||
62 | static inline int is_in_system_inode_array(struct ocfs2_super *osb, | 57 | static 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 | ||
69 | struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb, | 105 | struct 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 */ |