linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/6] f2fs: fix to recover inode's project id during POR
@ 2018-09-25  7:35 Chao Yu
  2018-09-25  7:35 ` [PATCH 2/6] f2fs: fix to recover inode's i_flags " Chao Yu
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Chao Yu @ 2018-09-25  7:35 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, chao, Chao Yu

Testcase to reproduce this bug:
1. mkfs.f2fs -O extra_attr -O project_quota /dev/sdd
2. mount -t f2fs /dev/sdd /mnt/f2fs
3. touch /mnt/f2fs/file
4. sync
5. chattr -p 1 /mnt/f2fs/file
6. xfs_io -f /mnt/f2fs/file -c "fsync"
7. godown /mnt/f2fs
8. umount /mnt/f2fs
9. mount -t f2fs /dev/sdd /mnt/f2fs
10. lsattr -p /mnt/f2fs/file

    0 -----------------N- /mnt/f2fs/file

But actually, we expect the correct result is:

    1 -----------------N- /mnt/f2fs/file

The reason is we didn't recover inode.i_projid field during mount,
fix it.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/recovery.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 70f05650191e..c7e292f21b64 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -244,6 +244,19 @@ static int recover_inode(struct inode *inode, struct page *page)
 
 	i_uid_write(inode, le32_to_cpu(raw->i_uid));
 	i_gid_write(inode, le32_to_cpu(raw->i_gid));
+
+	if (raw->i_inline & F2FS_EXTRA_ATTR) {
+		if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)->sb) &&
+			F2FS_FITS_IN_INODE(raw, le16_to_cpu(raw->i_extra_isize),
+								i_projid)) {
+			projid_t i_projid;
+
+			i_projid = (projid_t)le32_to_cpu(raw->i_projid);
+			F2FS_I(inode)->i_projid =
+				make_kprojid(&init_user_ns, i_projid);
+		}
+	}
+
 	f2fs_i_size_write(inode, le64_to_cpu(raw->i_size));
 	inode->i_atime.tv_sec = le64_to_cpu(raw->i_atime);
 	inode->i_ctime.tv_sec = le64_to_cpu(raw->i_ctime);
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/6] f2fs: fix to recover inode's i_flags during POR
  2018-09-25  7:35 [PATCH 1/6] f2fs: fix to recover inode's project id during POR Chao Yu
@ 2018-09-25  7:35 ` Chao Yu
  2018-09-25  7:36 ` [PATCH 3/6] f2fs: fix to recover inode's i_gc_failures " Chao Yu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2018-09-25  7:35 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, chao, Chao Yu

Testcase to reproduce this bug:
1. mkfs.f2fs /dev/sdd
2. mount -t f2fs /dev/sdd /mnt/f2fs
3. touch /mnt/f2fs/file
4. sync
5. chattr +A /mnt/f2fs/file
6. xfs_io -f /mnt/f2fs/file -c "fsync"
7. godown /mnt/f2fs
8. umount /mnt/f2fs
9. mount -t f2fs /dev/sdd /mnt/f2fs
10. lsattr /mnt/f2fs/file

-----------------N- /mnt/f2fs/file

But actually, we expect the corrct result is:

-------A---------N- /mnt/f2fs/file

The reason is we didn't recover inode.i_flags field during mount,
fix it.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/recovery.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index c7e292f21b64..4a0f49654573 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -266,6 +266,7 @@ static int recover_inode(struct inode *inode, struct page *page)
 	inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec);
 
 	F2FS_I(inode)->i_advise = raw->i_advise;
+	F2FS_I(inode)->i_flags = le32_to_cpu(raw->i_flags);
 
 	recover_inline_flags(inode, raw);
 
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/6] f2fs: fix to recover inode's i_gc_failures during POR
  2018-09-25  7:35 [PATCH 1/6] f2fs: fix to recover inode's project id during POR Chao Yu
  2018-09-25  7:35 ` [PATCH 2/6] f2fs: fix to recover inode's i_flags " Chao Yu
@ 2018-09-25  7:36 ` Chao Yu
  2018-09-25  7:36 ` [PATCH 4/6] f2fs: fix to recover inode's crtime " Chao Yu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2018-09-25  7:36 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, chao, Chao Yu

