Commit 0eb0adad authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: measure inode.i_blocks as generic filesystem

Both in memory or on disk, generic filesystems record i_blocks with
512bytes sized sector count, also VFS sub module such as disk quota
follows this rule, but f2fs records it with 4096bytes sized block
count, this difference leads to that once we use dquota's function
which inc/dec iblocks, it will make i_blocks of f2fs being inconsistent
between in memory and on disk.

In order to resolve this issue, this patch changes to make in-memory
i_blocks of f2fs recording sector count instead of block count,
meanwhile leaving on-disk i_blocks recording block count.
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 663f387b
...@@ -1352,10 +1352,10 @@ static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) ...@@ -1352,10 +1352,10 @@ static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid)
*/ */
static inline int F2FS_HAS_BLOCKS(struct inode *inode) static inline int F2FS_HAS_BLOCKS(struct inode *inode)
{ {
if (F2FS_I(inode)->i_xattr_nid) block_t xattr_block = F2FS_I(inode)->i_xattr_nid ? 1 : 0;
return inode->i_blocks > F2FS_DEFAULT_ALLOCATED_BLOCKS + 1;
else return (inode->i_blocks >> F2FS_LOG_SECTORS_PER_BLOCK) >
return inode->i_blocks > F2FS_DEFAULT_ALLOCATED_BLOCKS; (F2FS_DEFAULT_ALLOCATED_BLOCKS + xattr_block);
} }
static inline bool f2fs_has_xattr_block(unsigned int ofs) static inline bool f2fs_has_xattr_block(unsigned int ofs)
...@@ -1363,7 +1363,7 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs) ...@@ -1363,7 +1363,7 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs)
return ofs == XATTR_NODE_OFFSET; return ofs == XATTR_NODE_OFFSET;
} }
static inline void f2fs_i_blocks_write(struct inode *, blkcnt_t, bool); static inline void f2fs_i_blocks_write(struct inode *, block_t, bool);
static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
struct inode *inode, blkcnt_t *count) struct inode *inode, blkcnt_t *count)
{ {
...@@ -1401,11 +1401,13 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, ...@@ -1401,11 +1401,13 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
struct inode *inode, struct inode *inode,
blkcnt_t count) block_t count)
{ {
blkcnt_t sectors = count << F2FS_LOG_SECTORS_PER_BLOCK;
spin_lock(&sbi->stat_lock); spin_lock(&sbi->stat_lock);
f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count); f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count);
f2fs_bug_on(sbi, inode->i_blocks < count); f2fs_bug_on(sbi, inode->i_blocks < sectors);
sbi->total_valid_block_count -= (block_t)count; sbi->total_valid_block_count -= (block_t)count;
spin_unlock(&sbi->stat_lock); spin_unlock(&sbi->stat_lock);
f2fs_i_blocks_write(inode, count, false); f2fs_i_blocks_write(inode, count, false);
...@@ -1856,13 +1858,14 @@ static inline void f2fs_i_links_write(struct inode *inode, bool inc) ...@@ -1856,13 +1858,14 @@ static inline void f2fs_i_links_write(struct inode *inode, bool inc)
} }
static inline void f2fs_i_blocks_write(struct inode *inode, static inline void f2fs_i_blocks_write(struct inode *inode,
blkcnt_t diff, bool add) block_t diff, bool add)
{ {
bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE); bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE);
bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER); bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER);
blkcnt_t sectors = diff << F2FS_LOG_SECTORS_PER_BLOCK;
inode->i_blocks = add ? inode->i_blocks + diff : inode->i_blocks = add ? inode->i_blocks + sectors :
inode->i_blocks - diff; inode->i_blocks - sectors;
f2fs_mark_inode_dirty_sync(inode, true); f2fs_mark_inode_dirty_sync(inode, true);
if (clean || recover) if (clean || recover)
set_inode_flag(inode, FI_AUTO_RECOVER); set_inode_flag(inode, FI_AUTO_RECOVER);
......
...@@ -665,7 +665,6 @@ int f2fs_getattr(const struct path *path, struct kstat *stat, ...@@ -665,7 +665,6 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
STATX_ATTR_NODUMP); STATX_ATTR_NODUMP);
generic_fillattr(inode, stat); generic_fillattr(inode, stat);
stat->blocks <<= 3;
return 0; return 0;
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "f2fs.h" #include "f2fs.h"
#include "node.h" #include "node.h"
#include "segment.h"
#include <trace/events/f2fs.h> #include <trace/events/f2fs.h>
...@@ -129,7 +130,7 @@ static int do_read_inode(struct inode *inode) ...@@ -129,7 +130,7 @@ static int do_read_inode(struct inode *inode)
i_gid_write(inode, le32_to_cpu(ri->i_gid)); i_gid_write(inode, le32_to_cpu(ri->i_gid));
set_nlink(inode, le32_to_cpu(ri->i_links)); set_nlink(inode, le32_to_cpu(ri->i_links));
inode->i_size = le64_to_cpu(ri->i_size); inode->i_size = le64_to_cpu(ri->i_size);
inode->i_blocks = le64_to_cpu(ri->i_blocks); inode->i_blocks = SECTOR_FROM_BLOCK(le64_to_cpu(ri->i_blocks));
inode->i_atime.tv_sec = le64_to_cpu(ri->i_atime); inode->i_atime.tv_sec = le64_to_cpu(ri->i_atime);
inode->i_ctime.tv_sec = le64_to_cpu(ri->i_ctime); inode->i_ctime.tv_sec = le64_to_cpu(ri->i_ctime);
...@@ -267,7 +268,7 @@ int update_inode(struct inode *inode, struct page *node_page) ...@@ -267,7 +268,7 @@ int update_inode(struct inode *inode, struct page *node_page)
ri->i_gid = cpu_to_le32(i_gid_read(inode)); ri->i_gid = cpu_to_le32(i_gid_read(inode));
ri->i_links = cpu_to_le32(inode->i_nlink); ri->i_links = cpu_to_le32(inode->i_nlink);
ri->i_size = cpu_to_le64(i_size_read(inode)); ri->i_size = cpu_to_le64(i_size_read(inode));
ri->i_blocks = cpu_to_le64(inode->i_blocks); ri->i_blocks = cpu_to_le64(SECTOR_TO_BLOCK(inode->i_blocks));
if (et) { if (et) {
read_lock(&et->lock); read_lock(&et->lock);
......
...@@ -1011,7 +1011,7 @@ int remove_inode_page(struct inode *inode) ...@@ -1011,7 +1011,7 @@ int remove_inode_page(struct inode *inode)
/* 0 is possible, after f2fs_new_inode() has failed */ /* 0 is possible, after f2fs_new_inode() has failed */
f2fs_bug_on(F2FS_I_SB(inode), f2fs_bug_on(F2FS_I_SB(inode),
inode->i_blocks != 0 && inode->i_blocks != 1); inode->i_blocks != 0 && inode->i_blocks != 8);
/* will put inode & node pages */ /* will put inode & node pages */
truncate_node(&dn); truncate_node(&dn);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment