Skip to contentSkip to conversation

fsfreeze: manage kill signal when sb_start_write is called

PATCH Superseded Marco Stornelli 3 participants 4 messages Apr 6, 2013

Subsystems (11)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 2/4 fsfreeze: manage kill signal when sb_start_write is called

In every place where sb_start_write was called now we must manage the error code and return -EINTR.

---
 fs/btrfs/file.c    |    9 +++++++--
 fs/cifs/file.c     |    4 +++-
 fs/ext4/mmp.c      |    3 ++-
 fs/ext4/super.c    |    4 +++-
 fs/fuse/file.c     |    4 +++-
 fs/namespace.c     |    8 ++++++--
 fs/ntfs/file.c     |    4 +++-
 fs/ocfs2/file.c    |    4 +++-
 fs/open.c          |    8 ++++++--
 fs/splice.c        |    4 +++-
 fs/xfs/xfs_file.c  |    4 +++-
 include/linux/fs.h |    6 ++++--
 mm/filemap.c       |    4 +++-
 mm/filemap_xip.c   |    4 +++-
 14 files changed, 52 insertions(+), 18 deletions(-)
fs/btrfs/file.c +7 -2
index ade03e6..4891fda 100644
@@ -329,7 +329,9 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
 	range.len = (u64)-1;
 	range.start = defrag->last_offset;
 
-	sb_start_write(fs_info->sb);
+	ret = sb_start_write(fs_info->sb);
+	if (ret)
+		goto cleanup;
 	num_defrag = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
 				       BTRFS_DEFRAG_BATCH);
 	sb_end_write(fs_info->sb);
@@ -1514,7 +1516,9 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
 	size_t count, ocount;
 	bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
 
-	sb_start_write(inode->i_sb);
+	err = sb_start_write(inode->i_sb);
+	if (err)
+		goto out2;
 
 	mutex_lock(&inode->i_mutex);
 
@@ -1618,6 +1622,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
 		atomic_dec(&BTRFS_I(inode)->sync_writers);
 out:
 	sb_end_write(inode->i_sb);
+out2:
 	current->backing_dev_info = NULL;
 	return num_written ? num_written : err;
 }
fs/cifs/file.c +3 -1
index 7a0dd99..1613eb9 100644
@@ -2520,7 +2520,9 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
 
 	BUG_ON(iocb->ki_pos != pos);
 
-	sb_start_write(inode->i_sb);
+	rc = sb_start_write(inode->i_sb);
+	if (rc)
+		return rc;
 
 	/*
 	 * We need to hold the sem to be sure nobody modifies lock list
fs/ext4/mmp.c +2 -1
index f9b5515..dbdfc6d 100644
@@ -48,7 +48,8 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
 	 * We protect against freezing so that we don't create dirty buffers
 	 * on frozen filesystem.
 	 */
-	sb_start_write(sb);
+	if (sb_start_write(sb))
+		return 1;
 	ext4_mmp_csum_set(sb, mmp);
 	mark_buffer_dirty(bh);
 	lock_buffer(bh);
fs/ext4/super.c +3 -1
index 5d6d535..e6962be 100644
@@ -2712,7 +2712,9 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
 	sb = elr->lr_super;
 	ngroups = EXT4_SB(sb)->s_groups_count;
 
