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/ntfs/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/ntfs/file.c')
-rw-r--r-- | fs/ntfs/file.c | 80 |
1 files changed, 27 insertions, 53 deletions
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 840e95e3f1d2..7bb487e663b4 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -328,25 +328,25 @@ err_out: | |||
328 | return err; | 328 | return err; |
329 | } | 329 | } |
330 | 330 | ||
331 | static ssize_t ntfs_prepare_file_for_write(struct file *file, loff_t *ppos, | 331 | static ssize_t ntfs_prepare_file_for_write(struct kiocb *iocb, |
332 | size_t *count) | 332 | struct iov_iter *from) |
333 | { | 333 | { |
334 | loff_t pos; | 334 | loff_t pos; |
335 | s64 end, ll; | 335 | s64 end, ll; |
336 | ssize_t err; | 336 | ssize_t err; |
337 | unsigned long flags; | 337 | unsigned long flags; |
338 | struct file *file = iocb->ki_filp; | ||
338 | struct inode *vi = file_inode(file); | 339 | struct inode *vi = file_inode(file); |
339 | ntfs_inode *base_ni, *ni = NTFS_I(vi); | 340 | ntfs_inode *base_ni, *ni = NTFS_I(vi); |
340 | ntfs_volume *vol = ni->vol; | 341 | ntfs_volume *vol = ni->vol; |
341 | 342 | ||
342 | ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, pos " | 343 | ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, pos " |
343 | "0x%llx, count 0x%lx.", vi->i_ino, | 344 | "0x%llx, count 0x%zx.", vi->i_ino, |
344 | (unsigned)le32_to_cpu(ni->type), | 345 | (unsigned)le32_to_cpu(ni->type), |
345 | (unsigned long long)*ppos, (unsigned long)*count); | 346 | (unsigned long long)iocb->ki_pos, |
346 | /* We can write back this queue in page reclaim. */ | 347 | iov_iter_count(from)); |
347 | current->backing_dev_info = inode_to_bdi(vi); | 348 | err = generic_write_checks(iocb, from); |
348 | err = generic_write_checks(file, ppos, count, S_ISBLK(vi->i_mode)); | 349 | if (unlikely(err <= 0)) |
349 | if (unlikely(err)) | ||
350 | goto out; | 350 | goto out; |
351 | /* | 351 | /* |
352 | * All checks have passed. Before we start doing any writing we want | 352 | * All checks have passed. Before we start doing any writing we want |
@@ -379,8 +379,6 @@ static ssize_t ntfs_prepare_file_for_write(struct file *file, loff_t *ppos, | |||
379 | err = -EOPNOTSUPP; | 379 | err = -EOPNOTSUPP; |
380 | goto out; | 380 | goto out; |
381 | } | 381 | } |
382 | if (*count == 0) | ||
383 | goto out; | ||
384 | base_ni = ni; | 382 | base_ni = ni; |
385 | if (NInoAttr(ni)) | 383 | if (NInoAttr(ni)) |
386 | base_ni = ni->ext.base_ntfs_ino; | 384 | base_ni = ni->ext.base_ntfs_ino; |
@@ -392,9 +390,9 @@ static ssize_t ntfs_prepare_file_for_write(struct file *file, loff_t *ppos, | |||
392 | * cannot fail either so there is no need to check the return code. | 390 | * cannot fail either so there is no need to check the return code. |
393 | */ | 391 | */ |
394 | file_update_time(file); | 392 | file_update_time(file); |
395 | pos = *ppos; | 393 | pos = iocb->ki_pos; |
396 | /* The first byte after the last cluster being written to. */ | 394 | /* The first byte after the last cluster being written to. */ |
397 | end = (pos + *count + vol->cluster_size_mask) & | 395 | end = (pos + iov_iter_count(from) + vol->cluster_size_mask) & |
398 | ~(u64)vol->cluster_size_mask; | 396 | ~(u64)vol->cluster_size_mask; |
399 | /* | 397 | /* |
400 | * If the write goes beyond the allocated size, extend the allocation | 398 | * If the write goes beyond the allocated size, extend the allocation |
@@ -422,7 +420,7 @@ static ssize_t ntfs_prepare_file_for_write(struct file *file, loff_t *ppos, | |||
422 | "partially extended.", | 420 | "partially extended.", |
423 | vi->i_ino, (unsigned) | 421 | vi->i_ino, (unsigned) |
424 | le32_to_cpu(ni->type)); | 422 | le32_to_cpu(ni->type)); |
425 | *count = ll - pos; | 423 | iov_iter_truncate(from, ll - pos); |
426 | } | 424 | } |
427 | } else { | 425 | } else { |
428 | err = ll; | 426 | err = ll; |
@@ -438,7 +436,7 @@ static ssize_t ntfs_prepare_file_for_write(struct file *file, loff_t *ppos, | |||
438 | vi->i_ino, (unsigned) | 436 | vi->i_ino, (unsigned) |
439 | le32_to_cpu(ni->type), | 437 | le32_to_cpu(ni->type), |
440 | (int)-err); | 438 | (int)-err); |
441 | *count = ll - pos; | 439 | iov_iter_truncate(from, ll - pos); |
442 | } else { | 440 | } else { |
443 | if (err != -ENOSPC) | 441 | if (err != -ENOSPC) |
444 | ntfs_error(vi->i_sb, "Cannot perform " | 442 | ntfs_error(vi->i_sb, "Cannot perform " |
@@ -1930,60 +1928,36 @@ again: | |||
1930 | } | 1928 | } |
1931 | 1929 | ||
1932 | /** | 1930 | /** |
1933 | * ntfs_file_write_iter_nolock - write data to a file | ||
1934 | * @iocb: IO state structure (file, offset, etc.) | ||
1935 | * @from: iov_iter with data to write | ||
1936 | * | ||
1937 | * Basically the same as __generic_file_write_iter() except that it ends | ||
1938 | * up calling ntfs_perform_write() instead of generic_perform_write() and that | ||
1939 | * O_DIRECT is not implemented. | ||
1940 | */ | ||
1941 | static ssize_t ntfs_file_write_iter_nolock(struct kiocb *iocb, | ||
1942 | struct iov_iter *from) | ||
1943 | { | ||
1944 | struct file *file = iocb->ki_filp; | ||
1945 | loff_t pos = iocb->ki_pos; | ||
1946 | ssize_t written = 0; | ||
1947 | ssize_t err; | ||
1948 | size_t count = iov_iter_count(from); | ||
1949 | |||
1950 | err = ntfs_prepare_file_for_write(file, &pos, &count); | ||
1951 | if (count && !err) { | ||
1952 | iov_iter_truncate(from, count); | ||
1953 | written = ntfs_perform_write(file, from, pos); | ||
1954 | if (likely(written >= 0)) | ||
1955 | iocb->ki_pos = pos + written; | ||
1956 | } | ||
1957 | current->backing_dev_info = NULL; | ||
1958 | return written ? written : err; | ||
1959 | } | ||
1960 | |||
1961 | /** | ||
1962 | * ntfs_file_write_iter - simple wrapper for ntfs_file_write_iter_nolock() | 1931 | * ntfs_file_write_iter - simple wrapper for ntfs_file_write_iter_nolock() |
1963 | * @iocb: IO state structure | 1932 | * @iocb: IO state structure |
1964 | * @from: iov_iter with data to write | 1933 | * @from: iov_iter with data to write |
1965 | * | 1934 | * |
1966 | * Basically the same as generic_file_write_iter() except that it ends up | 1935 | * Basically the same as generic_file_write_iter() except that it ends up |
1967 | * calling ntfs_file_write_iter_nolock() instead of | 1936 | * up calling ntfs_perform_write() instead of generic_perform_write() and that |
1968 | * __generic_file_write_iter(). | 1937 | * O_DIRECT is not implemented. |
1969 | */ | 1938 | */ |
1970 | static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | 1939 | static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) |
1971 | { | 1940 | { |
1972 | struct file *file = iocb->ki_filp; | 1941 | struct file *file = iocb->ki_filp; |
1973 | struct inode *vi = file_inode(file); | 1942 | struct inode *vi = file_inode(file); |
1974 | ssize_t ret; | 1943 | ssize_t written = 0; |
1944 | ssize_t err; | ||
1975 | 1945 | ||
1976 | mutex_lock(&vi->i_mutex); | 1946 | mutex_lock(&vi->i_mutex); |
1977 | ret = ntfs_file_write_iter_nolock(iocb, from); | 1947 | /* We can write back this queue in page reclaim. */ |
1948 | current->backing_dev_info = inode_to_bdi(vi); | ||
1949 | err = ntfs_prepare_file_for_write(iocb, from); | ||
1950 | if (iov_iter_count(from) && !err) | ||
1951 | written = ntfs_perform_write(file, from, iocb->ki_pos); | ||
1952 | current->backing_dev_info = NULL; | ||
1978 | mutex_unlock(&vi->i_mutex); | 1953 | mutex_unlock(&vi->i_mutex); |
1979 | if (ret > 0) { | 1954 | if (likely(written > 0)) { |
1980 | ssize_t err; | 1955 | err = generic_write_sync(file, iocb->ki_pos, written); |
1981 | |||
1982 | err = generic_write_sync(file, iocb->ki_pos - ret, ret); | ||
1983 | if (err < 0) | 1956 | if (err < 0) |
1984 | ret = err; | 1957 | written = 0; |
1985 | } | 1958 | } |
1986 | return ret; | 1959 | iocb->ki_pos += written; |
1960 | return written ? written : err; | ||
1987 | } | 1961 | } |
1988 | 1962 | ||
1989 | /** | 1963 | /** |