Skip to contentSkip to conversation

f2fs: support an ioctl to move a range of data blocks

PATCH New Jaegeuk Kim 1 participant 3 messages Jul 21, 2016

Subsystems (2)
lore
Share & tools
lore

Jaegeuk Kim

author maintainer
#0 lore raw

PATCH 1/3 f2fs: support an ioctl to move a range of data blocks

This patch implements moving a range of data blocks from source file to destination file.

---
 fs/f2fs/f2fs.h |   9 ++++
 fs/f2fs/file.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 141 insertions(+)
fs/f2fs/f2fs.h +9 -0
index c737854..7a57279 100644
@@ -268,6 +268,8 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal,
 #define F2FS_IOC_GARBAGE_COLLECT	_IO(F2FS_IOCTL_MAGIC, 6)
 #define F2FS_IOC_WRITE_CHECKPOINT	_IO(F2FS_IOCTL_MAGIC, 7)
 #define F2FS_IOC_DEFRAGMENT		_IO(F2FS_IOCTL_MAGIC, 8)
+#define F2FS_IOC_MOVE_RANGE		_IOWR(F2FS_IOCTL_MAGIC, 9,	\
+						struct f2fs_move_range)
 
 #define F2FS_IOC_SET_ENCRYPTION_POLICY	FS_IOC_SET_ENCRYPTION_POLICY
 #define F2FS_IOC_GET_ENCRYPTION_POLICY	FS_IOC_GET_ENCRYPTION_POLICY
@@ -297,6 +299,13 @@ struct f2fs_defragment {
 	u64 len;
 };
 
+struct f2fs_move_range {
+	u32 dst_fd;		/* destination fd */
+	u64 pos_in;		/* start position in src_fd */
+	u64 pos_out;		/* start position in dst_fd */
+	u64 len;		/* size to move */
+};
+
 /*
  * For INODE and NODE manager
  */
fs/f2fs/file.c +132 -0

156 lines not on this page · raw message

Signature · 1 line
2.8.3
author maintainer
#1 lore raw

PATCH 2/3 f2fs: avoid data race when deciding checkpoin in f2fs_sync_file

When fs utilization is almost full, f2fs_sync_file should do checkpoint if there is not enough space for roll-forward later. (i.e. space_for_roll_forward) So, currently we have no lock for sbi->alloc_valid_block_count, resulting in race condition.

In rare case, we can get -ENOSPC when doing roll-forward which triggers

	if (is_valid_blkaddr(sbi, dest, META_POR)) {
		if (src == NULL_ADDR) {
			err = reserve_new_block(&dn);
			f2fs_bug_on(sbi, err);
			...
		}
		...
	}

in do_recover_data.

So, this patch avoids that situation in advance.

---
 fs/f2fs/f2fs.h | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
fs/f2fs/f2fs.h +11 -2
index 7a57279..3098109 100644
@@ -1147,24 +1147,33 @@ static inline void f2fs_i_blocks_write(struct inode *, blkcnt_t, bool);
 static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
 				 struct inode *inode, blkcnt_t *count)
 {
+	blkcnt_t diff;
+
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 	if (time_to_inject(FAULT_BLOCK))
 		return false;
 #endif
+	/*
+	 * let's increase this in prior to actual block count change in order
+	 * for f2fs_sync_file to avoid data races when deciding checkpoint.
+	 */
+	percpu_counter_add(&sbi->alloc_valid_block_count, (*count));
+
 	spin_lock(&sbi->stat_lock);
 	sbi->total_valid_block_count += (block_t)(*count);
 	if (unlikely(sbi->total_valid_block_count > sbi->user_block_count)) {
-		*count -= sbi->total_valid_block_count - sbi->user_block_count;
+		diff = sbi->total_valid_block_count - sbi->user_block_count;
+		*count -= diff;
 		sbi->total_valid_block_count = sbi->user_block_count;
 		if (!*count) {
 			spin_unlock(&sbi->stat_lock);
+			percpu_counter_sub(&sbi->alloc_valid_block_count, diff);
 			return false;
 		}
 	}
 	spin_unlock(&sbi->stat_lock);
 
 	f2fs_i_blocks_write(inode, *count, true);
-	percpu_counter_add(&sbi->alloc_valid_block_count, (*count));
 	return true;
 }
 
Signature · 1 line
2.8.3
author maintainer
#2 lore raw

PATCH 3/3 f2fs: handle error case with f2fs_bug_on

In reply to Jaegeuk Kim

It's enough to show BUG or WARN by f2fs_bug_on for error case. Then, we don't need to remain corrupted filesystem.

---
 fs/f2fs/recovery.c | 2 ++
 1 file changed, 2 insertions(+)
fs/f2fs/recovery.c +2 -0
index 5d4461f..9e652d5 100644
@@ -482,6 +482,8 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
 #endif
 				/* We should not get -ENOSPC */
 				f2fs_bug_on(sbi, err);
+				if (err)
+					goto err;
 			}
 
 			/* Check the previous node page having this index */
Signature · 1 line
2.8.3