switch generic_write_checks() to iocb and iter
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 9 Apr 2015 16:55:47 +0000 (12:55 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 12 Apr 2015 02:30:21 +0000 (22:30 -0400)
... returning -E... upon error and amount of data left in iter after
(possible) truncation upon success.  Note, that normal case gives
a non-zero (positive) return value, so any tests for != 0 _must_ be
updated.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Conflicts:
fs/ext4/file.c

14 files changed:
fs/9p/vfs_file.c
fs/btrfs/file.c
fs/ceph/file.c
fs/cifs/file.c
fs/ext4/file.c
fs/fuse/file.c
fs/ncpfs/file.c
fs/nfs/direct.c
fs/ntfs/file.c
fs/ocfs2/file.c
fs/udf/file.c
fs/xfs/xfs_file.c
include/linux/fs.h
mm/filemap.c

index b5b020a..2a9dd37 100644 (file)
@@ -404,21 +404,16 @@ static ssize_t
 v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *file = iocb->ki_filp;
-       ssize_t retval = 0;
-       loff_t origin = iocb->ki_pos;
-       size_t count = iov_iter_count(from);
+       ssize_t retval;
+       loff_t origin;
        int err = 0;
 
-       retval = generic_write_checks(file, &origin, &count);
-       if (retval)
+       retval = generic_write_checks(iocb, from);
+       if (retval <= 0)
                return retval;
 
-       iov_iter_truncate(from, count);
-
-       if (!count)
-               return 0;
-
-       retval = p9_client_write(file->private_data, origin, from, &err);
+       origin = iocb->ki_pos;
+       retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err);
        if (retval > 0) {
                struct inode *inode = file_inode(file);
                loff_t i_size;
@@ -428,12 +423,11 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
                if (inode->i_mapping && inode->i_mapping->nrpages)
                        invalidate_inode_pages2_range(inode->i_mapping,
                                                      pg_start, pg_end);
-               origin += retval;
+               iocb->ki_pos += retval;
                i_size = i_size_read(inode);
-               iocb->ki_pos = origin;
-               if (origin > i_size) {
-                       inode_add_bytes(inode, origin - i_size);
-                       i_size_write(inode, origin);
+               if (iocb->ki_pos > i_size) {
+                       inode_add_bytes(inode, iocb->ki_pos - i_size);
+                       i_size_write(inode, iocb->ki_pos);
                }
                return retval;
        }
index 691a84a..c64d11c 100644 (file)
@@ -1739,27 +1739,19 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
        u64 start_pos;
        u64 end_pos;
        ssize_t num_written = 0;
-       ssize_t err = 0;
-       size_t count = iov_iter_count(from);
        bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
-       loff_t pos = iocb->ki_pos;
+       ssize_t err;
+       loff_t pos;
+       size_t count;
 
        mutex_lock(&inode->i_mutex);
-
-       current->backing_dev_info = inode_to_bdi(inode);
-       err = generic_write_checks(file, &pos, &count);
-       if (err) {
+       err = generic_write_checks(iocb, from);
+       if (err <= 0) {
                mutex_unlock(&inode->i_mutex);
-               goto out;
-       }
-
-       if (count == 0) {
-               mutex_unlock(&inode->i_mutex);
-               goto out;
+               return err;
        }
 
-       iov_iter_truncate(from, count);
-
+       current->backing_dev_info = inode_to_bdi(inode);
        err = file_remove_suid(file);
        if (err) {
                mutex_unlock(&inode->i_mutex);
@@ -1786,6 +1778,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
         */
        update_time_for_write(inode);
 
+       pos = iocb->ki_pos;
+       count = iov_iter_count(from);
        start_pos = round_down(pos, root->sectorsize);
        if (start_pos > i_size_read(inode)) {
                /* Expand hole size to cover write data, preventing empty gap */
index 7618419..3f0b933 100644 (file)
@@ -941,9 +941,9 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_osd_client *osdc =
                &ceph_sb_to_client(inode->i_sb)->client->osdc;
-       ssize_t count = iov_iter_count(from), written = 0;
+       ssize_t count, written = 0;
        int err, want, got;
-       loff_t pos = iocb->ki_pos;
+       loff_t pos;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
@@ -953,14 +953,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
        /* We can write back this queue in page reclaim */
        current->backing_dev_info = inode_to_bdi(inode);
 
-       err = generic_write_checks(file, &pos, &count);
-       if (err)
-               goto out;
-
-       if (count == 0)
+       err = generic_write_checks(iocb, from);
+       if (err <= 0)
                goto out;
-       iov_iter_truncate(from, count);
 
+       pos = iocb->ki_pos;
+       count = iov_iter_count(from);
        err = file_remove_suid(file);
        if (err)
                goto out;
index 4202e74..ca2bc54 100644 (file)
@@ -2563,7 +2563,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
 ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *file = iocb->ki_filp;
-       size_t len;
        ssize_t total_written = 0;
        struct cifsFileInfo *open_file;
        struct cifs_tcon *tcon;
@@ -2579,16 +2578,10 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
         * write request.
         */
 
-       len = iov_iter_count(from);
-       rc = generic_write_checks(file, &iocb->ki_pos, &len);
-       if (rc)
+       rc = generic_write_checks(iocb, from);
+       if (rc <= 0)
                return rc;
 
-       if (!len)
-               return 0;
-
-       iov_iter_truncate(from, len);
-
        INIT_LIST_HEAD(&wdata_list);
        cifs_sb = CIFS_FILE_SB(file);
        open_file = file->private_data;
@@ -2599,8 +2592,8 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
 
        memcpy(&saved_from, from, sizeof(struct iov_iter));
 
-       rc = cifs_write_from_iter(iocb->ki_pos, len, from, open_file, cifs_sb,
-                                 &wdata_list);
+       rc = cifs_write_from_iter(iocb->ki_pos, iov_iter_count(from), from,
+                                 open_file, cifs_sb, &wdata_list);
 
        /*
         * If at least one write was successfully sent, then discard any rc
@@ -2674,7 +2667,6 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
        struct cifsInodeInfo *cinode = CIFS_I(inode);
        struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
        ssize_t rc;
-       size_t count;
 
        /*
         * We need to hold the sem to be sure nobody modifies lock list
@@ -2683,16 +2675,10 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
        down_read(&cinode->lock_sem);
        mutex_lock(&inode->i_mutex);
 
-       count = iov_iter_count(from);
-       rc = generic_write_checks(file, &iocb->ki_pos, &count);
-       if (rc)
+       rc = generic_write_checks(iocb, from);
+       if (rc <= 0)
                goto out;
 
-       if (count == 0)
-               goto out;
-
-       iov_iter_truncate(from, count);
-
        if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
                                     server->vals->exclusive_lock_type, NULL,
                                     CIFS_WRITE_OP))
diff --cc fs/ext4/file.c
Simple merge
diff --cc fs/fuse/file.c
Simple merge
diff --cc fs/ncpfs/file.c
Simple merge
diff --cc fs/nfs/direct.c
Simple merge
diff --cc fs/ntfs/file.c
Simple merge
diff --cc fs/ocfs2/file.c
Simple merge
diff --cc fs/udf/file.c
Simple merge
Simple merge
Simple merge
diff --cc mm/filemap.c
Simple merge