diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-08-14 19:32:54 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-08-21 16:57:01 -0400 |
commit | 764aa3e978020121cbb86111b5d8f42830015a06 (patch) | |
tree | df2e0f43245a452010aa184042e7da2306ed2e4b /fs/f2fs | |
parent | 14f4e690857715d5e0cbe403b4cb8e8c904a6c15 (diff) |
f2fs: avoid double lock in truncate_blocks
The init_inode_metadata calls truncate_blocks when error is occurred.
The callers holds f2fs_lock_op, so we should not call it again in
truncate_blocks.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/data.c | 2 | ||||
-rw-r--r-- | fs/f2fs/dir.c | 2 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 2 | ||||
-rw-r--r-- | fs/f2fs/file.c | 13 | ||||
-rw-r--r-- | fs/f2fs/inline.c | 2 |
5 files changed, 12 insertions, 9 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 6ba52a393063..76de83e25a89 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -936,7 +936,7 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to) | |||
936 | 936 | ||
937 | if (to > inode->i_size) { | 937 | if (to > inode->i_size) { |
938 | truncate_pagecache(inode, inode->i_size); | 938 | truncate_pagecache(inode, inode->i_size); |
939 | truncate_blocks(inode, inode->i_size); | 939 | truncate_blocks(inode, inode->i_size, true); |
940 | } | 940 | } |
941 | } | 941 | } |
942 | 942 | ||
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index a69bbfa90c99..155fb056b7f1 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -391,7 +391,7 @@ put_error: | |||
391 | error: | 391 | error: |
392 | /* once the failed inode becomes a bad inode, i_mode is S_IFREG */ | 392 | /* once the failed inode becomes a bad inode, i_mode is S_IFREG */ |
393 | truncate_inode_pages(&inode->i_data, 0); | 393 | truncate_inode_pages(&inode->i_data, 0); |
394 | truncate_blocks(inode, 0); | 394 | truncate_blocks(inode, 0, false); |
395 | remove_dirty_dir_inode(inode); | 395 | remove_dirty_dir_inode(inode); |
396 | remove_inode_page(inode); | 396 | remove_inode_page(inode); |
397 | return ERR_PTR(err); | 397 | return ERR_PTR(err); |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 2723b2d45479..7f976c1d1723 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -1122,7 +1122,7 @@ static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi) | |||
1122 | */ | 1122 | */ |
1123 | int f2fs_sync_file(struct file *, loff_t, loff_t, int); | 1123 | int f2fs_sync_file(struct file *, loff_t, loff_t, int); |
1124 | void truncate_data_blocks(struct dnode_of_data *); | 1124 | void truncate_data_blocks(struct dnode_of_data *); |
1125 | int truncate_blocks(struct inode *, u64); | 1125 | int truncate_blocks(struct inode *, u64, bool); |
1126 | void f2fs_truncate(struct inode *); | 1126 | void f2fs_truncate(struct inode *); |
1127 | int f2fs_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 1127 | int f2fs_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
1128 | int f2fs_setattr(struct dentry *, struct iattr *); | 1128 | int f2fs_setattr(struct dentry *, struct iattr *); |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index ecbdf6a6381c..a8e97f8ed163 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -422,7 +422,7 @@ out: | |||
422 | f2fs_put_page(page, 1); | 422 | f2fs_put_page(page, 1); |
423 | } | 423 | } |
424 | 424 | ||
425 | int truncate_blocks(struct inode *inode, u64 from) | 425 | int truncate_blocks(struct inode *inode, u64 from, bool lock) |
426 | { | 426 | { |
427 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 427 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
428 | unsigned int blocksize = inode->i_sb->s_blocksize; | 428 | unsigned int blocksize = inode->i_sb->s_blocksize; |
@@ -438,14 +438,16 @@ int truncate_blocks(struct inode *inode, u64 from) | |||
438 | free_from = (pgoff_t) | 438 | free_from = (pgoff_t) |
439 | ((from + blocksize - 1) >> (sbi->log_blocksize)); | 439 | ((from + blocksize - 1) >> (sbi->log_blocksize)); |
440 | 440 | ||
441 | f2fs_lock_op(sbi); | 441 | if (lock) |
442 | f2fs_lock_op(sbi); | ||
442 | 443 | ||
443 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 444 | set_new_dnode(&dn, inode, NULL, NULL, 0); |
444 | err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE); | 445 | err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE); |
445 | if (err) { | 446 | if (err) { |
446 | if (err == -ENOENT) | 447 | if (err == -ENOENT) |
447 | goto free_next; | 448 | goto free_next; |
448 | f2fs_unlock_op(sbi); | 449 | if (lock) |
450 | f2fs_unlock_op(sbi); | ||
449 | trace_f2fs_truncate_blocks_exit(inode, err); | 451 | trace_f2fs_truncate_blocks_exit(inode, err); |
450 | return err; | 452 | return err; |
451 | } | 453 | } |
@@ -463,7 +465,8 @@ int truncate_blocks(struct inode *inode, u64 from) | |||
463 | f2fs_put_dnode(&dn); | 465 | f2fs_put_dnode(&dn); |
464 | free_next: | 466 | free_next: |
465 | err = truncate_inode_blocks(inode, free_from); | 467 | err = truncate_inode_blocks(inode, free_from); |
466 | f2fs_unlock_op(sbi); | 468 | if (lock) |
469 | f2fs_unlock_op(sbi); | ||
467 | done: | 470 | done: |
468 | /* lastly zero out the first data page */ | 471 | /* lastly zero out the first data page */ |
469 | truncate_partial_data_page(inode, from); | 472 | truncate_partial_data_page(inode, from); |
@@ -480,7 +483,7 @@ void f2fs_truncate(struct inode *inode) | |||
480 | 483 | ||
481 | trace_f2fs_truncate(inode); | 484 | trace_f2fs_truncate(inode); |
482 | 485 | ||
483 | if (!truncate_blocks(inode, i_size_read(inode))) { | 486 | if (!truncate_blocks(inode, i_size_read(inode), true)) { |
484 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 487 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
485 | mark_inode_dirty(inode); | 488 | mark_inode_dirty(inode); |
486 | } | 489 | } |
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 520758b91999..4d1f39f4583c 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c | |||
@@ -247,7 +247,7 @@ process_inline: | |||
247 | update_inode(inode, ipage); | 247 | update_inode(inode, ipage); |
248 | f2fs_put_page(ipage, 1); | 248 | f2fs_put_page(ipage, 1); |
249 | } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { | 249 | } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { |
250 | truncate_blocks(inode, 0); | 250 | truncate_blocks(inode, 0, false); |
251 | set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | 251 | set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); |
252 | goto process_inline; | 252 | goto process_inline; |
253 | } | 253 | } |