Skip to content

Commit 7813081

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: fix to keep project quota consistent
This patch does below changes to keep consistence of project quota data in sudden power-cut case: - update inode.i_projid and project quota atomically under lock_op() in f2fs_ioc_setproject() - recover inode.i_projid and project quota in recover_inode() Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent af033b2 commit 7813081

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

fs/f2fs/f2fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2811,6 +2811,7 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count);
28112811
int f2fs_precache_extents(struct inode *inode);
28122812
long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
28132813
long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
2814+
int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid);
28142815
int f2fs_pin_file_control(struct inode *inode, bool inc);
28152816

28162817
/*

fs/f2fs/file.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,13 +2613,29 @@ static int f2fs_ioc_get_features(struct file *filp, unsigned long arg)
26132613
}
26142614

26152615
#ifdef CONFIG_QUOTA
2616+
int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid)
2617+
{
2618+
struct dquot *transfer_to[MAXQUOTAS] = {};
2619+
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
2620+
struct super_block *sb = sbi->sb;
2621+
int err = 0;
2622+
2623+
transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
2624+
if (!IS_ERR(transfer_to[PRJQUOTA])) {
2625+
err = __dquot_transfer(inode, transfer_to);
2626+
if (err)
2627+
set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
2628+
dqput(transfer_to[PRJQUOTA]);
2629+
}
2630+
return err;
2631+
}
2632+
26162633
static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
26172634
{
26182635
struct inode *inode = file_inode(filp);
26192636
struct f2fs_inode_info *fi = F2FS_I(inode);
26202637
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
26212638
struct super_block *sb = sbi->sb;
2622-
struct dquot *transfer_to[MAXQUOTAS] = {};
26232639
struct page *ipage;
26242640
kprojid_t kprojid;
26252641
int err;
@@ -2660,21 +2676,24 @@ static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
26602676
if (err)
26612677
return err;
26622678

2663-
transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
2664-
if (!IS_ERR(transfer_to[PRJQUOTA])) {
2665-
err = __dquot_transfer(inode, transfer_to);
2666-
dqput(transfer_to[PRJQUOTA]);
2667-
if (err)
2668-
goto out_dirty;
2669-
}
2679+
f2fs_lock_op(sbi);
2680+
err = f2fs_transfer_project_quota(inode, kprojid);
2681+
if (err)
2682+
goto out_unlock;
26702683

26712684
F2FS_I(inode)->i_projid = kprojid;
26722685
inode->i_ctime = current_time(inode);
2673-
out_dirty:
26742686
f2fs_mark_inode_dirty_sync(inode, true);
2687+
out_unlock:
2688+
f2fs_unlock_op(sbi);
26752689
return err;
26762690
}
26772691
#else
2692+
int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid)
2693+
{
2694+
return 0;
2695+
}
2696+
26782697
static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
26792698
{
26802699
if (projid != F2FS_DEF_PROJID)

fs/f2fs/recovery.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,18 @@ static int recover_inode(struct inode *inode, struct page *page)
254254
F2FS_FITS_IN_INODE(raw, le16_to_cpu(raw->i_extra_isize),
255255
i_projid)) {
256256
projid_t i_projid;
257+
kprojid_t kprojid;
257258

258259
i_projid = (projid_t)le32_to_cpu(raw->i_projid);
259-
F2FS_I(inode)->i_projid =
260-
make_kprojid(&init_user_ns, i_projid);
260+
kprojid = make_kprojid(&init_user_ns, i_projid);
261+
262+
if (!projid_eq(kprojid, F2FS_I(inode)->i_projid)) {
263+
err = f2fs_transfer_project_quota(inode,
264+
kprojid);
265+
if (err)
266+
return err;
267+
F2FS_I(inode)->i_projid = kprojid;
268+
}
261269
}
262270
}
263271

0 commit comments

Comments
 (0)