summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-16 23:27:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-16 23:27:56 -0400
commit4fc8adcfec3da639da76e8314c9ccefe5bf9a045 (patch)
treee07a2dea8acf04d8bbbecd4fd3a571653ecdd953 /fs/cifs
parent84588e7a5d8220446d677d7b909a20ee7a4496b9 (diff)
parentaa4d86163e4e91a1ac560954a554bab417e338f4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull third hunk of vfs changes from Al Viro: "This contains the ->direct_IO() changes from Omar + saner generic_write_checks() + dealing with fcntl()/{read,write}() races (mirroring O_APPEND/O_DIRECT into iocb->ki_flags and instead of repeatedly looking at ->f_flags, which can be changed by fcntl(2), check ->ki_flags - which cannot) + infrastructure bits for dhowells' d_inode annotations + Christophs switch of /dev/loop to vfs_iter_write()" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (30 commits) block: loop: switch to VFS ITER_BVEC configfs: Fix inconsistent use of file_inode() vs file->f_path.dentry->d_inode VFS: Make pathwalk use d_is_reg() rather than S_ISREG() VFS: Fix up debugfs to use d_is_dir() in place of S_ISDIR() VFS: Combine inode checks with d_is_negative() and d_is_positive() in pathwalk NFS: Don't use d_inode as a variable name VFS: Impose ordering on accesses of d_inode and d_flags VFS: Add owner-filesystem positive/negative dentry checks nfs: generic_write_checks() shouldn't be done on swapout... ocfs2: use __generic_file_write_iter() mirror O_APPEND and O_DIRECT into iocb->ki_flags switch generic_write_checks() to iocb and iter ocfs2: move generic_write_checks() before the alignment checks ocfs2_file_write_iter: stop messing with ppos udf_file_write_iter: reorder and simplify fuse: ->direct_IO() doesn't need generic_write_checks() ext4_file_write_iter: move generic_write_checks() up xfs_file_aio_write_checks: switch to iocb/iov_iter generic_write_checks(): drop isblk argument blkdev_write_iter: expand generic_file_checks() call in there ...
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/file.c93
1 files changed, 35 insertions, 58 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ca30c391a894..ca2bc5406306 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2560,10 +2560,9 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2560 return rc; 2560 return rc;
2561} 2561}
2562 2562
2563static ssize_t 2563ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
2564cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
2565{ 2564{
2566 size_t len; 2565 struct file *file = iocb->ki_filp;
2567 ssize_t total_written = 0; 2566 ssize_t total_written = 0;
2568 struct cifsFileInfo *open_file; 2567 struct cifsFileInfo *open_file;
2569 struct cifs_tcon *tcon; 2568 struct cifs_tcon *tcon;
@@ -2573,15 +2572,15 @@ cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
2573 struct iov_iter saved_from; 2572 struct iov_iter saved_from;
2574 int rc; 2573 int rc;
2575 2574
2576 len = iov_iter_count(from); 2575 /*
2577 rc = generic_write_checks(file, poffset, &len, 0); 2576 * BB - optimize the way when signing is disabled. We can drop this
2578 if (rc) 2577 * extra memory-to-memory copying and use iovec buffers for constructing
2579 return rc; 2578 * write request.
2580 2579 */
2581 if (!len)
2582 return 0;
2583 2580
2584 iov_iter_truncate(from, len); 2581 rc = generic_write_checks(iocb, from);
2582 if (rc <= 0)
2583 return rc;
2585 2584
2586 INIT_LIST_HEAD(&wdata_list); 2585 INIT_LIST_HEAD(&wdata_list);
2587 cifs_sb = CIFS_FILE_SB(file); 2586 cifs_sb = CIFS_FILE_SB(file);
@@ -2593,8 +2592,8 @@ cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
2593 2592
2594 memcpy(&saved_from, from, sizeof(struct iov_iter)); 2593 memcpy(&saved_from, from, sizeof(struct iov_iter));
2595 2594
2596 rc = cifs_write_from_iter(*poffset, len, from, open_file, cifs_sb, 2595 rc = cifs_write_from_iter(iocb->ki_pos, iov_iter_count(from), from,
2597 &wdata_list); 2596 open_file, cifs_sb, &wdata_list);
2598 2597
2599 /* 2598 /*
2600 * If at least one write was successfully sent, then discard any rc 2599 * If at least one write was successfully sent, then discard any rc
@@ -2633,7 +2632,7 @@ restart_loop:
2633 memcpy(&tmp_from, &saved_from, 2632 memcpy(&tmp_from, &saved_from,
2634 sizeof(struct iov_iter)); 2633 sizeof(struct iov_iter));
2635 iov_iter_advance(&tmp_from, 2634 iov_iter_advance(&tmp_from,
2636 wdata->offset - *poffset); 2635 wdata->offset - iocb->ki_pos);
2637 2636
2638 rc = cifs_write_from_iter(wdata->offset, 2637 rc = cifs_write_from_iter(wdata->offset,
2639 wdata->bytes, &tmp_from, 2638 wdata->bytes, &tmp_from,
@@ -2650,34 +2649,13 @@ restart_loop:
2650 kref_put(&wdata->refcount, cifs_uncached_writedata_release); 2649 kref_put(&wdata->refcount, cifs_uncached_writedata_release);
2651 } 2650 }
2652 2651
2653 if (total_written > 0) 2652 if (unlikely(!total_written))
2654 *poffset += total_written; 2653 return rc;
2655 2654
2655 iocb->ki_pos += total_written;
2656 set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(file_inode(file))->flags);
2656 cifs_stats_bytes_written(tcon, total_written); 2657 cifs_stats_bytes_written(tcon, total_written);
2657 return total_written ? total_written : (ssize_t)rc; 2658 return total_written;
2658}
2659
2660ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
2661{
2662 ssize_t written;
2663 struct inode *inode;
2664 loff_t pos = iocb->ki_pos;
2665
2666 inode = file_inode(iocb->ki_filp);
2667
2668 /*
2669 * BB - optimize the way when signing is disabled. We can drop this
2670 * extra memory-to-memory copying and use iovec buffers for constructing
2671 * write request.
2672 */
2673
2674 written = cifs_iovec_write(iocb->ki_filp, from, &pos);
2675 if (written > 0) {
2676 set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(inode)->flags);
2677 iocb->ki_pos = pos;
2678 }
2679
2680 return written;
2681} 2659}
2682 2660
2683static ssize_t 2661static ssize_t
@@ -2688,8 +2666,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
2688 struct inode *inode = file->f_mapping->host; 2666 struct inode *inode = file->f_mapping->host;
2689 struct cifsInodeInfo *cinode = CIFS_I(inode); 2667 struct cifsInodeInfo *cinode = CIFS_I(inode);
2690 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; 2668 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
2691 ssize_t rc = -EACCES; 2669 ssize_t rc;
2692 loff_t lock_pos = iocb->ki_pos;
2693 2670
2694 /* 2671 /*
2695 * We need to hold the sem to be sure nobody modifies lock list 2672 * We need to hold the sem to be sure nobody modifies lock list
@@ -2697,23 +2674,24 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
2697 */ 2674 */
2698 down_read(&cinode->lock_sem); 2675 down_read(&cinode->lock_sem);
2699 mutex_lock(&inode->i_mutex); 2676 mutex_lock(&inode->i_mutex);
2700 if (file->f_flags & O_APPEND) 2677
2701 lock_pos = i_size_read(inode); 2678 rc = generic_write_checks(iocb, from);
2702 if (!cifs_find_lock_conflict(cfile, lock_pos, iov_iter_count(from), 2679 if (rc <= 0)
2680 goto out;
2681
2682 if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
2703 server->vals->exclusive_lock_type, NULL, 2683 server->vals->exclusive_lock_type, NULL,
2704 CIFS_WRITE_OP)) { 2684 CIFS_WRITE_OP))
2705 rc = __generic_file_write_iter(iocb, from); 2685 rc = __generic_file_write_iter(iocb, from);
2706 mutex_unlock(&inode->i_mutex); 2686 else
2707 2687 rc = -EACCES;
2708 if (rc > 0) { 2688out:
2709 ssize_t err; 2689 mutex_unlock(&inode->i_mutex);
2710 2690
2711 err = generic_write_sync(file, iocb->ki_pos - rc, rc); 2691 if (rc > 0) {
2712 if (err < 0) 2692 ssize_t err = generic_write_sync(file, iocb->ki_pos - rc, rc);
2713 rc = err; 2693 if (err < 0)
2714 } 2694 rc = err;
2715 } else {
2716 mutex_unlock(&inode->i_mutex);
2717 } 2695 }
2718 up_read(&cinode->lock_sem); 2696 up_read(&cinode->lock_sem);
2719 return rc; 2697 return rc;
@@ -3877,8 +3855,7 @@ void cifs_oplock_break(struct work_struct *work)
3877 * Direct IO is not yet supported in the cached mode. 3855 * Direct IO is not yet supported in the cached mode.
3878 */ 3856 */
3879static ssize_t 3857static ssize_t
3880cifs_direct_io(int rw, struct kiocb *iocb, struct iov_iter *iter, 3858cifs_direct_io(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
3881 loff_t pos)
3882{ 3859{
3883 /* 3860 /*
3884 * FIXME 3861 * FIXME