aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-04-17 16:09:22 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:39:36 -0400
commit9b884164d59707216840159d45f6be68073fac6e (patch)
treec1e6f2ffef22003502bd8f118492b16ae03723bc /fs/ext4
parenta8324754889c0a491b216bc0502ef9ba557eeac7 (diff)
convert ext4 to ->write_iter()
unfortunately, Ted's changes to ext4_file_write() are *still* an incomplete fix - playing with rlimits can let you smuggle an unaligned request past the checks. So there almost certainly will be more merge PITA around that place... [fix from Peter Ujfalusi <peter.ujfalusi@ti.com> folded] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/file.c29
1 files changed, 11 insertions, 18 deletions
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 86a13a514e4a..48383a5f37a1 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -74,26 +74,22 @@ void ext4_unwritten_wait(struct inode *inode)
74 * or one thread will zero the other's data, causing corruption. 74 * or one thread will zero the other's data, causing corruption.
75 */ 75 */
76static int 76static int
77ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, 77ext4_unaligned_aio(struct inode *inode, struct iov_iter *from, loff_t pos)
78 unsigned long nr_segs, loff_t pos)
79{ 78{
80 struct super_block *sb = inode->i_sb; 79 struct super_block *sb = inode->i_sb;
81 int blockmask = sb->s_blocksize - 1; 80 int blockmask = sb->s_blocksize - 1;
82 size_t count = iov_length(iov, nr_segs);
83 loff_t final_size = pos + count;
84 81
85 if (pos >= i_size_read(inode)) 82 if (pos >= i_size_read(inode))
86 return 0; 83 return 0;
87 84
88 if ((pos & blockmask) || (final_size & blockmask)) 85 if ((pos | iov_iter_alignment(from)) & blockmask)
89 return 1; 86 return 1;
90 87
91 return 0; 88 return 0;
92} 89}
93 90
94static ssize_t 91static ssize_t
95ext4_file_write(struct kiocb *iocb, const struct iovec *iov, 92ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
96 unsigned long nr_segs, loff_t pos)
97{ 93{
98 struct file *file = iocb->ki_filp; 94 struct file *file = iocb->ki_filp;
99 struct inode *inode = file_inode(iocb->ki_filp); 95 struct inode *inode = file_inode(iocb->ki_filp);
@@ -101,10 +97,9 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
101 struct blk_plug plug; 97 struct blk_plug plug;
102 int o_direct = file->f_flags & O_DIRECT; 98 int o_direct = file->f_flags & O_DIRECT;
103 int overwrite = 0; 99 int overwrite = 0;
104 size_t length = iov_length(iov, nr_segs); 100 size_t length = iov_iter_count(from);
105 ssize_t ret; 101 ssize_t ret;
106 102 loff_t pos = iocb->ki_pos;
107 BUG_ON(iocb->ki_pos != pos);
108 103
109 /* 104 /*
110 * Unaligned direct AIO must be serialized; see comment above 105 * Unaligned direct AIO must be serialized; see comment above
@@ -114,7 +109,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
114 ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && 109 ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
115 !is_sync_kiocb(iocb) && 110 !is_sync_kiocb(iocb) &&
116 (file->f_flags & O_APPEND || 111 (file->f_flags & O_APPEND ||
117 ext4_unaligned_aio(inode, iov, nr_segs, pos))) { 112 ext4_unaligned_aio(inode, from, pos))) {
118 aio_mutex = ext4_aio_mutex(inode); 113 aio_mutex = ext4_aio_mutex(inode);
119 mutex_lock(aio_mutex); 114 mutex_lock(aio_mutex);
120 ext4_unwritten_wait(inode); 115 ext4_unwritten_wait(inode);
@@ -138,10 +133,8 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
138 goto errout; 133 goto errout;
139 } 134 }
140 135
141 if (pos + length > sbi->s_bitmap_maxbytes) { 136 if (pos + length > sbi->s_bitmap_maxbytes)
142 nr_segs = iov_shorten((struct iovec *)iov, nr_segs, 137 iov_iter_truncate(from, sbi->s_bitmap_maxbytes - pos);
143 sbi->s_bitmap_maxbytes - pos);
144 }
145 } 138 }
146 139
147 if (o_direct) { 140 if (o_direct) {
@@ -179,7 +172,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
179 } 172 }
180 } 173 }
181 174
182 ret = __generic_file_aio_write(iocb, iov, nr_segs); 175 ret = __generic_file_write_iter(iocb, from);
183 mutex_unlock(&inode->i_mutex); 176 mutex_unlock(&inode->i_mutex);
184 177
185 if (ret > 0) { 178 if (ret > 0) {
@@ -594,9 +587,9 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int whence)
594const struct file_operations ext4_file_operations = { 587const struct file_operations ext4_file_operations = {
595 .llseek = ext4_llseek, 588 .llseek = ext4_llseek,
596 .read = new_sync_read, 589 .read = new_sync_read,
597 .write = do_sync_write, 590 .write = new_sync_write,
598 .read_iter = generic_file_read_iter, 591 .read_iter = generic_file_read_iter,
599 .aio_write = ext4_file_write, 592 .write_iter = ext4_file_write_iter,
600 .unlocked_ioctl = ext4_ioctl, 593 .unlocked_ioctl = ext4_ioctl,
601#ifdef CONFIG_COMPAT 594#ifdef CONFIG_COMPAT
602 .compat_ioctl = ext4_compat_ioctl, 595 .compat_ioctl = ext4_compat_ioctl,