Skip to content

Commit cf7cd17

Browse files
Daeho JeongJaegeuk Kim
authored andcommitted
f2fs: handle error cases of memory donation
In cases of removing memory donation, we need to handle some error cases like ENOENT and EACCES (indicating the range already has been donated). Signed-off-by: Daeho Jeong <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent bb5eb8a commit cf7cd17

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

fs/f2fs/f2fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,7 @@ enum {
828828
FI_ATOMIC_DIRTIED, /* indicate atomic file is dirtied */
829829
FI_ATOMIC_REPLACE, /* indicate atomic replace */
830830
FI_OPENED_FILE, /* indicate file has been opened */
831+
FI_DONATE_FINISHED, /* indicate page donation of file has been finished */
831832
FI_MAX, /* max flag, never be used */
832833
};
833834

fs/f2fs/file.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,27 +2468,28 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
24682468
return ret;
24692469
}
24702470

2471-
static void f2fs_keep_noreuse_range(struct inode *inode,
2471+
static int f2fs_keep_noreuse_range(struct inode *inode,
24722472
loff_t offset, loff_t len)
24732473
{
24742474
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
24752475
u64 max_bytes = F2FS_BLK_TO_BYTES(max_file_blocks(inode));
24762476
u64 start, end;
2477+
int ret = 0;
24772478

24782479
if (!S_ISREG(inode->i_mode))
2479-
return;
2480+
return 0;
24802481

24812482
if (offset >= max_bytes || len > max_bytes ||
24822483
(offset + len) > max_bytes)
2483-
return;
2484+
return 0;
24842485

24852486
start = offset >> PAGE_SHIFT;
24862487
end = DIV_ROUND_UP(offset + len, PAGE_SIZE);
24872488

24882489
inode_lock(inode);
24892490
if (f2fs_is_atomic_file(inode)) {
24902491
inode_unlock(inode);
2491-
return;
2492+
return 0;
24922493
}
24932494

24942495
spin_lock(&sbi->inode_lock[DONATE_INODE]);
@@ -2497,7 +2498,12 @@ static void f2fs_keep_noreuse_range(struct inode *inode,
24972498
if (!list_empty(&F2FS_I(inode)->gdonate_list)) {
24982499
list_del_init(&F2FS_I(inode)->gdonate_list);
24992500
sbi->donate_files--;
2500-
}
2501+
if (is_inode_flag_set(inode, FI_DONATE_FINISHED))
2502+
ret = -EALREADY;
2503+
else
2504+
set_inode_flag(inode, FI_DONATE_FINISHED);
2505+
} else
2506+
ret = -ENOENT;
25012507
} else {
25022508
if (list_empty(&F2FS_I(inode)->gdonate_list)) {
25032509
list_add_tail(&F2FS_I(inode)->gdonate_list,
@@ -2509,9 +2515,12 @@ static void f2fs_keep_noreuse_range(struct inode *inode,
25092515
}
25102516
F2FS_I(inode)->donate_start = start;
25112517
F2FS_I(inode)->donate_end = end - 1;
2518+
clear_inode_flag(inode, FI_DONATE_FINISHED);
25122519
}
25132520
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
25142521
inode_unlock(inode);
2522+
2523+
return ret;
25152524
}
25162525

25172526
static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
@@ -5242,8 +5251,8 @@ static int f2fs_file_fadvise(struct file *filp, loff_t offset, loff_t len,
52425251
f2fs_compressed_file(inode)))
52435252
f2fs_invalidate_compress_pages(F2FS_I_SB(inode), inode->i_ino);
52445253
else if (advice == POSIX_FADV_NOREUSE)
5245-
f2fs_keep_noreuse_range(inode, offset, len);
5246-
return 0;
5254+
err = f2fs_keep_noreuse_range(inode, offset, len);
5255+
return err;
52475256
}
52485257

52495258
#ifdef CONFIG_COMPAT

fs/f2fs/shrinker.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,17 @@ static unsigned int do_reclaim_caches(struct f2fs_sb_info *sbi,
184184
if (!inode)
185185
continue;
186186

187-
len = fi->donate_end - fi->donate_start + 1;
188-
npages = npages < len ? 0 : npages - len;
189-
invalidate_inode_pages2_range(inode->i_mapping,
187+
inode_lock(inode);
188+
if (!is_inode_flag_set(inode, FI_DONATE_FINISHED)) {
189+
len = fi->donate_end - fi->donate_start + 1;
190+
npages = npages < len ? 0 : npages - len;
191+
192+
invalidate_inode_pages2_range(inode->i_mapping,
190193
fi->donate_start, fi->donate_end);
194+
set_inode_flag(inode, FI_DONATE_FINISHED);
195+
}
196+
inode_unlock(inode);
197+
191198
iput(inode);
192199
cond_resched();
193200
}

0 commit comments

Comments
 (0)