Saner handling of "lseek should fail with ESPIPE" - gets rid of
magical no_llseek thing and makes checks consistent. In particular, ad-hoc "can we do splice via internal pipe" checks got saner (and somewhat more permissive, which is what Jason had been after, AFAICT) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQqUNBr3gm4hGXdBJlZ7Krx/gZQ6wUCYug2xgAKCRBZ7Krx/gZQ 6wxWAQDqeg+xMq2FGPXmgjCa+Cp3PXH96Lp6f3hHzakIDx+t8gEAxvuiXAD22Mct 6S1SKuGj0iDIuM4L7hUiWTiY/bDXSAc= =3EC/ -----END PGP SIGNATURE----- Merge tag 'pull-work.lseek' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull vfs lseek updates from Al Viro: "Jason's lseek series. Saner handling of 'lseek should fail with ESPIPE' - this gets rid of the magical no_llseek thing and makes checks consistent. In particular, the ad-hoc "can we do splice via internal pipe" checks got saner (and somewhat more permissive, which is what Jason had been after, AFAICT)" * tag 'pull-work.lseek' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fs: remove no_llseek fs: check FMODE_LSEEK to control internal pipe splicing vfio: do not set FMODE_LSEEK flag dma-buf: remove useless FMODE_LSEEK flag fs: do not compare against ->llseek fs: clear or set FMODE_LSEEK based on llseek function
This commit is contained in:
commit
a782e86649
|
@ -914,3 +914,11 @@ Calling conventions for file_open_root() changed; now it takes struct path *
|
|||
instead of passing mount and dentry separately. For callers that used to
|
||||
pass <mnt, mnt->mnt_root> pair (i.e. the root of given mount), a new helper
|
||||
is provided - file_open_root_mnt(). In-tree users adjusted.
|
||||
|
||||
---
|
||||
|
||||
**mandatory**
|
||||
|
||||
no_llseek is gone; don't set .llseek to that - just leave it NULL instead.
|
||||
Checks for "does that file have llseek(2), or should it fail with ESPIPE"
|
||||
should be done by looking at FMODE_LSEEK in file->f_mode.
|
||||
|
|
|
@ -549,7 +549,6 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
|||
goto err_dmabuf;
|
||||
}
|
||||
|
||||
file->f_mode |= FMODE_LSEEK;
|
||||
dmabuf->file = file;
|
||||
|
||||
mutex_init(&dmabuf->lock);
|
||||
|
|
|
@ -552,8 +552,7 @@ EXPORT_SYMBOL(drm_release_noglobal);
|
|||
* Since events are used by the KMS API for vblank and page flip completion this
|
||||
* means all modern display drivers must use it.
|
||||
*
|
||||
* @offset is ignored, DRM events are read like a pipe. Therefore drivers also
|
||||
* must set the &file_operation.llseek to no_llseek(). Polling support is
|
||||
* @offset is ignored, DRM events are read like a pipe. Polling support is
|
||||
* provided by drm_poll().
|
||||
*
|
||||
* This function will only ever read a full event. Therefore userspace must
|
||||
|
|
|
@ -1132,7 +1132,7 @@ static struct file *vfio_device_open(struct vfio_device *device)
|
|||
* Appears to be missing by lack of need rather than
|
||||
* explicitly prevented. Now there's need.
|
||||
*/
|
||||
filep->f_mode |= (FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
|
||||
filep->f_mode |= (FMODE_PREAD | FMODE_PWRITE);
|
||||
|
||||
if (device->group->type == VFIO_NO_IOMMU)
|
||||
dev_warn(device->dev, "vfio-noiommu device opened by user "
|
||||
|
|
|
@ -816,9 +816,9 @@ static int __dump_skip(struct coredump_params *cprm, size_t nr)
|
|||
{
|
||||
static char zeroes[PAGE_SIZE];
|
||||
struct file *file = cprm->file;
|
||||
if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
|
||||
if (file->f_mode & FMODE_LSEEK) {
|
||||
if (dump_interrupted() ||
|
||||
file->f_op->llseek(file, nr, SEEK_CUR) < 0)
|
||||
vfs_llseek(file, nr, SEEK_CUR) < 0)
|
||||
return 0;
|
||||
cprm->pos += nr;
|
||||
return 1;
|
||||
|
|
|
@ -235,6 +235,8 @@ static struct file *alloc_file(const struct path *path, int flags,
|
|||
file->f_mapping = path->dentry->d_inode->i_mapping;
|
||||
file->f_wb_err = filemap_sample_wb_err(file->f_mapping);
|
||||
file->f_sb_err = file_sample_sb_err(file);
|
||||
if (fop->llseek)
|
||||
file->f_mode |= FMODE_LSEEK;
|
||||
if ((file->f_mode & FMODE_READ) &&
|
||||
likely(fop->read || fop->read_iter))
|
||||
file->f_mode |= FMODE_CAN_READ;
|
||||
|
|
|
@ -888,6 +888,8 @@ static int do_dentry_open(struct file *f,
|
|||
if ((f->f_mode & FMODE_WRITE) &&
|
||||
likely(f->f_op->write || f->f_op->write_iter))
|
||||
f->f_mode |= FMODE_CAN_WRITE;
|
||||
if ((f->f_mode & FMODE_LSEEK) && !f->f_op->llseek)
|
||||
f->f_mode &= ~FMODE_LSEEK;
|
||||
if (f->f_mapping->a_ops && f->f_mapping->a_ops->direct_IO)
|
||||
f->f_mode |= FMODE_CAN_ODIRECT;
|
||||
|
||||
|
|
|
@ -226,8 +226,7 @@ static int ovl_copy_up_data(struct ovl_fs *ofs, struct path *old,
|
|||
/* Couldn't clone, so now we try to copy the data */
|
||||
|
||||
/* Check if lower fs supports seek operation */
|
||||
if (old_file->f_mode & FMODE_LSEEK &&
|
||||
old_file->f_op->llseek)
|
||||
if (old_file->f_mode & FMODE_LSEEK)
|
||||
skip_hole = true;
|
||||
|
||||
while (len) {
|
||||
|
|
|
@ -227,12 +227,6 @@ loff_t noop_llseek(struct file *file, loff_t offset, int whence)
|
|||
}
|
||||
EXPORT_SYMBOL(noop_llseek);
|
||||
|
||||
loff_t no_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
return -ESPIPE;
|
||||
}
|
||||
EXPORT_SYMBOL(no_llseek);
|
||||
|
||||
loff_t default_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
|
@ -290,14 +284,9 @@ EXPORT_SYMBOL(default_llseek);
|
|||
|
||||
loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
loff_t (*fn)(struct file *, loff_t, int);
|
||||
|
||||
fn = no_llseek;
|
||||
if (file->f_mode & FMODE_LSEEK) {
|
||||
if (file->f_op->llseek)
|
||||
fn = file->f_op->llseek;
|
||||
}
|
||||
return fn(file, offset, whence);
|
||||
if (!(file->f_mode & FMODE_LSEEK))
|
||||
return -ESPIPE;
|
||||
return file->f_op->llseek(file, offset, whence);
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_llseek);
|
||||
|
||||
|
|
10
fs/splice.c
10
fs/splice.c
|
@ -814,17 +814,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
|
|||
{
|
||||
struct pipe_inode_info *pipe;
|
||||
long ret, bytes;
|
||||
umode_t i_mode;
|
||||
size_t len;
|
||||
int i, flags, more;
|
||||
|
||||
/*
|
||||
* We require the input being a regular file, as we don't want to
|
||||
* randomly drop data for eg socket -> socket splicing. Use the
|
||||
* piped splicing for that!
|
||||
* We require the input to be seekable, as we don't want to randomly
|
||||
* drop data for eg socket -> socket splicing. Use the piped splicing
|
||||
* for that!
|
||||
*/
|
||||
i_mode = file_inode(in)->i_mode;
|
||||
if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode)))
|
||||
if (unlikely(!(in->f_mode & FMODE_LSEEK)))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
|
|
@ -3152,7 +3152,7 @@ extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
|
|||
extern void
|
||||
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
|
||||
extern loff_t noop_llseek(struct file *file, loff_t offset, int whence);
|
||||
extern loff_t no_llseek(struct file *file, loff_t offset, int whence);
|
||||
#define no_llseek NULL
|
||||
extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize);
|
||||
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence);
|
||||
extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
|
||||
|
|
|
@ -81,10 +81,9 @@ static bool bpf_iter_support_resched(struct seq_file *seq)
|
|||
#define MAX_ITER_OBJECTS 1000000
|
||||
|
||||
/* bpf_seq_read, a customized and simpler version for bpf iterator.
|
||||
* no_llseek is assumed for this file.
|
||||
* The following are differences from seq_read():
|
||||
* . fixed buffer size (PAGE_SIZE)
|
||||
* . assuming no_llseek
|
||||
* . assuming NULL ->llseek()
|
||||
* . stop() may call bpf program, handling potential overflow there
|
||||
*/
|
||||
static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size,
|
||||
|
|
Loading…
Reference in New Issue