inode.i_gc_failures is used to indicate that skip count of migrating
on blocks of inode, we should guarantee it can be recovered in sudden
power-off case.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/recovery.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 4a0f49654573..71577f30a889 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -267,6 +267,8 @@ static int recover_inode(struct inode *inode, struct page *page)
 
 	F2FS_I(inode)->i_advise = raw->i_advise;
 	F2FS_I(inode)->i_flags = le32_to_cpu(raw->i_flags);
+	F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] =
+				le16_to_cpu(raw->i_gc_failures);
 
 	recover_inline_flags(inode, raw);
 
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/6] f2fs: fix to recover inode's crtime during POR
  2018-09-25  7:35 [PATCH 1/6] f2fs: fix to recover inode's project id during POR Chao Yu
  2018-09-25  7:35 ` [PATCH 2/6] f2fs: fix to recover inode's i_flags " Chao Yu
  2018-09-25  7:36 ` [PATCH 3/6] f2fs: fix to recover inode's i_gc_failures " Chao Yu
@ 2018-09-25  7:36 ` Chao Yu
  2018-09-25  7:36 ` [PATCH 5/6] f2fs: fix to keep project quota consistent Chao Yu
  2018-09-25  7:36 ` [PATCH 6/6] f2fs: mark inode dirty explicitly in recover_inode() Chao Yu
  4 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2018-09-25  7:36 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, chao, Chao Yu

Testcase to reproduce this bug:
1. mkfs.f2fs -O extra_attr -O inode_crtime /dev/sdd
2. mount -t f2fs /dev/sdd /mnt/f2fs
3. touch /mnt/f2fs/file
4. xfs_io -f /mnt/f2fs/file -c "fsync"
5. godown /mnt/f2fs
6. umount /mnt/f2fs
7. mount -t f2fs /dev/sdd /mnt/f2fs
8. xfs_io -f /mnt/f2fs/file -c "statx -r"

stat.btime.tv_sec = 0
stat.btime.tv_nsec = 0

This patch fixes to recover inode creation time fields during
mount.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/node.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 5717fb6e7d7d..ea151e07790f 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2565,6 +2565,13 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
 			F2FS_FITS_IN_INODE(src, le16_to_cpu(src->i_extra_isize),
 								i_projid))
 			dst->i_projid = src->i_projid;
+
+		if (f2fs_sb_has_inode_crtime(sbi->sb) &&
+			F2FS_FITS_IN_INODE(src, le16_to_cpu(src->i_extra_isize),
+							i_crtime_nsec)) {
+			dst->i_crtime = src->i_crtime;
+			dst->i_crtime_nsec = src->i_crtime_nsec;
+		}
 	}
 
 	new_ni = old_ni;
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/6] f2fs: fix to keep project quota consistent
  2018-09-25  7:35 [PATCH 1/6] f2fs: fix to recover inode's project id during POR Chao Yu
                   ` (2 preceding siblings ...)
  2018-09-25  7:36 ` [PATCH 4/6] f2fs: fix to recover inode's crtime " Chao Yu
@ 2018-09-25  7:36 ` Chao Yu
  2018-09-25  7:36 ` [PATCH 6/6] f2fs: mark inode dirty explicitly in recover_inode() Chao Yu
  4 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2018-09-25  7:36 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, chao, Chao Yu

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>
---
 fs/f2fs/f2fs.h     |  1 +
 fs/f2fs/file.c     | 37 ++++++++++++++++++++++++++++---------
 fs/f2fs/recovery.c | 12 ++++++++++--
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index be16a49c8b62..171917c0961c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2793,6 +2793,7 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count);
 int f2fs_precache_extents(struct inode *inode);
 long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid);
 int f2fs_pin_file_control(struct inode *inode, bool inc);
 
 /*
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index a388866e71ee..6f02c8daff76 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2604,13 +2604,29 @@ static int f2fs_ioc_get_features(struct file *filp, unsigned long arg)
 }
 
 #ifdef CONFIG_QUOTA
+int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid)
+{
+	struct dquot *transfer_to[MAXQUOTAS] = {};
+	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+	struct super_block *sb = sbi->sb;
+	int err = 0;
+
+	transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
+	if (!IS_ERR(transfer_to[PRJQUOTA])) {
+		err = __dquot_transfer(inode, transfer_to);
+		if (err)
+			set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
+		dqput(transfer_to[PRJQUOTA]);
+	}
+	return err;
+}
+
 static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
 {
 	struct inode *inode = file_inode(filp);
 	struct f2fs_inode_info *fi = F2FS_I(inode);
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	struct super_block *sb = sbi->sb;
-	struct dquot *transfer_to[MAXQUOTAS] = {};
 	struct page *ipage;
 	kprojid_t kprojid;
 	int err;
@@ -2651,21 +2667,24 @@ static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
 	if (err)
 		return err;
 
-	transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
-	if (!IS_ERR(transfer_to[PRJQUOTA])) {
-		err = __dquot_transfer(inode, transfer_to);
-		dqput(transfer_to[PRJQUOTA]);
-		if (err)
-			goto out_dirty;
-	}
+	f2fs_lock_op(sbi);
+	err = f2fs_transfer_project_quota(inode, kprojid);
+	if (err)
+		goto out_unlock;
 
 	F2FS_I(inode)->i_projid = kprojid;
 	inode->i_ctime = current_time(inode);
-out_dirty:
 	f2fs_mark_inode_dirty_sync(inode, true);
+out_unlock:
+	f2fs_unlock_op(sbi);
 	return err;
 }
 #else
+int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid)
+{
+	return 0;
+}
+
 static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
 {
 	if (projid != F2FS_DEF_PROJID)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 71577f30a889..5e68e31989c8 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -250,10 +250,18 @@ static int recover_inode(struct inode *inode, struct page *page)
 			F2FS_FITS_IN_INODE(raw, le16_to_cpu(raw->i_extra_isize),
 								i_projid)) {
 			projid_t i_projid;
+			kprojid_t kprojid;
 
 			i_projid = (projid_t)le32_to_cpu(raw->i_projid);
-			F2FS_I(inode)->i_projid =
-				make_kprojid(&init_user_ns, i_projid);
+			kprojid = make_kprojid(&init_user_ns, i_projid);
+
+			if (!projid_eq(kprojid, F2FS_I(inode)->i_projid)) {
+				err = f2fs_transfer_project_quota(inode,
+								kprojid);
+				if (err)
+					return err;
+				F2FS_I(inode)->i_projid = kprojid;
+			}
 		}
 	}
 
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 6/6] f2fs: mark inode dirty explicitly in recover_inode()
  2018-09-25  7:35 [PATCH 1/6] f2fs: fix to recover inode's project id during POR Chao Yu
                   ` (3 preceding siblings ...)
  2018-09-25  7:36 ` [PATCH 5/6] f2fs: fix to keep project quota consistent Chao Yu
@ 2018-09-25  7:36 ` Chao Yu
  4 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2018-09-25  7:36 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, chao, Chao Yu

Mark inode dirty explicitly in the end of recover_inode() to make sure
that all recoverable fields can be persisted later.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/recovery.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 5e68e31989c8..409be551ba03 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -280,6 +280,8 @@ static int recover_inode(struct inode *inode, struct page *page)
 
 	recover_inline_flags(inode, raw);
 
+	f2fs_mark_inode_dirty_sync(inode, true);
+
 	if (file_enc_name(inode))
 		name = "<encrypted>";
 	else
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-09-25  7:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-25  7:35 [PATCH 1/6] f2fs: fix to recover inode's project id during POR Chao Yu
2018-09-25  7:35 ` [PATCH 2/6] f2fs: fix to recover inode's i_flags " Chao Yu
2018-09-25  7:36 ` [PATCH 3/6] f2fs: fix to recover inode's i_gc_failures " Chao Yu
2018-09-25  7:36 ` [PATCH 4/6] f2fs: fix to recover inode's crtime " Chao Yu
2018-09-25  7:36 ` [PATCH 5/6] f2fs: fix to keep project quota consistent Chao Yu
2018-09-25  7:36 ` [PATCH 6/6] f2fs: mark inode dirty explicitly in recover_inode() Chao Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).