Skip to content

Commit 5f739e4

Browse files
committed
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()
2 parents a667cb7 + 12e1e7a commit 5f739e4

File tree

10 files changed

+52
-30
lines changed

10 files changed

+52
-30
lines changed

fs/devpts/inode.c

+1
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ devpts_fill_super(struct super_block *s, void *data, int silent)
455455
s->s_blocksize_bits = 10;
456456
s->s_magic = DEVPTS_SUPER_MAGIC;
457457
s->s_op = &devpts_sops;
458+
s->s_d_op = &simple_dentry_operations;
458459
s->s_time_gran = 1;
459460

460461
error = -ENOMEM;

fs/orangefs/inode.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,8 @@ int orangefs_getattr(const struct path *path, struct kstat *stat,
261261
generic_fillattr(inode, stat);
262262

263263
/* override block size reported to stat */
264-
if (request_mask & STATX_SIZE)
265-
stat->result_mask = STATX_BASIC_STATS;
266-
else
267-
stat->result_mask = STATX_BASIC_STATS &
268-
~STATX_SIZE;
264+
if (!(request_mask & STATX_SIZE))
265+
stat->result_mask &= ~STATX_SIZE;
269266

270267
stat->attributes_mask = STATX_ATTR_IMMUTABLE |
271268
STATX_ATTR_APPEND;

fs/pipe.c

+29-3
Original file line numberDiff line numberDiff line change
@@ -225,22 +225,48 @@ void generic_pipe_buf_release(struct pipe_inode_info *pipe,
225225
}
226226
EXPORT_SYMBOL(generic_pipe_buf_release);
227227

228+
/* New data written to a pipe may be appended to a buffer with this type. */
228229
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 = {
230237
.confirm = generic_pipe_buf_confirm,
231238
.release = anon_pipe_buf_release,
232239
.steal = anon_pipe_buf_steal,
233240
.get = generic_pipe_buf_get,
234241
};
235242

236243
static const struct pipe_buf_operations packet_pipe_buf_ops = {
237-
.can_merge = 0,
238244
.confirm = generic_pipe_buf_confirm,
239245
.release = anon_pipe_buf_release,
240246
.steal = anon_pipe_buf_steal,
241247
.get = generic_pipe_buf_get,
242248
};
243249

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+
244270
static ssize_t
245271
pipe_read(struct kiocb *iocb, struct iov_iter *to)
246272
{
@@ -378,7 +404,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
378404
struct pipe_buffer *buf = pipe->bufs + lastbuf;
379405
int offset = buf->offset + buf->len;
380406

381-
if (buf->ops->can_merge && offset + chars <= PAGE_SIZE) {
407+
if (pipe_buf_can_merge(buf) && offset + chars <= PAGE_SIZE) {
382408
ret = pipe_buf_confirm(pipe, buf);
383409
if (ret)
384410
goto out;

fs/read_write.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,8 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t
478478
return ret;
479479
}
480480

481-
ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
482-
loff_t *pos)
481+
static ssize_t __vfs_write(struct file *file, const char __user *p,
482+
size_t count, loff_t *pos)
483483
{
484484
if (file->f_op->write)
485485
return file->f_op->write(file, p, count, pos);
@@ -1238,6 +1238,9 @@ COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd,
12381238
const struct compat_iovec __user *,vec,
12391239
unsigned long, vlen, loff_t, pos, rwf_t, flags)
12401240
{
1241+
if (pos == -1)
1242+
return do_compat_readv(fd, vec, vlen, flags);
1243+
12411244
return do_compat_preadv64(fd, vec, vlen, pos, flags);
12421245
}
12431246
#endif
@@ -1344,6 +1347,9 @@ COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd,
13441347
const struct compat_iovec __user *,vec,
13451348
unsigned long, vlen, loff_t, pos, rwf_t, flags)
13461349
{
1350+
if (pos == -1)
1351+
return do_compat_writev(fd, vec, vlen, flags);
1352+
13471353
return do_compat_pwritev64(fd, vec, vlen, pos, flags);
13481354
}
13491355
#endif

fs/splice.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
138138
}
139139

140140
const struct pipe_buf_operations page_cache_pipe_buf_ops = {
141-
.can_merge = 0,
142141
.confirm = page_cache_pipe_buf_confirm,
143142
.release = page_cache_pipe_buf_release,
144143
.steal = page_cache_pipe_buf_steal,
@@ -156,7 +155,6 @@ static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe,
156155
}
157156

