f2fs: fix to use per-inode maxbytes
authorChengguang Xu <cgxu519@mykernel.net>
Wed, 13 Jan 2021 05:21:54 +0000 (13:21 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Wed, 27 Jan 2021 23:20:06 +0000 (15:20 -0800)
F2FS inode may have different max size, e.g. compressed file have
less blkaddr entries in all its direct-node blocks, result in being
with less max filesize. So change to use per-inode maxbytes.

Suggested-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Chengguang Xu <cgxu519@mykernel.net>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/super.c

index c7bb07dd9a20691ef779fe54b7226458feb95416..9aa458c01101cfb8f78010fb112c3da28c7ea80f 100644 (file)
@@ -3761,7 +3761,7 @@ static sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
                filemap_write_and_wait(mapping);
 
        /* Block number less than F2FS MAX BLOCKS */
-       if (unlikely(block >= F2FS_I_SB(inode)->max_file_blocks))
+       if (unlikely(block >= max_file_blocks(inode)))
                goto out;
 
        if (f2fs_compressed_file(inode)) {
index 63852404151eae6b2038332ad59706fdd6b46c11..ca5f1ff14dabf032cb4b705bb27ea64ea448e275 100644 (file)
@@ -1474,7 +1474,6 @@ struct f2fs_sb_info {
        unsigned int total_sections;            /* total section count */
        unsigned int total_node_count;          /* total node block count */
        unsigned int total_valid_node_count;    /* valid node block count */
-       loff_t max_file_blocks;                 /* max block index of file */
        int dir_level;                          /* directory level */
        int readdir_ra;                         /* readahead inode in readdir */
        u64 max_io_bytes;                       /* max io bytes to merge IOs */
@@ -3265,6 +3264,7 @@ int f2fs_inode_dirtied(struct inode *inode, bool sync);
 void f2fs_inode_synced(struct inode *inode);
 int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
 int f2fs_quota_sync(struct super_block *sb, int type);
+loff_t max_file_blocks(struct inode *inode);
 void f2fs_quota_off_umount(struct super_block *sb);
 int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
 int f2fs_sync_fs(struct super_block *sb, int sync);
index e3a5b620b50aea05e74451e8f9dbc0359f59fd50..e768371c6575042c0f3d86e05ce465c296b9d7cb 100644 (file)
@@ -486,6 +486,9 @@ static loff_t f2fs_llseek(struct file *file, loff_t offset, int whence)
        struct inode *inode = file->f_mapping->host;
        loff_t maxbytes = inode->i_sb->s_maxbytes;
 
+       if (f2fs_compressed_file(inode))
+               maxbytes = max_file_blocks(inode) << F2FS_BLKSIZE_BITS;
+
        switch (whence) {
        case SEEK_SET:
        case SEEK_CUR:
@@ -670,7 +673,7 @@ int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock)
 
        free_from = (pgoff_t)F2FS_BLK_ALIGN(from);
 
-       if (free_from >= sbi->max_file_blocks)
+       if (free_from >= max_file_blocks(inode))
                goto free_partial;
 
        if (lock)
@@ -2744,7 +2747,7 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg)
                return -EINVAL;
 
        if (unlikely((range.start + range.len) >> PAGE_SHIFT >
-                                       sbi->max_file_blocks))
+                                       max_file_blocks(inode)))
                return -EINVAL;
 
        err = mnt_want_write_file(filp);
@@ -3307,7 +3310,7 @@ int f2fs_precache_extents(struct inode *inode)
        map.m_next_extent = &m_next_extent;
        map.m_seg_type = NO_CHECK_TYPE;
        map.m_may_create = false;
-       end = F2FS_I_SB(inode)->max_file_blocks;
+       end = max_file_blocks(inode);
 
        while (map.m_lblk < end) {
                map.m_len = end - map.m_lblk;
index c8be27a9eed6b9b500e0ab6dd53a3ebb31f27415..9749c9ad374f19f8f05507e135abe948d6093370 100644 (file)
@@ -2739,10 +2739,10 @@ static const struct export_operations f2fs_export_ops = {
        .get_parent = f2fs_get_parent,
 };
 
-static loff_t max_file_blocks(void)
+loff_t max_file_blocks(struct inode *inode)
 {
        loff_t result = 0;
-       loff_t leaf_count = DEF_ADDRS_PER_BLOCK;
+       loff_t leaf_count;
 
        /*
         * note: previously, result is equal to (DEF_ADDRS_PER_INODE -
@@ -2751,6 +2751,11 @@ static loff_t max_file_blocks(void)
         * result as zero.
         */
 
+       if (inode && f2fs_compressed_file(inode))
+               leaf_count = ADDRS_PER_BLOCK(inode);
+       else
+               leaf_count = DEF_ADDRS_PER_BLOCK;
+
        /* two direct node blocks */
        result += (leaf_count * 2);
 
@@ -3634,8 +3639,7 @@ try_onemore:
        if (err)
                goto free_options;
 
-       sbi->max_file_blocks = max_file_blocks();
-       sb->s_maxbytes = sbi->max_file_blocks <<
+       sb->s_maxbytes = max_file_blocks(NULL) <<
                                le32_to_cpu(raw_super->log_blocksize);
        sb->s_max_links = F2FS_LINK_MAX;