Skip to content

Commit 3265d3d

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: support partial truncation on compressed inode
Supports to truncate compressed/normal cluster partially on compressed inode. Signed-off-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent b5f4684 commit 3265d3d

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

fs/f2fs/compress.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,55 @@ bool f2fs_compress_write_end(struct inode *inode, void *fsdata,
954954
return first_index;
955955
}
956956

957+
int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock)
958+
{
959+
void *fsdata = NULL;
960+
struct page *pagep;
961+
int log_cluster_size = F2FS_I(inode)->i_log_cluster_size;
962+
pgoff_t start_idx = from >> (PAGE_SHIFT + log_cluster_size) <<
963+
log_cluster_size;
964+
int err;
965+
966+
err = f2fs_is_compressed_cluster(inode, start_idx);
967+
if (err < 0)
968+
return err;
969+
970+
/* truncate normal cluster */
971+
if (!err)
972+
return f2fs_do_truncate_blocks(inode, from, lock);
973+
974+
/* truncate compressed cluster */
975+
err = f2fs_prepare_compress_overwrite(inode, &pagep,
976+
start_idx, &fsdata);
977+
978+
/* should not be a normal cluster */
979+
f2fs_bug_on(F2FS_I_SB(inode), err == 0);
980+
981+
if (err <= 0)
982+
return err;
983+
984+
if (err > 0) {
985+
struct page **rpages = fsdata;
986+
int cluster_size = F2FS_I(inode)->i_cluster_size;
987+
int i;
988+
989+
for (i = cluster_size - 1; i >= 0; i--) {
990+
loff_t start = rpages[i]->index << PAGE_SHIFT;
991+
992+
if (from <= start) {
993+
zero_user_segment(rpages[i], 0, PAGE_SIZE);
994+
} else {
995+
zero_user_segment(rpages[i], from - start,
996+
PAGE_SIZE);
997+
break;
998+
}
999+
}
1000+
1001+
f2fs_compress_write_end(inode, fsdata, start_idx, true);
1002+
}
1003+
return 0;
1004+
}
1005+
9571006
static int f2fs_write_compressed_pages(struct compress_ctx *cc,
9581007
int *submitted,
9591008
struct writeback_control *wbc,

fs/f2fs/f2fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,6 +3105,7 @@ static inline void f2fs_clear_page_private(struct page *page)
31053105
*/
31063106
int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
31073107
void f2fs_truncate_data_blocks(struct dnode_of_data *dn);
3108+
int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock);
31083109
int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock);
31093110
int f2fs_truncate(struct inode *inode);
31103111
int f2fs_getattr(const struct path *path, struct kstat *stat,
@@ -3825,6 +3826,7 @@ int f2fs_prepare_compress_overwrite(struct inode *inode,
38253826
struct page **pagep, pgoff_t index, void **fsdata);
38263827
bool f2fs_compress_write_end(struct inode *inode, void *fsdata,
38273828
pgoff_t index, unsigned copied);
3829+
int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock);
38283830
void f2fs_compress_write_end_io(struct bio *bio, struct page *page);
38293831
bool f2fs_is_compress_backend_ready(struct inode *inode);
38303832
void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity);

fs/f2fs/file.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -647,9 +647,6 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
647647
return 0;
648648
}
649649

650-
if (f2fs_compressed_file(inode))
651-
return 0;
652-
653650
page = f2fs_get_lock_data_page(inode, index, true);
654651
if (IS_ERR(page))
655652
return PTR_ERR(page) == -ENOENT ? 0 : PTR_ERR(page);
@@ -665,7 +662,7 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
665662
return 0;
666663
}
667664

668-
static int do_truncate_blocks(struct inode *inode, u64 from, bool lock)
665+
int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock)
669666
{
670667
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
671668
struct dnode_of_data dn;
@@ -733,7 +730,9 @@ static int do_truncate_blocks(struct inode *inode, u64 from, bool lock)
733730
int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock)
734731
{
735732
u64 free_from = from;
733+
int err;
736734

735+
#ifdef CONFIG_F2FS_FS_COMPRESSION
737736
/*
738737
* for compressed file, only support cluster size
739738
* aligned truncation.
@@ -748,8 +747,18 @@ int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock)
748747
free_from++;
749748
free_from <<= cluster_shift;
750749
}
750+
#endif
751+
752+
err = f2fs_do_truncate_blocks(inode, free_from, lock);
753+
if (err)
754+
return err;
755+
756+
#ifdef CONFIG_F2FS_FS_COMPRESSION
757+
if (from != free_from)
758+
err = f2fs_truncate_partial_cluster(inode, from, lock);
759+
#endif
751760

752-
return do_truncate_blocks(inode, free_from, lock);
761+
return err;
753762
}
754763

755764
int f2fs_truncate(struct inode *inode)

0 commit comments

Comments
 (0)