158157
static const struct pipe_buf_operations user_page_pipe_buf_ops = {
159-
.can_merge = 0,
160158
.confirm = generic_pipe_buf_confirm,
161159
.release = page_cache_pipe_buf_release,
162160
.steal = user_page_pipe_buf_steal,
@@ -326,7 +324,6 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
326324
EXPORT_SYMBOL(generic_file_splice_read);
327325

328326
const struct pipe_buf_operations default_pipe_buf_ops = {
329-
.can_merge = 0,
330327
.confirm = generic_pipe_buf_confirm,
331328
.release = generic_pipe_buf_release,
332329
.steal = generic_pipe_buf_steal,
@@ -341,7 +338,6 @@ static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe,
341338

342339
/* Pipe buffer operations for a socket and similar. */
343340
const struct pipe_buf_operations nosteal_pipe_buf_ops = {
344-
.can_merge = 0,
345341
.confirm = generic_pipe_buf_confirm,
346342
.release = generic_pipe_buf_release,
347343
.steal = generic_pipe_buf_nosteal,
@@ -1606,6 +1602,8 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
16061602
*/
16071603
obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
16081604

1605+
pipe_buf_mark_unmergeable(obuf);
1606+
16091607
obuf->len = len;
16101608
opipe->nrbufs++;
16111609
ibuf->offset += obuf->len;
@@ -1680,6 +1678,8 @@ static int link_pipe(struct pipe_inode_info *ipipe,
16801678
*/
16811679
obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
16821680

1681+
pipe_buf_mark_unmergeable(obuf);
1682+
16831683
if (obuf->len > len)
16841684
obuf->len = len;
16851685

fs/stat.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,6 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
4545
stat->ctime = inode->i_ctime;
4646
stat->blksize = i_blocksize(inode);
4747
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;
5348
}
5449
EXPORT_SYMBOL(generic_fillattr);
5550

@@ -75,6 +70,13 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
7570
stat->result_mask |= STATX_BASIC_STATS;
7671
request_mask &= STATX_ALL;
7772
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+
7880
if (inode->i_op->getattr)
7981
return inode->i_op->getattr(path, stat, request_mask,
8082
query_flags);

include/linux/pipe_fs_i.h

+1-7
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,6 @@ struct pipe_inode_info {
7373
* in fs/pipe.c for the pipe and generic variants of these hooks.
7474
*/
7575
struct pipe_buf_operations {
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-
8376
/*
8477
* ->confirm() verifies that the data in the pipe buffer is there
8578
* and that the contents are good. If the pages in the pipe belong
@@ -182,6 +175,7 @@ void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
182175
int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
183176
int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
184177
void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
178+
void pipe_buf_mark_unmergeable(struct pipe_buffer *buf);
185179

186180
extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
187181

kernel/relay.c

-1
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,6 @@ static void relay_pipe_buf_release(struct pipe_inode_info *pipe,
11771177
}
11781178

11791179
static const struct pipe_buf_operations relay_pipe_buf_ops = {
1180-
.can_merge = 0,
11811180
.confirm = generic_pipe_buf_confirm,
11821181
.release = relay_pipe_buf_release,
11831182
.steal = generic_pipe_buf_steal,

kernel/trace/trace.c

-2
Original file line numberDiff line numberDiff line change
@@ -6023,7 +6023,6 @@ static void tracing_spd_release_pipe(struct splice_pipe_desc *spd,
60236023
}
60246024

60256025
static const struct pipe_buf_operations tracing_pipe_buf_ops = {
6026-
.can_merge = 0,
60276026
.confirm = generic_pipe_buf_confirm,
60286027
.release = generic_pipe_buf_release,
60296028
.steal = generic_pipe_buf_steal,
@@ -7050,7 +7049,6 @@ static void buffer_pipe_buf_get(struct pipe_inode_info *pipe,
70507049

70517050
/* Pipe buffer operations for a buffer. */
70527051
static const struct pipe_buf_operations buffer_pipe_buf_ops = {
7053-
.can_merge = 0,
70547052
.confirm = generic_pipe_buf_confirm,
70557053
.release = buffer_pipe_buf_release,
70567054
.steal = generic_pipe_buf_steal,

net/smc/smc_rx.c

-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ static int smc_rx_pipe_buf_nosteal(struct pipe_inode_info *pipe,
136136
}
137137

138138
static const struct pipe_buf_operations smc_pipe_ops = {
139-
.can_merge = 0,
140139
.confirm = generic_pipe_buf_confirm,
141140
.release = smc_rx_pipe_buf_release,
142141
.steal = smc_rx_pipe_buf_nosteal,

0 commit comments

Comments
 (0)