[PATCH 3/6] f2fs: need fsck.f2fs when f2fs_bug_on is triggered

2014-09-02 Thread Jaegeuk Kim
If any f2fs_bug_on is triggered, fsck.f2fs is needed.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/checkpoint.c |  6 +++---
 fs/f2fs/data.c   |  4 ++--
 fs/f2fs/dir.c|  4 ++--
 fs/f2fs/f2fs.h   | 26 ++-
 fs/f2fs/file.c   |  2 +-
 fs/f2fs/inline.c |  4 ++--
 fs/f2fs/inode.c  |  2 +-
 fs/f2fs/node.c   | 58 ++--
 fs/f2fs/recovery.c   |  8 
 fs/f2fs/segment.c| 17 +++
 fs/f2fs/xattr.c  |  2 +-
 11 files changed, 70 insertions(+), 63 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5af97d9..935a56e 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -374,7 +374,7 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi)
 void release_orphan_inode(struct f2fs_sb_info *sbi)
 {
spin_lock(>ino_lock[ORPHAN_INO]);
-   f2fs_bug_on(sbi->n_orphans == 0);
+   f2fs_bug_on(sbi, sbi->n_orphans == 0);
sbi->n_orphans--;
spin_unlock(>ino_lock[ORPHAN_INO]);
 }
@@ -394,7 +394,7 @@ void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t 
ino)
 static void recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 {
struct inode *inode = f2fs_iget(sbi->sb, ino);
-   f2fs_bug_on(IS_ERR(inode));
+   f2fs_bug_on(sbi, IS_ERR(inode));
clear_nlink(inode);
 
/* truncate all the data during iput */
@@ -455,7 +455,7 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, 
block_t start_blk)
list_for_each_entry(orphan, head, list) {
if (!page) {
page = find_get_page(META_MAPPING(sbi), start_blk++);
-   f2fs_bug_on(!page);
+   f2fs_bug_on(sbi, !page);
orphan_blk =
(struct f2fs_orphan_block *)page_address(page);
memset(orphan_blk, 0, sizeof(*orphan_blk));
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 8eb6fca..64d8550 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -258,7 +258,7 @@ int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t 
index)
int err;
 
/* if inode_page exists, index should be zero */
-   f2fs_bug_on(!need_put && index);
+   f2fs_bug_on(F2FS_I_SB(dn->inode), !need_put && index);
 
err = get_dnode_of_data(dn, index, ALLOC_NODE);
if (err)
@@ -321,7 +321,7 @@ void update_extent_cache(block_t blk_addr, struct 
dnode_of_data *dn)
block_t start_blkaddr, end_blkaddr;
int need_update = true;
 
-   f2fs_bug_on(blk_addr == NEW_ADDR);
+   f2fs_bug_on(F2FS_I_SB(dn->inode), blk_addr == NEW_ADDR);
fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
dn->ofs_in_node;
 
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index c242904..f1ceeb2 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -126,7 +126,7 @@ static struct f2fs_dir_entry *find_in_block(struct page 
*dentry_page,
 * For the most part, it should be a bug when name_len is zero.
 * We stop here for figuring out where the bugs has occurred.
 */
-   f2fs_bug_on(!de->name_len);
+   f2fs_bug_on(F2FS_P_SB(dentry_page), !de->name_len);
 
bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
}
@@ -151,7 +151,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode 
*dir,
bool room = false;
int max_slots = 0;
 
-   f2fs_bug_on(level > MAX_DIR_HASH_DEPTH);
+   f2fs_bug_on(F2FS_I_SB(dir), level > MAX_DIR_HASH_DEPTH);
 
nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level);
nblock = bucket_blocks(level);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 210c62d..b389ced 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -21,10 +21,16 @@
 #include 
 
 #ifdef CONFIG_F2FS_CHECK_FS
-#define f2fs_bug_on(condition) BUG_ON(condition)
+#define f2fs_bug_on(sbi, condition)BUG_ON(condition)
 #define f2fs_down_write(x, y)  down_write_nest_lock(x, y)
 #else
-#define f2fs_bug_on(condition) WARN_ON(condition)
+#define f2fs_bug_on(sbi, condition)\
+   do {\
+   if (unlikely(condition)) {  \
+   WARN_ON(1); \
+   sbi->need_fsck = true;  \
+   }   \
+   } while (0)
 #define f2fs_down_write(x, y)  down_write(x)
 #endif
 
