diff options
| -rw-r--r-- | fs/aio.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 3 | ||||
| -rw-r--r-- | fs/cifs/file.c | 3 | ||||
| -rw-r--r-- | fs/compat.c | 6 | ||||
| -rw-r--r-- | fs/fuse/file.c | 2 | ||||
| -rw-r--r-- | fs/ntfs/file.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 3 | ||||
| -rw-r--r-- | fs/read_write.c | 8 | ||||
| -rw-r--r-- | fs/xfs/xfs_file.c | 3 | ||||
| -rw-r--r-- | include/linux/fs.h | 14 | ||||
| -rw-r--r-- | mm/filemap.c | 2 | 
11 files changed, 28 insertions, 22 deletions
@@ -1324,6 +1324,8 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb)  	if (iocb->ki_pos < 0)  		return -EINVAL; +	if (opcode == IOCB_CMD_PWRITEV) +		file_start_write(file);  	do {  		ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg],  			    iocb->ki_nr_segs - iocb->ki_cur_seg, @@ -1336,6 +1338,8 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb)  	} while (ret > 0 && iocb->ki_left > 0 &&  		 (opcode == IOCB_CMD_PWRITEV ||  		  (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode)))); +	if (opcode == IOCB_CMD_PWRITEV) +		file_end_write(file);  	/* This means we must have transferred all that we could */  	/* No need to retry anymore */ diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 5b4ea5f55b8..254aeb72915 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1514,8 +1514,6 @@ 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); -  	mutex_lock(&inode->i_mutex);  	err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); @@ -1617,7 +1615,6 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,  	if (sync)  		atomic_dec(&BTRFS_I(inode)->sync_writers);  out: -	sb_end_write(inode->i_sb);  	current->backing_dev_info = NULL;  	return num_written ? num_written : err;  } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 7a0dd99e450..2d4a231dd70 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2520,8 +2520,6 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,  	BUG_ON(iocb->ki_pos != pos); -	sb_start_write(inode->i_sb); -  	/*  	 * We need to hold the sem to be sure nobody modifies lock list  	 * with a brlock that prevents writing. @@ -2545,7 +2543,6 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,  	}  	up_read(&cinode->lock_sem); -	sb_end_write(inode->i_sb);  	return rc;  } diff --git a/fs/compat.c b/fs/compat.c index d487985dd0e..daa3b771d64 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1103,10 +1103,12 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,  		fnv = file->f_op->aio_write;  	} -	if (fnv) +	if (fnv) { +		file_start_write(file);  		ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,  						pos, fnv); -	else +		file_end_write(file); +	} else  		ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);  out: diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 34b80ba95ba..d15c6f21c17 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -971,7 +971,6 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  		return err;  	count = ocount; -	sb_start_write(inode->i_sb);  	mutex_lock(&inode->i_mutex);  	/* We can write back this queue in page reclaim */ @@ -1030,7 +1029,6 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  out:  	current->backing_dev_info = NULL;  	mutex_unlock(&inode->i_mutex); -	sb_end_write(inode->i_sb);  	return written ? written : err;  } diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 5b2d4f0853a..1da4b81e6f7 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2129,7 +2129,6 @@ 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);  	mutex_lock(&inode->i_mutex);  	ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);  	mutex_unlock(&inode->i_mutex); @@ -2138,7 +2137,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  		if (err < 0)  			ret = err;  	} -	sb_end_write(inode->i_sb);  	return ret;  } diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 6474cb44004..1c93e771e95 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2248,8 +2248,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,  	if (iocb->ki_left == 0)  		return 0; -	sb_start_write(inode->i_sb); -  	appending = file->f_flags & O_APPEND ? 1 : 0;  	direct_io = file->f_flags & O_DIRECT ? 1 : 0; @@ -2423,7 +2421,6 @@ out_sems:  		ocfs2_iocb_clear_sem_locked(iocb);  	mutex_unlock(&inode->i_mutex); -	sb_end_write(inode->i_sb);  	if (written)  		ret = written; diff --git a/fs/read_write.c b/fs/read_write.c index f7b5a23b804..3e1791a2cfd 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -398,6 +398,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof  	struct kiocb kiocb;  	ssize_t ret; +	file_start_write(filp);  	init_sync_kiocb(&kiocb, filp);  	kiocb.ki_pos = *ppos;  	kiocb.ki_left = len; @@ -413,6 +414,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof  	if (-EIOCBQUEUED == ret)  		ret = wait_on_sync_kiocb(&kiocb);  	*ppos = kiocb.ki_pos; +	file_end_write(filp);  	return ret;  } @@ -758,10 +760,12 @@ static ssize_t do_readv_writev(int type, struct file *file,  		fnv = file->f_op->aio_write;  	} -	if (fnv) +	if (fnv) { +		file_start_write(file);  		ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,  						pos, fnv); -	else +		file_end_write(file); +	} else  		ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);  out: diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f03bf1a456f..3800128d217 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -775,8 +775,6 @@ xfs_file_aio_write(  	if (ocount == 0)  		return 0; -	sb_start_write(inode->i_sb); -  	if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {  		ret = -EIO;  		goto out; @@ -800,7 +798,6 @@ xfs_file_aio_write(  	}  out: -	sb_end_write(inode->i_sb);  	return ret;  } diff --git a/include/linux/fs.h b/include/linux/fs.h index 2c28271ab9d..578a66e6ee7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2223,6 +2223,20 @@ static inline struct inode *file_inode(struct file *f)  	return f->f_inode;  } +static inline void file_start_write(struct file *file) +{ +	if (!S_ISREG(file_inode(file)->i_mode)) +		return; +	__sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); +} + +static inline void file_end_write(struct file *file) +{ +	if (!S_ISREG(file_inode(file)->i_mode)) +		return; +	__sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); +} +  /*   * get_write_access() gets write permission for a file.   * put_write_access() releases this write permission. diff --git a/mm/filemap.c b/mm/filemap.c index e1979fdca80..cbde8842a37 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2528,7 +2528,6 @@ 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);  	mutex_lock(&inode->i_mutex);  	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);  	mutex_unlock(&inode->i_mutex); @@ -2540,7 +2539,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  		if (err < 0 && ret > 0)  			ret = err;  	} -	sb_end_write(inode->i_sb);  	return ret;  }  EXPORT_SYMBOL(generic_file_aio_write);  |