Skip to content

Commit c614041

Browse files
author
Jaegeuk Kim
committed
f2fs: introduce FI_COMPRESS_RELEASED instead of using IMMUTABLE bit
Once we release compressed blocks, we used to set IMMUTABLE bit. But it turned out it disallows every fs operations which we don't need for compression. Let's just prevent writing data only. Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent 8f1d498 commit c614041

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

fs/f2fs/compress.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,8 @@ static int __f2fs_cluster_blocks(struct inode *inode,
928928
}
929929

930930
f2fs_bug_on(F2FS_I_SB(inode),
931-
!compr && ret != cluster_size && !IS_IMMUTABLE(inode));
931+
!compr && ret != cluster_size &&
932+
!is_inode_flag_set(inode, FI_COMPRESS_RELEASED));
932933
}
933934
fail:
934935
f2fs_put_dnode(&dn);

fs/f2fs/f2fs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ enum {
706706
FI_COMPRESS_CORRUPT, /* indicate compressed cluster is corrupted */
707707
FI_MMAP_FILE, /* indicate file was mmapped */
708708
FI_ENABLE_COMPRESS, /* enable compression in "user" compression mode */
709+
FI_COMPRESS_RELEASED, /* compressed blocks were released */
709710
FI_MAX, /* max flag, never be used */
710711
};
711712

@@ -2746,6 +2747,7 @@ static inline void __mark_inode_dirty_flag(struct inode *inode,
27462747
case FI_DATA_EXIST:
27472748
case FI_INLINE_DOTS:
27482749
case FI_PIN_FILE:
2750+
case FI_COMPRESS_RELEASED:
27492751
f2fs_mark_inode_dirty_sync(inode, true);
27502752
}
27512753
}
@@ -2867,6 +2869,8 @@ static inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri)
28672869
set_bit(FI_EXTRA_ATTR, fi->flags);
28682870
if (ri->i_inline & F2FS_PIN_FILE)
28692871
set_bit(FI_PIN_FILE, fi->flags);
2872+
if (ri->i_inline & F2FS_COMPRESS_RELEASED)
2873+
set_bit(FI_COMPRESS_RELEASED, fi->flags);
28702874
}
28712875

28722876
static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
@@ -2887,6 +2891,8 @@ static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
28872891
ri->i_inline |= F2FS_EXTRA_ATTR;
28882892
if (is_inode_flag_set(inode, FI_PIN_FILE))
28892893
ri->i_inline |= F2FS_PIN_FILE;
2894+
if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED))
2895+
ri->i_inline |= F2FS_COMPRESS_RELEASED;
28902896
}
28912897

28922898
static inline int f2fs_has_extra_attr(struct inode *inode)

fs/f2fs/file.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
6363
if (unlikely(IS_IMMUTABLE(inode)))
6464
return VM_FAULT_SIGBUS;
6565

66+
if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED))
67+
return VM_FAULT_SIGBUS;
68+
6669
if (unlikely(f2fs_cp_error(sbi))) {
6770
err = -EIO;
6871
goto err;
@@ -3420,7 +3423,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
34203423
goto out;
34213424
}
34223425

3423-
if (IS_IMMUTABLE(inode)) {
3426+
if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
34243427
ret = -EINVAL;
34253428
goto out;
34263429
}
@@ -3429,8 +3432,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
34293432
if (ret)
34303433
goto out;
34313434

3432-
F2FS_I(inode)->i_flags |= F2FS_IMMUTABLE_FL;
3433-
f2fs_set_inode_flags(inode);
3435+
set_inode_flag(inode, FI_COMPRESS_RELEASED);
34343436
inode->i_ctime = current_time(inode);
34353437
f2fs_mark_inode_dirty_sync(inode, true);
34363438

@@ -3585,7 +3587,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
35853587

35863588
inode_lock(inode);
35873589

3588-
if (!IS_IMMUTABLE(inode)) {
3590+
if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
35893591
ret = -EINVAL;
35903592
goto unlock_inode;
35913593
}
@@ -3630,8 +3632,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
36303632
up_write(&F2FS_I(inode)->i_mmap_sem);
36313633

36323634
if (ret >= 0) {
3633-
F2FS_I(inode)->i_flags &= ~F2FS_IMMUTABLE_FL;
3634-
f2fs_set_inode_flags(inode);
3635+
clear_inode_flag(inode, FI_COMPRESS_RELEASED);
36353636
inode->i_ctime = current_time(inode);
36363637
f2fs_mark_inode_dirty_sync(inode, true);
36373638
}
@@ -4249,6 +4250,11 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
42494250
goto unlock;
42504251
}
42514252

4253+
if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
4254+
ret = -EPERM;
4255+
goto unlock;
4256+
}
4257+
42524258
ret = generic_write_checks(iocb, from);
42534259
if (ret > 0) {
42544260
bool preallocated = false;

include/linux/f2fs_fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ struct f2fs_extent {
229229
#define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries */
230230
#define F2FS_EXTRA_ATTR 0x20 /* file having extra attribute */
231231
#define F2FS_PIN_FILE 0x40 /* file should not be gced */
232+
#define F2FS_COMPRESS_RELEASED 0x80 /* file released compressed blocks */
232233

233234
struct f2fs_inode {
234235
__le16 i_mode; /* file mode */

0 commit comments

Comments
 (0)