-	sb_start_write(sb);
+	ret = sb_start_write(sb);
+	if (ret)
+		return 1;
 	for (group = elr->lr_next_group; group < ngroups; group++) {
 		gdp = ext4_get_group_desc(sb, group, NULL);
 		if (!gdp) {
fs/fuse/file.c +3 -1
index 34b80ba..57194eb 100644
@@ -971,7 +971,9 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 		return err;
 
 	count = ocount;
-	sb_start_write(inode->i_sb);
+	err = sb_start_write(inode->i_sb);
+	if (err)
+		return err;
 	mutex_lock(&inode->i_mutex);
 
 	/* We can write back this queue in page reclaim */
fs/namespace.c +6 -2
index d581e45..2d2b054 100644
@@ -343,7 +343,9 @@ int mnt_want_write(struct vfsmount *m)
 {
 	int ret;
 
-	sb_start_write(m->mnt_sb);
+	ret = sb_start_write(m->mnt_sb);
+	if (ret)
+		return ret;
 	ret = __mnt_want_write(m);
 	if (ret)
 		sb_end_write(m->mnt_sb);
@@ -403,7 +405,9 @@ int mnt_want_write_file(struct file *file)
 {
 	int ret;
 
-	sb_start_write(file->f_path.mnt->mnt_sb);
+	ret = sb_start_write(file->f_path.mnt->mnt_sb);
+	if (ret)
+		return ret;
 	ret = __mnt_want_write_file(file);
 	if (ret)
 		sb_end_write(file->f_path.mnt->mnt_sb);
fs/ntfs/file.c +3 -1
index 5b2d4f0..a414c53 100644
@@ -2129,7 +2129,9 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
 	BUG_ON(iocb->ki_pos != pos);
 
-	sb_start_write(inode->i_sb);
+	ret = sb_start_write(inode->i_sb);
+	if (ret)
+		return ret;
 	mutex_lock(&inode->i_mutex);
 	ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
fs/ocfs2/file.c +3 -1
index 6474cb4..8b68176 100644
@@ -2248,7 +2248,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
 	if (iocb->ki_left == 0)
 		return 0;
 
-	sb_start_write(inode->i_sb);
+	ret = sb_start_write(inode->i_sb);
+	if (ret)
+		return ret;
 
 	appending = file->f_flags & O_APPEND ? 1 : 0;
 	direct_io = file->f_flags & O_DIRECT ? 1 : 0;
fs/open.c +6 -2
index 6835446..4589d88 100644
@@ -182,7 +182,9 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
 	if (IS_APPEND(inode))
 		goto out_putf;
 
-	sb_start_write(inode->i_sb);
+	error = sb_start_write(inode->i_sb);
+	if (error)
+		goto out_putf;
 	error = locks_verify_truncate(inode, f.file, length);
 	if (!error)
 		error = security_path_truncate(&f.file->f_path);
@@ -293,7 +295,9 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
 	if (!file->f_op->fallocate)
 		return -EOPNOTSUPP;
 
-	sb_start_write(inode->i_sb);
+	ret = sb_start_write(inode->i_sb);
+	if (ret)
+		return ret;
 	ret = file->f_op->fallocate(file, mode, offset, len);
 	sb_end_write(inode->i_sb);
 	return ret;
fs/splice.c +3 -1
index 29e394e..4b5c365 100644
@@ -1000,7 +1000,9 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 	};
 	ssize_t ret;
 
-	sb_start_write(inode->i_sb);
+	ret = sb_start_write(inode->i_sb);
+	if (ret)
+		return ret;
 
 	pipe_lock(pipe);
 
fs/xfs/xfs_file.c +3 -1
index f03bf1a..6ba4c0d 100644
@@ -775,7 +775,9 @@ xfs_file_aio_write(
 	if (ocount == 0)
 		return 0;
 
-	sb_start_write(inode->i_sb);
+	ret = sb_start_write(inode->i_sb);
+	if (ret)
+		return ret;
 
 	if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
 		ret = -EIO;
include/linux/fs.h +4 -2
index 2bfb88d..03921d6 100644
@@ -1376,6 +1376,8 @@ static inline void sb_end_intwrite(struct super_block *sb)
  * sb_start_write - get write access to a superblock
  * @sb: the super we write to
  *
+ * It returns zero when no error occured, the error code otherwise.
+ *
  * When a process wants to write data or metadata to a file system (i.e. dirty
  * a page or an inode), it should embed the operation in a sb_start_write() -
  * sb_end_write() pair to get exclusion against file system freezing. This
@@ -1391,9 +1393,9 @@ static inline void sb_end_intwrite(struct super_block *sb)
  *   -> i_mutex			(write path, truncate, directory ops, ...)
  *   -> s_umount		(freeze_super, thaw_super)
  */
-static inline void sb_start_write(struct super_block *sb)
+static inline int sb_start_write(struct super_block *sb)
 {
-	__sb_start_write_wait(sb, SB_FREEZE_WRITE, false);
+	return __sb_start_write_wait(sb, SB_FREEZE_WRITE, true);
 }
 
 static inline int sb_start_write_trylock(struct super_block *sb)
mm/filemap.c +3 -1
index e1979fd..b238671 100644
@@ -2528,7 +2528,9 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
 	BUG_ON(iocb->ki_pos != pos);
 
-	sb_start_write(inode->i_sb);
+	ret = sb_start_write(inode->i_sb);
+	if (ret)
+		return ret;
 	mutex_lock(&inode->i_mutex);
 	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
mm/filemap_xip.c +3 -1
index a912da6..4cde643 100644
@@ -404,7 +404,9 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len,
 	loff_t pos;
 	ssize_t ret;
 
-	sb_start_write(inode->i_sb);
+	ret = sb_start_write(inode->i_sb);
+	if (ret)
+		return ret;
 
 	mutex_lock(&inode->i_mutex);
 
Signature · 8 lines
1.7.3.4

------------------------------------------------------------------------------
Minimize network downtime and maximize team effectiveness.
Reduce network management and security costs.Learn how to hire 
the most talented Cisco Certified professionals. Visit the 
Employer Resources Portal
http://www.cisco.com/web/learning/employer_resources/index.html
#1 lore raw
Quoted 2 lines · Marco Stornelli

In every place where sb_start_write was called now we must manage the error code and return -EINTR.

If we must manage the error code, then these functions should be marked __must_check.

Signature · 4 lines
Matthew Wilcox				Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."
#2 lore raw

Il 06/04/2013 15:17, Matthew Wilcox ha scritto:

Quoted 7 lines · Marco Stornelli
Quoted 2 lines

In every place where sb_start_write was called now we must manage the error code and return -EINTR.

If we must manage the error code, then these functions should be marked __must_check.

Yep, good point.

Marco

maintainer
#3 lore raw
In reply to Marco Stornelli
Quoted 2 lines · Marco Stornelli

In every place where sb_start_write was called now we must manage the error code and return -EINTR.

Now go and look for callers of mnt_want_write() ;-/ The really painful one is in do_last(), but kern_path_create() is not much better; mq_open() would be bad too, had it not been about something you are not going to freeze anyway...