@@ -719,8 +725,8 @@ static inline void dec_valid_block_count(struct 
f2fs_sb_info *sbi,
blkcnt_t count)
 {
spin_lock(>stat_lock);
-   f2fs_bug_on(sbi->total_valid_block_count < (block_t) count);
-   f2fs_bug_on(inode->i_blocks < count);
+   

[PATCH 3/6] f2fs: need fsck.f2fs when f2fs_bug_on is triggered

2014-09-02 Thread Jaegeuk Kim
If any f2fs_bug_on is triggered, fsck.f2fs is needed.

Signed-off-by: Jaegeuk Kim jaeg...@kernel.org
---
 fs/f2fs/checkpoint.c |  6 +++---
 fs/f2fs/data.c   |  4 ++--
 fs/f2fs/dir.c|  4 ++--
 fs/f2fs/f2fs.h   | 26 ++-
 fs/f2fs/file.c   |  2 +-
 fs/f2fs/inline.c |  4 ++--
 fs/f2fs/inode.c  |  2 +-
 fs/f2fs/node.c   | 58 ++--
 fs/f2fs/recovery.c   |  8 
 fs/f2fs/segment.c| 17 +++
 fs/f2fs/xattr.c  |  2 +-
 11 files changed, 70 insertions(+), 63 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5af97d9..935a56e 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -374,7 +374,7 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi)
 void release_orphan_inode(struct f2fs_sb_info *sbi)
 {
spin_lock(sbi-ino_lock[ORPHAN_INO]);
-   f2fs_bug_on(sbi-n_orphans == 0);
+   f2fs_bug_on(sbi, sbi-n_orphans == 0);
sbi-n_orphans--;
spin_unlock(sbi-ino_lock[ORPHAN_INO]);
 }
@@ -394,7 +394,7 @@ void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t 
ino)
 static void recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 {
struct inode *inode = f2fs_iget(sbi-sb, ino);
-   f2fs_bug_on(IS_ERR(inode));
+   f2fs_bug_on(sbi, IS_ERR(inode));
clear_nlink(inode);
 
/* truncate all the data during iput */
@@ -455,7 +455,7 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, 
block_t start_blk)
list_for_each_entry(orphan, head, list) {
if (!page) {
page = find_get_page(META_MAPPING(sbi), start_blk++);
-   f2fs_bug_on(!page);
+   f2fs_bug_on(sbi, !page);
orphan_blk =
(struct f2fs_orphan_block *)page_address(page);
memset(orphan_blk, 0, sizeof(*orphan_blk));
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 8eb6fca..64d8550 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -258,7 +258,7 @@ int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t 
index)
int err;
 
/* if inode_page exists, index should be zero */
-   f2fs_bug_on(!need_put  index);
+   f2fs_bug_on(F2FS_I_SB(dn-inode), !need_put  index);
 
err = get_dnode_of_data(dn, index, ALLOC_NODE);
if (err)
@@ -321,7 +321,7 @@ void update_extent_cache(block_t blk_addr, struct 
dnode_of_data *dn)
block_t start_blkaddr, end_blkaddr;
int need_update = true;
 
-   f2fs_bug_on(blk_addr == NEW_ADDR);
+   f2fs_bug_on(F2FS_I_SB(dn-inode), blk_addr == NEW_ADDR);
fofs = start_bidx_of_node(ofs_of_node(dn-node_page), fi) +
dn-ofs_in_node;
 
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index c242904..f1ceeb2 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -126,7 +126,7 @@ static struct f2fs_dir_entry *find_in_block(struct page 
*dentry_page,
 * For the most part, it should be a bug when name_len is zero.
 * We stop here for figuring out where the bugs has occurred.
 */
-   f2fs_bug_on(!de-name_len);
+   f2fs_bug_on(F2FS_P_SB(dentry_page), !de-name_len);
 
bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de-name_len));
}
@@ -151,7 +151,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode 
*dir,
bool room = false;
int max_slots = 0;
 
-   f2fs_bug_on(level  MAX_DIR_HASH_DEPTH);
+   f2fs_bug_on(F2FS_I_SB(dir), level  MAX_DIR_HASH_DEPTH);
 
nbucket = dir_buckets(level, F2FS_I(dir)-i_dir_level);
nblock = bucket_blocks(level);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 210c62d..b389ced 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -21,10 +21,16 @@
 #include linux/sched.h
 
 #ifdef CONFIG_F2FS_CHECK_FS
-#define f2fs_bug_on(condition) BUG_ON(condition)
+#define f2fs_bug_on(sbi, condition)BUG_ON(condition)
 #define f2fs_down_write(x, y)  down_write_nest_lock(x, y)
 #else
-#define f2fs_bug_on(condition) WARN_ON(condition)
+#define f2fs_bug_on(sbi, condition)\
+   do {\
+   if (unlikely(condition)) {  \
+   WARN_ON(1); \
+   sbi-need_fsck = true;  \
+   }   \
+   } while (0)
 #define f2fs_down_write(x, y)  down_write(x)
 #endif
 
@@ -719,8 +725,8 @@ static inline void dec_valid_block_count(struct 
f2fs_sb_info *sbi,
blkcnt_t count)
 {
spin_lock(sbi-stat_lock);
-   f2fs_bug_on(sbi-total_valid_block_count  (block_t) count);
-   f2fs_bug_on(inode-i_blocks  count);