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 | |
| 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
...
55 files changed, 691 insertions, 861 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 7c3f187d48bf..0a926e2ba3ab 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
| @@ -196,7 +196,7 @@ prototypes: | |||
| 196 | void (*invalidatepage) (struct page *, unsigned int, unsigned int); | 196 | void (*invalidatepage) (struct page *, unsigned int, unsigned int); |
| 197 | int (*releasepage) (struct page *, int); | 197 | int (*releasepage) (struct page *, int); |
| 198 | void (*freepage)(struct page *); | 198 | void (*freepage)(struct page *); |
| 199 | int (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset); | 199 | int (*direct_IO)(struct kiocb *, struct iov_iter *iter, loff_t offset); |
| 200 | int (*migratepage)(struct address_space *, struct page *, struct page *); | 200 | int (*migratepage)(struct address_space *, struct page *, struct page *); |
| 201 | int (*launder_page)(struct page *); | 201 | int (*launder_page)(struct page *); |
| 202 | int (*is_partially_uptodate)(struct page *, unsigned long, unsigned long); | 202 | int (*is_partially_uptodate)(struct page *, unsigned long, unsigned long); |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 207cdca68bed..5d833b32bbcd 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
| @@ -590,7 +590,7 @@ struct address_space_operations { | |||
| 590 | void (*invalidatepage) (struct page *, unsigned int, unsigned int); | 590 | void (*invalidatepage) (struct page *, unsigned int, unsigned int); |
| 591 | int (*releasepage) (struct page *, int); | 591 | int (*releasepage) (struct page *, int); |
| 592 | void (*freepage)(struct page *); | 592 | void (*freepage)(struct page *); |
| 593 | ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset); | 593 | ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter, loff_t offset); |
| 594 | /* migrate the contents of a page to the specified target */ | 594 | /* migrate the contents of a page to the specified target */ |
| 595 | int (*migratepage) (struct page *, struct page *); | 595 | int (*migratepage) (struct page *, struct page *); |
| 596 | int (*launder_page) (struct page *); | 596 | int (*launder_page) (struct page *); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c4fd1e45ce1e..ae3fcb4199e9 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -88,28 +88,6 @@ static int part_shift; | |||
| 88 | 88 | ||
| 89 | static struct workqueue_struct *loop_wq; | 89 | static struct workqueue_struct *loop_wq; |
| 90 | 90 | ||
| 91 | /* | ||
| 92 | * Transfer functions | ||
| 93 | */ | ||
| 94 | static int transfer_none(struct loop_device *lo, int cmd, | ||
| 95 | struct page *raw_page, unsigned raw_off, | ||
| 96 | struct page *loop_page, unsigned loop_off, | ||
| 97 | int size, sector_t real_block) | ||
| 98 | { | ||
| 99 | char *raw_buf = kmap_atomic(raw_page) + raw_off; | ||
| 100 | char *loop_buf = kmap_atomic(loop_page) + loop_off; | ||
| 101 | |||
| 102 | if (cmd == READ) | ||
| 103 | memcpy(loop_buf, raw_buf, size); | ||
| 104 | else | ||
| 105 | memcpy(raw_buf, loop_buf, size); | ||
| 106 | |||
| 107 | kunmap_atomic(loop_buf); | ||
| 108 | kunmap_atomic(raw_buf); | ||
| 109 | cond_resched(); | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int transfer_xor(struct loop_device *lo, int cmd, | 91 | static int transfer_xor(struct loop_device *lo, int cmd, |
| 114 | struct page *raw_page, unsigned raw_off, | 92 | struct page *raw_page, unsigned raw_off, |
| 115 | struct page *loop_page, unsigned loop_off, | 93 | struct page *loop_page, unsigned loop_off, |
| @@ -148,14 +126,13 @@ static int xor_init(struct loop_device *lo, const struct loop_info64 *info) | |||
| 148 | 126 | ||
| 149 | static struct loop_func_table none_funcs = { | 127 | static struct loop_func_table none_funcs = { |
| 150 | .number = LO_CRYPT_NONE, | 128 | .number = LO_CRYPT_NONE, |
| 151 | .transfer = transfer_none, | 129 | }; |
| 152 | }; | ||
| 153 | 130 | ||
| 154 | static struct loop_func_table xor_funcs = { | 131 | static struct loop_func_table xor_funcs = { |
| 155 | .number = LO_CRYPT_XOR, | 132 | .number = LO_CRYPT_XOR, |
| 156 | .transfer = transfer_xor, | 133 | .transfer = transfer_xor, |
| 157 | .init = xor_init | 134 | .init = xor_init |
| 158 | }; | 135 | }; |
| 159 | 136 | ||
| 160 | /* xfer_funcs[0] is special - its release function is never called */ | 137 | /* xfer_funcs[0] is special - its release function is never called */ |
| 161 | static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { | 138 | static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { |
| @@ -215,207 +192,169 @@ lo_do_transfer(struct loop_device *lo, int cmd, | |||
| 215 | struct page *lpage, unsigned loffs, | 192 | struct page *lpage, unsigned loffs, |
| 216 | int size, sector_t rblock) | 193 | int size, sector_t rblock) |
| 217 | { | 194 | { |
| 218 | if (unlikely(!lo->transfer)) | 195 | int ret; |
| 196 | |||
| 197 | ret = lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock); | ||
| 198 | if (likely(!ret)) | ||
| 219 | return 0; | 199 | return 0; |
| 220 | 200 | ||
| 221 | return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock); | 201 | printk_ratelimited(KERN_ERR |
| 202 | "loop: Transfer error at byte offset %llu, length %i.\n", | ||
| 203 | (unsigned long long)rblock << 9, size); | ||
| 204 | return ret; | ||
| 222 | } | 205 | } |
| 223 | 206 | ||
| 224 | /** | 207 | static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) |
| 225 | * __do_lo_send_write - helper for writing data to a loop device | ||
| 226 | * | ||
