diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-16 23:27:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-16 23:27:56 -0400 |
commit | 4fc8adcfec3da639da76e8314c9ccefe5bf9a045 (patch) | |
tree | e07a2dea8acf04d8bbbecd4fd3a571653ecdd953 /fs/udf/file.c | |
parent | 84588e7a5d8220446d677d7b909a20ee7a4496b9 (diff) | |
parent | aa4d86163e4e91a1ac560954a554bab417e338f4 (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/udf/file.c')
-rw-r--r-- | fs/udf/file.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/fs/udf/file.c b/fs/udf/file.c index f77f7681288f..5dadad9960b9 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -99,8 +99,7 @@ static int udf_adinicb_write_begin(struct file *file, | |||
99 | return 0; | 99 | return 0; |
100 | } | 100 | } |
101 | 101 | ||
102 | static ssize_t udf_adinicb_direct_IO(int rw, struct kiocb *iocb, | 102 | static ssize_t udf_adinicb_direct_IO(struct kiocb *iocb, struct iov_iter *iter, |
103 | struct iov_iter *iter, | ||
104 | loff_t offset) | 103 | loff_t offset) |
105 | { | 104 | { |
106 | /* Fallback to buffered I/O. */ | 105 | /* Fallback to buffered I/O. */ |
@@ -120,21 +119,21 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
120 | ssize_t retval; | 119 | ssize_t retval; |
121 | struct file *file = iocb->ki_filp; | 120 | struct file *file = iocb->ki_filp; |
122 | struct inode *inode = file_inode(file); | 121 | struct inode *inode = file_inode(file); |
123 | int err, pos; | ||
124 | size_t count = iov_iter_count(from); | ||
125 | struct udf_inode_info *iinfo = UDF_I(inode); | 122 | struct udf_inode_info *iinfo = UDF_I(inode); |
123 | int err; | ||
126 | 124 | ||
127 | mutex_lock(&inode->i_mutex); | 125 | mutex_lock(&inode->i_mutex); |
126 | |||
127 | retval = generic_write_checks(iocb, from); | ||
128 | if (retval <= 0) | ||
129 | goto out; | ||
130 | |||
128 | down_write(&iinfo->i_data_sem); | 131 | down_write(&iinfo->i_data_sem); |
129 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 132 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
130 | if (file->f_flags & O_APPEND) | 133 | loff_t end = iocb->ki_pos + iov_iter_count(from); |
131 | pos = inode->i_size; | ||
132 | else | ||
133 | pos = iocb->ki_pos; | ||
134 | 134 | ||
135 | if (inode->i_sb->s_blocksize < | 135 | if (inode->i_sb->s_blocksize < |
136 | (udf_file_entry_alloc_offset(inode) + | 136 | (udf_file_entry_alloc_offset(inode) + end)) { |
137 | pos + count)) { | ||
138 | err = udf_expand_file_adinicb(inode); | 137 | err = udf_expand_file_adinicb(inode); |
139 | if (err) { | 138 | if (err) { |
140 | mutex_unlock(&inode->i_mutex); | 139 | mutex_unlock(&inode->i_mutex); |
@@ -142,16 +141,14 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
142 | return err; | 141 | return err; |
143 | } | 142 | } |
144 | } else { | 143 | } else { |
145 | if (pos + count > inode->i_size) | 144 | iinfo->i_lenAlloc = max(end, inode->i_size); |
146 | iinfo->i_lenAlloc = pos + count; | ||
147 | else | ||
148 | iinfo->i_lenAlloc = inode->i_size; | ||
149 | up_write(&iinfo->i_data_sem); | 145 | up_write(&iinfo->i_data_sem); |
150 | } | 146 | } |
151 | } else | 147 | } else |
152 | up_write(&iinfo->i_data_sem); | 148 | up_write(&iinfo->i_data_sem); |
153 | 149 | ||
154 | retval = __generic_file_write_iter(iocb, from); | 150 | retval = __generic_file_write_iter(iocb, from); |
151 | out: | ||
155 | mutex_unlock(&inode->i_mutex); | 152 | mutex_unlock(&inode->i_mutex); |
156 | 153 | ||
157 | if (retval > 0) { | 154 | if (retval > 0) { |