aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/namei.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/namei.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/namei.c')
-rw-r--r--fs/f2fs/namei.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 7c6e219a479c..841f6b486bd6 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -26,19 +26,19 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
26 nid_t ino; 26 nid_t ino;
27 struct inode *inode; 27 struct inode *inode;
28 bool nid_free = false; 28 bool nid_free = false;
29 int err; 29 int err, ilock;
30 30
31 inode = new_inode(sb); 31 inode = new_inode(sb);
32 if (!inode) 32 if (!inode)
33 return ERR_PTR(-ENOMEM); 33 return ERR_PTR(-ENOMEM);
34 34
35 mutex_lock_op(sbi, NODE_NEW); 35 ilock = mutex_lock_op(sbi);
36 if (!alloc_nid(sbi, &ino)) { 36 if (!alloc_nid(sbi, &ino)) {
37 mutex_unlock_op(sbi, NODE_NEW); 37 mutex_unlock_op(sbi, ilock);
38 err = -ENOSPC; 38 err = -ENOSPC;
39 goto fail; 39 goto fail;
40 } 40 }
41 mutex_unlock_op(sbi, NODE_NEW); 41 mutex_unlock_op(sbi, ilock);
42 42
43 inode->i_uid = current_fsuid(); 43 inode->i_uid = current_fsuid();
44 44
@@ -122,7 +122,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
122 struct f2fs_sb_info *sbi = F2FS_SB(sb); 122 struct f2fs_sb_info *sbi = F2FS_SB(sb);
123 struct inode *inode; 123 struct inode *inode;
124 nid_t ino = 0; 124 nid_t ino = 0;
125 int err; 125 int err, ilock;
126 126
127 f2fs_balance_fs(sbi); 127 f2fs_balance_fs(sbi);
128 128
@@ -138,7 +138,9 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
138 inode->i_mapping->a_ops = &f2fs_dblock_aops; 138 inode->i_mapping->a_ops = &f2fs_dblock_aops;
139 ino = inode->i_ino; 139 ino = inode->i_ino;
140 140
141 ilock = mutex_lock_op(sbi);
141 err = f2fs_add_link(dentry, inode); 142 err = f2fs_add_link(dentry, inode);
143 mutex_unlock_op(sbi, ilock);
142 if (err) 144 if (err)
143 goto out; 145 goto out;
144 146
@@ -162,7 +164,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
162 struct inode *inode = old_dentry->d_inode; 164 struct inode *inode = old_dentry->d_inode;
163 struct super_block *sb = dir->i_sb; 165 struct super_block *sb = dir->i_sb;
164 struct f2fs_sb_info *sbi = F2FS_SB(sb); 166 struct f2fs_sb_info *sbi = F2FS_SB(sb);
165 int err; 167 int err, ilock;
166 168
167 f2fs_balance_fs(sbi); 169 f2fs_balance_fs(sbi);
168 170
@@ -170,7 +172,9 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
170 atomic_inc(&inode->i_count); 172 atomic_inc(&inode->i_count);
171 173
172 set_inode_flag(F2FS_I(inode), FI_INC_LINK); 174 set_inode_flag(F2FS_I(inode), FI_INC_LINK);
175 ilock = mutex_lock_op(sbi);
173 err = f2fs_add_link(dentry, inode); 176 err = f2fs_add_link(dentry, inode);
177 mutex_unlock_op(sbi, ilock);
174 if (err) 178 if (err)
175 goto out; 179 goto out;
176 180
@@ -229,6 +233,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
229 struct f2fs_dir_entry *de; 233 struct f2fs_dir_entry *de;
230 struct page *page; 234 struct page *page;
231 int err = -ENOENT; 235 int err = -ENOENT;
236 int ilock;
232 237
233 f2fs_balance_fs(sbi); 238 f2fs_balance_fs(sbi);
234 239
@@ -243,7 +248,9 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
243 goto fail; 248 goto fail;
244 } 249 }
245 250
251 ilock = mutex_lock_op(sbi);
246 f2fs_delete_entry(de, page, inode); 252 f2fs_delete_entry(de, page, inode);
253 mutex_unlock_op(sbi, ilock);
247 254
248 /* In order to evict this inode, we set it dirty */ 255 /* In order to evict this inode, we set it dirty */
249 mark_inode_dirty(inode); 256 mark_inode_dirty(inode);
@@ -258,7 +265,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
258 struct f2fs_sb_info *sbi = F2FS_SB(sb); 265 struct f2fs_sb_info *sbi = F2FS_SB(sb);
259 struct inode *inode; 266 struct inode *inode;
260 size_t symlen = strlen(symname) + 1; 267 size_t symlen = strlen(symname) + 1;
261 int err; 268 int err, ilock;
262 269
263 f2fs_balance_fs(sbi); 270 f2fs_balance_fs(sbi);
264 271
@@ -269,7 +276,9 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
269 inode->i_op = &f2fs_symlink_inode_operations; 276 inode->i_op = &f2fs_symlink_inode_operations;
270 inode->i_mapping->a_ops = &f2fs_dblock_aops; 277 inode->i_mapping->a_ops = &f2fs_dblock_aops;
271 278
279 ilock = mutex_lock_op(sbi);
272 err = f2fs_add_link(dentry, inode); 280 err = f2fs_add_link(dentry, inode);
281 mutex_unlock_op(sbi, ilock);
273 if (err) 282 if (err)
274 goto out; 283 goto out;
275 284
@@ -291,7 +300,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
291{ 300{
292 struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 301 struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
293 struct inode *inode; 302 struct inode *inode;
294 int err; 303 int err, ilock;
295 304
296 f2fs_balance_fs(sbi); 305 f2fs_balance_fs(sbi);
297 306
@@ -305,7 +314,9 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
305 mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO); 314 mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
306 315
307 set_inode_flag(F2FS_I(inode), FI_INC_LINK); 316 set_inode_flag(F2FS_I(inode), FI_INC_LINK);
317 ilock = mutex_lock_op(sbi);
308 err = f2fs_add_link(dentry, inode); 318 err = f2fs_add_link(dentry, inode);
319 mutex_unlock_op(sbi, ilock);
309 if (err) 320 if (err)
310 goto out_fail; 321 goto out_fail;
311 322
@@ -340,6 +351,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
340 struct f2fs_sb_info *sbi = F2FS_SB(sb); 351 struct f2fs_sb_info *sbi = F2FS_SB(sb);
341 struct inode *inode; 352 struct inode *inode;
342 int err = 0; 353 int err = 0;
354 int ilock;
343 355
344 if (!new_valid_dev(rdev)) 356 if (!new_valid_dev(rdev))
345 return -EINVAL; 357 return -EINVAL;
@@ -353,7 +365,9 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
353 init_special_inode(inode, inode->i_mode, rdev); 365 init_special_inode(inode, inode->i_mode, rdev);
354 inode->i_op = &f2fs_special_inode_operations; 366 inode->i_op = &f2fs_special_inode_operations;
355 367
368 ilock = mutex_lock_op(sbi);
356 err = f2fs_add_link(dentry, inode); 369 err = f2fs_add_link(dentry, inode);
370 mutex_unlock_op(sbi, ilock);
357 if (err) 371 if (err)
358 goto out; 372 goto out;
359 373
@@ -381,7 +395,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
381 struct f2fs_dir_entry *old_dir_entry = NULL; 395 struct f2fs_dir_entry *old_dir_entry = NULL;
382 struct f2fs_dir_entry *old_entry; 396 struct f2fs_dir_entry *old_entry;
383 struct f2fs_dir_entry *new_entry; 397 struct f2fs_dir_entry *new_entry;
384 int err = -ENOENT; 398 int err = -ENOENT, ilock = -1;
385 399
386 f2fs_balance_fs(sbi); 400 f2fs_balance_fs(sbi);
387 401
@@ -396,7 +410,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
396 goto out_old; 410 goto out_old;
397 } 411 }
398 412
399 mutex_lock_op(sbi, RENAME); 413 ilock = mutex_lock_op(sbi);
400 414
401 if (new_inode) { 415 if (new_inode) {
402 struct page *new_page; 416 struct page *new_page;
@@ -419,7 +433,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
419 drop_nlink(new_inode); 433 drop_nlink(new_inode);
420 if (!new_inode->i_nlink) 434 if (!new_inode->i_nlink)
421 add_orphan_inode(sbi, new_inode->i_ino); 435 add_orphan_inode(sbi, new_inode->i_ino);
422 f2fs_write_inode(new_inode, NULL); 436 update_inode_page(new_inode);
423 } else { 437 } else {
424 err = f2fs_add_link(new_dentry, old_inode); 438 err = f2fs_add_link(new_dentry, old_inode);
425 if (err) 439 if (err)
@@ -427,7 +441,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
427 441
428 if (old_dir_entry) { 442 if (old_dir_entry) {
429 inc_nlink(new_dir); 443 inc_nlink(new_dir);
430 f2fs_write_inode(new_dir, NULL); 444 update_inode_page(new_dir);
431 } 445 }
432 } 446 }
433 447
@@ -445,10 +459,10 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
445 f2fs_put_page(old_dir_page, 0); 459 f2fs_put_page(old_dir_page, 0);
446 } 460 }
447 drop_nlink(old_dir); 461 drop_nlink(old_dir);
448 f2fs_write_inode(old_dir, NULL); 462 update_inode_page(old_dir);
449 } 463 }
450 464
451 mutex_unlock_op(sbi, RENAME); 465 mutex_unlock_op(sbi, ilock);
452 return 0; 466 return 0;
453 467
454out_dir: 468out_dir:
@@ -456,7 +470,7 @@ out_dir:
456 kunmap(old_dir_page); 470 kunmap(old_dir_page);
457 f2fs_put_page(old_dir_page, 0); 471 f2fs_put_page(old_dir_page, 0);
458 } 472 }
459 mutex_unlock_op(sbi, RENAME); 473 mutex_unlock_op(sbi, ilock);
460out_old: 474out_old:
461 kunmap(old_page); 475 kunmap(old_page);
462 f2fs_put_page(old_page, 0); 476 f2fs_put_page(old_page, 0);