diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-12 16:27:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-12 16:27:20 -0400 |
commit | 5f739e4a491ab63730ef3b7464171340c689fbff (patch) | |
tree | 0ebf797a2b43ebefac2e5d0ef113b12a57c2b964 | |
parent | a667cb7a94d48a483fb5d6006fe04a440f1a42ce (diff) | |
parent | 12e1e7af1a55b9f911025365af4c689b3933c22a (diff) |
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro:
"Assorted fixes (really no common topic here)"
* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
vfs: Make __vfs_write() static
vfs: fix preadv64v2 and pwritev64v2 compat syscalls with offset == -1
pipe: stop using ->can_merge
splice: don't merge into linked buffers
fs: move generic stat response attr handling to vfs_getattr_nosec
orangefs: don't reinitialize result_mask in ->getattr
fs/devpts: always delete dcache dentry-s in dput()
-rw-r--r-- | fs/devpts/inode.c | 1 | ||||
-rw-r--r-- | fs/orangefs/inode.c | 7 | ||||
-rw-r--r-- | fs/pipe.c | 32 | ||||
-rw-r--r-- | fs/read_write.c | 10 | ||||
-rw-r--r-- | fs/splice.c | 8 | ||||
-rw-r--r-- | fs/stat.c | 12 | ||||
-rw-r--r-- | include/linux/pipe_fs_i.h | 8 | ||||
-rw-r--r-- | kernel/relay.c | 1 | ||||
-rw-r--r-- | kernel/trace/trace.c | 2 | ||||
-rw-r--r-- | net/smc/smc_rx.c | 1 |
10 files changed, 52 insertions, 30 deletions
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index c53814539070..553a3f3300ae 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -455,6 +455,7 @@ devpts_fill_super(struct super_block *s, void *data, int silent) | |||
455 | s->s_blocksize_bits = 10; | 455 | s->s_blocksize_bits = 10; |
456 | s->s_magic = DEVPTS_SUPER_MAGIC; | 456 | s->s_magic = DEVPTS_SUPER_MAGIC; |
457 | s->s_op = &devpts_sops; | 457 | s->s_op = &devpts_sops; |
458 | s->s_d_op = &simple_dentry_operations; | ||
458 | s->s_time_gran = 1; | 459 | s->s_time_gran = 1; |
459 | 460 | ||
460 | error = -ENOMEM; | 461 | error = -ENOMEM; |
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index f038235c64bd..c3334eca18c7 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c | |||
@@ -261,11 +261,8 @@ int orangefs_getattr(const struct path *path, struct kstat *stat, | |||
261 | generic_fillattr(inode, stat); | 261 | generic_fillattr(inode, stat); |
262 | 262 | ||
263 | /* override block size reported to stat */ | 263 | /* override block size reported to stat */ |
264 | if (request_mask & STATX_SIZE) | 264 | if (!(request_mask & STATX_SIZE)) |
265 | stat->result_mask = STATX_BASIC_STATS; | 265 | stat->result_mask &= ~STATX_SIZE; |
266 | else | ||
267 | stat->result_mask = STATX_BASIC_STATS & | ||
268 | ~STATX_SIZE; | ||
269 | 266 | ||
270 | stat->attributes_mask = STATX_ATTR_IMMUTABLE | | 267 | stat->attributes_mask = STATX_ATTR_IMMUTABLE | |
271 | STATX_ATTR_APPEND; | 268 | STATX_ATTR_APPEND; |
@@ -225,8 +225,15 @@ void generic_pipe_buf_release(struct pipe_inode_info *pipe, | |||
225 | } | 225 | } |
226 | EXPORT_SYMBOL(generic_pipe_buf_release); | 226 | EXPORT_SYMBOL(generic_pipe_buf_release); |
227 | 227 | ||
228 | /* New data written to a pipe may be appended to a buffer with this type. */ | ||
228 | static const struct pipe_buf_operations anon_pipe_buf_ops = { | 229 | static const struct pipe_buf_operations anon_pipe_buf_ops = { |
229 | .can_merge = 1, | 230 | .confirm = generic_pipe_buf_confirm, |
231 | .release = anon_pipe_buf_release, | ||
232 | .steal = anon_pipe_buf_steal, | ||
233 | .get = generic_pipe_buf_get, | ||
234 | }; | ||
235 | |||
236 | static const struct pipe_buf_operations anon_pipe_buf_nomerge_ops = { | ||
230 | .confirm = generic_pipe_buf_confirm, | 237 | .confirm = generic_pipe_buf_confirm, |
231 | .release = anon_pipe_buf_release, | 238 | .release = anon_pipe_buf_release, |
232 | .steal = anon_pipe_buf_steal, | 239 | .steal = anon_pipe_buf_steal, |
@@ -234,13 +241,32 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = { | |||
234 | }; | 241 | }; |
235 | 242 | ||
236 | static const struct pipe_buf_operations packet_pipe_buf_ops = { | 243 | static const struct pipe_buf_operations packet_pipe_buf_ops = { |
237 | .can_merge = 0, | ||
238 | .confirm = generic_pipe_buf_confirm, | 244 | .confirm = generic_pipe_buf_confirm, |
239 | .release = anon_pipe_buf_release, | 245 | .release = anon_pipe_buf_release, |
240 | .steal = anon_pipe_buf_steal, | 246 | .steal = anon_pipe_buf_steal, |
241 | .get = generic_pipe_buf_get, | 247 | .get = generic_pipe_buf_get, |
242 | }; | 248 | }; |
243 | 249 | ||
250 | /** | ||
251 | * pipe_buf_mark_unmergeable - mark a &struct pipe_buffer as unmergeable | ||
252 | * @buf: the buffer to mark | ||
253 | * | ||
254 | * Description: | ||
255 | * This function ensures that no future writes will be merged into the | ||
256 | * given &struct pipe_buffer. This is necessary when multiple pipe buffers | ||
257 | * share the same backing page. | ||
258 | */ | ||
259 | void pipe_buf_mark_unmergeable(struct pipe_buffer *buf) | ||
260 | { | ||
261 | if (buf->ops == &anon_pipe_buf_ops) | ||
262 | buf->ops = &anon_pipe_buf_nomerge_ops; | ||
263 | } | ||
264 | |||
265 | static bool pipe_buf_can_merge(struct pipe_buffer *buf) | ||
266 | { | ||
267 | return buf->ops == &anon_pipe_buf_ops; | ||
268 | } | ||
269 | |||
244 | static ssize_t | 270 | static ssize_t |
245 | pipe_read(struct kiocb *iocb, struct iov_iter *to) | 271 | pipe_read(struct kiocb *iocb, struct iov_iter *to) |
246 | { | 272 | { |
@@ -378,7 +404,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) | |||
378 | struct pipe_buffer *buf = pipe->bufs + lastbuf; | 404 | struct pipe_buffer *buf = pipe->bufs + lastbuf; |
379 | int offset = buf->offset + buf->len; | 405 | int offset = buf->offset + buf->len; |
380 | 406 | ||
381 | if (buf->ops->can_merge && offset + chars <= PAGE_SIZE) { | 407 | if (pipe_buf_can_merge(buf) && offset + chars <= PAGE_SIZE) { |
382 | ret = pipe_buf_confirm(pipe, buf); | 408 | ret = pipe_buf_confirm(pipe, buf); |
383 | if (ret) | 409 | if (ret) |
384 | goto out; | 410 | goto out; |
diff --git a/fs/read_write.c b/fs/read_write.c index 30df848b7451..177ccc3d405a 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -478,8 +478,8 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t | |||
478 | return ret; | 478 | return ret; |
479 | } | 479 | } |
480 | 480 | ||
481 | ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, | 481 | static ssize_t __vfs_write(struct file *file, const char __user *p, |
482 | loff_t *pos) | 482 | size_t count, loff_t *pos) |
483 | { | 483 | { |
484 | if (file->f_op->write) | 484 | if (file->f_op->write) |
485 | return file->f_op->write(file, p, count, pos); | 485 | return file->f_op->write(file, p, count, pos); |
@@ -1238,6 +1238,9 @@ COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd, | |||
1238 | const struct compat_iovec __user *,vec, | 1238 | const struct compat_iovec __user *,vec, |
1239 | unsigned long, vlen, loff_t, pos, rwf_t, flags) | 1239 | unsigned long, vlen, loff_t, pos, rwf_t, flags) |
1240 | { | 1240 | { |
1241 | if (pos == -1) | ||
1242 | return do_compat_readv(fd, vec, vlen, flags); | ||
1243 | |||
1241 | return do_compat_preadv64(fd, vec, vlen, pos, flags); | 1244 | return do_compat_preadv64(fd, vec, vlen, pos, flags); |
1242 | } | 1245 | } |
1243 | #endif | 1246 | #endif |
@@ -1344,6 +1347,9 @@ COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd, | |||
1344 | const struct compat_iovec __user *,vec, | 1347 | const struct compat_iovec __user *,vec, |
1345 | unsigned long, vlen, loff_t, pos, rwf_t, flags) | 1348 | unsigned long, vlen, loff_t, pos, rwf_t, flags) |
1346 | { | 1349 | { |
1350 | if (pos == -1) | ||
1351 | return do_compat_writev(fd, vec, vlen, flags); | ||
1352 | |||
1347 | return do_compat_pwritev64(fd, vec, vlen, pos, flags); | 1353 | return do_compat_pwritev64(fd, vec, vlen, pos, flags); |
1348 | } | 1354 | } |
1349 | #endif | 1355 | #endif |
diff --git a/fs/splice.c b/fs/splice.c index 6489fb9436e4..3ee7e82df48f 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -138,7 +138,6 @@ error: | |||
138 | } | 138 | } |
139 | 139 | ||
140 | const struct pipe_buf_operations page_cache_pipe_buf_ops = { | 140 | const struct pipe_buf_operations page_cache_pipe_buf_ops = { |
141 | .can_merge = 0, | ||
142 | .confirm = page_cache_pipe_buf_confirm, | 141 | .confirm = page_cache_pipe_buf_confirm, |
143 | .release = page_cache_pipe_buf_release, | 142 | .release = page_cache_pipe_buf_release, |
144 | .steal = page_cache_pipe_buf_steal, | 143 | .steal = page_cache_pipe_buf_steal, |
@@ -156,7 +155,6 @@ static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe, | |||
156 | } | 155 | } |
157 | 156 | ||
158 | static const struct pipe_buf_operations user_page_pipe_buf_ops = { | 157 | static const struct pipe_buf_operations user_page_pipe_buf_ops = { |
159 | .can_merge = 0, | ||
160 | .confirm = generic_pipe_buf_confirm, | 158 | .confirm = generic_pipe_buf_confirm, |
161 | .release = page_cache_pipe_buf_release, | 159 | .release = page_cache_pipe_buf_release, |
162 | .steal = user_page_pipe_buf_steal, | 160 | .steal = user_page_pipe_buf_steal, |
@@ -326,7 +324,6 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
326 | EXPORT_SYMBOL(generic_file_splice_read); | 324 | EXPORT_SYMBOL(generic_file_splice_read); |
327 | 325 | ||
328 | const struct pipe_buf_operations default_pipe_buf_ops = { | 326 | const struct pipe_buf_operations default_pipe_buf_ops = { |
329 | .can_merge = 0, | ||
330 | .confirm = generic_pipe_buf_confirm, | 327 | .confirm = generic_pipe_buf_confirm, |
331 | .release = generic_pipe_buf_release, | 328 | .release = generic_pipe_buf_release, |
332 | .steal = generic_pipe_buf_steal, | 329 | .steal = generic_pipe_buf_steal, |
@@ -341,7 +338,6 @@ static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe, | |||
341 | 338 | ||
342 | /* Pipe buffer operations for a socket and similar. */ | 339 | /* Pipe buffer operations for a socket and similar. */ |
343 | const struct pipe_buf_operations nosteal_pipe_buf_ops = { | 340 | const struct pipe_buf_operations nosteal_pipe_buf_ops = { |
344 | .can_merge = 0, | ||
345 | .confirm = generic_pipe_buf_confirm, | 341 | .confirm = generic_pipe_buf_confirm, |
346 | .release = generic_pipe_buf_release, | 342 | .release = generic_pipe_buf_release, |
347 | .steal = generic_pipe_buf_nosteal, | 343 | .steal = generic_pipe_buf_nosteal, |
@@ -1606,6 +1602,8 @@ retry: | |||
1606 | */ | 1602 | */ |
1607 | obuf->flags &= ~PIPE_BUF_FLAG_GIFT; | 1603 | obuf->flags &= ~PIPE_BUF_FLAG_GIFT; |
1608 | 1604 | ||
1605 | pipe_buf_mark_unmergeable(obuf); | ||
1606 | |||
1609 | obuf->len = len; | 1607 | obuf->len = len; |
1610 | opipe->nrbufs++; | 1608 | opipe->nrbufs++; |
1611 | ibuf->offset += obuf->len; | 1609 | ibuf->offset += obuf->len; |
@@ -1680,6 +1678,8 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1680 | */ | 1678 | */ |
1681 | obuf->flags &= ~PIPE_BUF_FLAG_GIFT; | 1679 | obuf->flags &= ~PIPE_BUF_FLAG_GIFT; |
1682 | 1680 | ||
1681 | pipe_buf_mark_unmergeable(obuf); | ||
1682 | |||
1683 | if (obuf->len > len) | 1683 | if (obuf->len > len) |
1684 | obuf->len = len; | 1684 | obuf->len = len; |
1685 | 1685 | ||
@@ -45,11 +45,6 @@ void generic_fillattr(struct inode *inode, struct kstat *stat) | |||
45 | stat->ctime = inode->i_ctime; | 45 | stat->ctime = inode->i_ctime; |
46 | stat->blksize = i_blocksize(inode); | 46 | stat->blksize = i_blocksize(inode); |
47 | stat->blocks = inode->i_blocks; | 47 | stat->blocks = inode->i_blocks; |
48 | |||
49 | if (IS_NOATIME(inode)) | ||
50 | stat->result_mask &= ~STATX_ATIME; | ||
51 | if (IS_AUTOMOUNT(inode)) | ||
52 | stat->attributes |= STATX_ATTR_AUTOMOUNT; | ||
53 | } | 48 | } |
54 | EXPORT_SYMBOL(generic_fillattr); | 49 | EXPORT_SYMBOL(generic_fillattr); |
55 | 50 | ||
@@ -75,6 +70,13 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat, | |||
75 | stat->result_mask |= STATX_BASIC_STATS; | 70 | stat->result_mask |= STATX_BASIC_STATS; |
76 | request_mask &= STATX_ALL; | 71 | request_mask &= STATX_ALL; |
77 | query_flags &= KSTAT_QUERY_FLAGS; | 72 | query_flags &= KSTAT_QUERY_FLAGS; |
73 | |||
74 | /* allow the fs to override these if it really wants to */ | ||
75 | if (IS_NOATIME(inode)) | ||
76 | stat->result_mask &= ~STATX_ATIME; | ||
77 | if (IS_AUTOMOUNT(inode)) | ||
78 | stat->attributes |= STATX_ATTR_AUTOMOUNT; | ||
79 | |||
78 | if (inode->i_op->getattr) | 80 | if (inode->i_op->getattr) |
79 | return inode->i_op->getattr(path, stat, request_mask, | 81 | return inode->i_op->getattr(path, stat, request_mask, |
80 | query_flags); | 82 | query_flags); |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 5a3bb3b7c9ad..787d224ff43e 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -74,13 +74,6 @@ struct pipe_inode_info { | |||
74 | */ | 74 | */ |
75 | struct pipe_buf_operations { | 75 | struct pipe_buf_operations { |
76 | /* | 76 | /* |
77 | * This is set to 1, if the generic pipe read/write may coalesce | ||
78 | * data into an existing buffer. If this is set to 0, a new pipe | ||
79 | * page segment is always used for new data. | ||
80 | */ | ||
81 | int can_merge; | ||
82 | |||
83 | /* | ||
84 | * ->confirm() verifies that the data in the pipe buffer is there | 77 | * ->confirm() verifies that the data in the pipe buffer is there |
85 | * and that the contents are good. If the pages in the pipe belong | 78 | * and that the contents are good. If the pages in the pipe belong |
86 | * to a file system, we may need to wait for IO completion in this | 79 | * to a file system, we may need to wait for IO completion in this |
@@ -182,6 +175,7 @@ void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); | |||
182 | int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); | 175 | int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); |
183 | int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); | 176 | int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); |
184 | void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); | 177 | void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); |
178 | void pipe_buf_mark_unmergeable(struct pipe_buffer *buf); | ||
185 | 179 | ||
186 | extern const struct pipe_buf_operations nosteal_pipe_buf_ops; | 180 | extern const struct pipe_buf_operations nosteal_pipe_buf_ops; |
187 | 181 | ||
diff --git a/kernel/relay.c b/kernel/relay.c index 9e0f52375487..ade14fb7ce2e 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
@@ -1177,7 +1177,6 @@ static void relay_pipe_buf_release(struct pipe_inode_info *pipe, | |||
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static const struct pipe_buf_operations relay_pipe_buf_ops = { | 1179 | static const struct pipe_buf_operations relay_pipe_buf_ops = { |
1180 | .can_merge = 0, | ||
1181 | .confirm = generic_pipe_buf_confirm, | 1180 | .confirm = generic_pipe_buf_confirm, |
1182 | .release = relay_pipe_buf_release, | 1181 | .release = relay_pipe_buf_release, |
1183 | .steal = generic_pipe_buf_steal, | 1182 | .steal = generic_pipe_buf_steal, |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d7325eb1bc83..94ffc1c559d5 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -6023,7 +6023,6 @@ static void tracing_spd_release_pipe(struct splice_pipe_desc *spd, | |||
6023 | } | 6023 | } |
6024 | 6024 | ||
6025 | static const struct pipe_buf_operations tracing_pipe_buf_ops = { | 6025 | static const struct pipe_buf_operations tracing_pipe_buf_ops = { |
6026 | .can_merge = 0, | ||
6027 | .confirm = generic_pipe_buf_confirm, | 6026 | .confirm = generic_pipe_buf_confirm, |
6028 | .release = generic_pipe_buf_release, | 6027 | .release = generic_pipe_buf_release, |
6029 | .steal = generic_pipe_buf_steal, | 6028 | .steal = generic_pipe_buf_steal, |
@@ -7050,7 +7049,6 @@ static void buffer_pipe_buf_get(struct pipe_inode_info *pipe, | |||
7050 | 7049 | ||
7051 | /* Pipe buffer operations for a buffer. */ | 7050 | /* Pipe buffer operations for a buffer. */ |
7052 | static const struct pipe_buf_operations buffer_pipe_buf_ops = { | 7051 | static const struct pipe_buf_operations buffer_pipe_buf_ops = { |
7053 | .can_merge = 0, | ||
7054 | .confirm = generic_pipe_buf_confirm, | 7052 | .confirm = generic_pipe_buf_confirm, |
7055 | .release = buffer_pipe_buf_release, | 7053 | .release = buffer_pipe_buf_release, |
7056 | .steal = generic_pipe_buf_steal, | 7054 | .steal = generic_pipe_buf_steal, |
diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c index bbcf0fe4ae10..413a6abf227e 100644 --- a/net/smc/smc_rx.c +++ b/net/smc/smc_rx.c | |||
@@ -136,7 +136,6 @@ static int smc_rx_pipe_buf_nosteal(struct pipe_inode_info *pipe, | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static const struct pipe_buf_operations smc_pipe_ops = { | 138 | static const struct pipe_buf_operations smc_pipe_ops = { |
139 | .can_merge = 0, | ||
140 | .confirm = generic_pipe_buf_confirm, | 139 | .confirm = generic_pipe_buf_confirm, |
141 | .release = smc_rx_pipe_buf_release, | 140 | .release = smc_rx_pipe_buf_release, |
142 | .steal = smc_rx_pipe_buf_nosteal, | 141 | .steal = smc_rx_pipe_buf_nosteal, |