aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/recovery.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2012-11-22 02:21:29 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-04-09 05:21:18 -0400
commit399368372ed9f3c396eadb5c2bbc98be8c774a39 (patch)
treeb496c910ebf04d95e5ad6cb1b65d8cbb45aeef89 /fs/f2fs/recovery.c
parent1127a3d448bcf4de338e60a7cc695d54c5767433 (diff)
f2fs: introduce a new global lock scheme
In the previous version, f2fs uses global locks according to the usage types, such as directory operations, block allocation, block write, and so on. Reference the following lock types in f2fs.h. enum lock_type { RENAME, /* for renaming operations */ DENTRY_OPS, /* for directory operations */ DATA_WRITE, /* for data write */ DATA_NEW, /* for data allocation */ DATA_TRUNC, /* for data truncate */ NODE_NEW, /* for node allocation */ NODE_TRUNC, /* for node truncate */ NODE_WRITE, /* for node write */ NR_LOCK_TYPE, }; In that case, we lose the performance under the multi-threading environment, since every types of operations must be conducted one at a time. In order to address the problem, let's share the locks globally with a mutex array regardless of any types. So, let users grab a mutex and perform their jobs in parallel as much as possbile. For this, I propose a new global lock scheme as follows. 0. Data structure - f2fs_sb_info -> mutex_lock[NR_GLOBAL_LOCKS] - f2fs_sb_info -> node_write 1. mutex_lock_op(sbi) - try to get an avaiable lock from the array. - returns the index of the gottern lock variable. 2. mutex_unlock_op(sbi, index of the lock) - unlock the given index of the lock. 3. mutex_lock_all(sbi) - grab all the locks in the array before the checkpoint. 4. mutex_unlock_all(sbi) - release all the locks in the array after checkpoint. 5. block_operations() - call mutex_lock_all() - sync_dirty_dir_inodes() - grab node_write - sync_node_pages() Note that, the pairs of mutex_lock_op()/mutex_unlock_op() and mutex_lock_all()/mutex_unlock_all() should be used together. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/recovery.c')
-rw-r--r--fs/f2fs/recovery.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 61bdaa755906..f16d12df8e99 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -242,6 +242,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
242 struct f2fs_summary sum; 242 struct f2fs_summary sum;
243 struct node_info ni; 243 struct node_info ni;
244 int err = 0; 244 int err = 0;
245 int ilock;
245 246
246 start = start_bidx_of_node(ofs_of_node(page)); 247 start = start_bidx_of_node(ofs_of_node(page));
247 if (IS_INODE(page)) 248 if (IS_INODE(page))
@@ -249,10 +250,14 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
249 else 250 else
250 end = start + ADDRS_PER_BLOCK; 251 end = start + ADDRS_PER_BLOCK;
251 252
253 ilock = mutex_lock_op(sbi);
252 set_new_dnode(&dn, inode, NULL, NULL, 0); 254 set_new_dnode(&dn, inode, NULL, NULL, 0);
255
253 err = get_dnode_of_data(&dn, start, ALLOC_NODE); 256 err = get_dnode_of_data(&dn, start, ALLOC_NODE);
254 if (err) 257 if (err) {
258 mutex_unlock_op(sbi, ilock);
255 return err; 259 return err;
260 }
256 261
257 wait_on_page_writeback(dn.node_page); 262 wait_on_page_writeback(dn.node_page);
258 263
@@ -297,6 +302,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
297 302
298 recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr); 303 recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr);
299 f2fs_put_dnode(&dn); 304 f2fs_put_dnode(&dn);
305 mutex_unlock_op(sbi, ilock);
300 return 0; 306 return 0;
301} 307}
302 308