Commit 4a47ae69 authored by Linus Torvalds's avatar Linus Torvalds

Add infrastructure for the VFS layer to mark files seekable.

We use a FMODE_LSEEK flag to match the existing read/write
bits. This allows us to check for seekability on a VFS level
for lseek/pread/pwrite, and cleans things up.

Update some sites that used the numeric constants to use 
the symbolic values instead.
parent 7d95b6c7
......@@ -44,6 +44,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
goto err_nocleanup;
}
filp->f_version = 0;
filp->f_mode &= ~FMODE_LSEEK;
switch (filp->f_mode) {
case 1:
......
......@@ -117,7 +117,7 @@ int open_private_file(struct file *filp, struct dentry *dentry, int flags)
memset(filp, 0, sizeof(*filp));
eventpoll_init_file(filp);
filp->f_flags = flags;
filp->f_mode = (flags+1) & O_ACCMODE;
filp->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK;
atomic_set(&filp->f_count, 1);
filp->f_dentry = dentry;
filp->f_mapping = dentry->d_inode->i_mapping;
......
......@@ -1141,7 +1141,7 @@ int status;
if (share_access & NFS4_SHARE_ACCESS_WRITE) {
status = get_write_access(filp->f_dentry->d_inode);
if (!status)
filp->f_mode = FMODE_WRITE;
filp->f_mode = FMODE_WRITE | FMODE_LSEEK;
else
return nfserrno(status);
}
......@@ -1153,7 +1153,7 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
{
if (share_access & NFS4_SHARE_ACCESS_WRITE) {
put_write_access(filp->f_dentry->d_inode);
filp->f_mode = FMODE_READ;
filp->f_mode = FMODE_READ | FMODE_LSEEK;
}
}
......
......@@ -781,7 +781,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
if (!f)
goto cleanup_dentry;
f->f_flags = flags;
f->f_mode = (flags+1) & O_ACCMODE;
f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK;
inode = dentry->d_inode;
if (f->f_mode & FMODE_WRITE) {
error = get_write_access(inode);
......
......@@ -656,13 +656,13 @@ int do_pipe(int *fd)
f1->f_pos = f2->f_pos = 0;
f1->f_flags = O_RDONLY;
f1->f_op = &read_pipe_fops;
f1->f_mode = 1;
f1->f_mode = FMODE_READ;
f1->f_version = 0;
/* write file */
f2->f_flags = O_WRONLY;
f2->f_op = &write_pipe_fops;
f2->f_mode = 2;
f2->f_mode = FMODE_WRITE;
f2->f_version = 0;
fd_install(i, f1);
......
......@@ -113,9 +113,12 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int origin)
{
loff_t (*fn)(struct file *, loff_t, int);
fn = no_llseek;
if (file->f_mode & FMODE_LSEEK) {
fn = default_llseek;
if (file->f_op && file->f_op->llseek)
fn = file->f_op->llseek;
}
return fn(file, offset, origin);
}
EXPORT_SYMBOL(vfs_llseek);
......@@ -310,6 +313,8 @@ asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf,
file = fget_light(fd, &fput_needed);
if (file) {
ret = -ESPIPE;
if (file->f_mode & FMODE_LSEEK)
ret = vfs_read(file, buf, count, &pos);
fput_light(file, fput_needed);
}
......@@ -329,6 +334,8 @@ asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf,
file = fget_light(fd, &fput_needed);
if (file) {
ret = -ESPIPE;
if (file->f_mode & FMODE_LSEEK)
ret = vfs_write(file, buf, count, &pos);
fput_light(file, fput_needed);
}
......
......@@ -74,6 +74,7 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
#define FMODE_READ 1
#define FMODE_WRITE 2
#define FMODE_LSEEK 4 /* Internal kernel extension */
#define RW_MASK 1
#define RWA_MASK 2
......
......@@ -401,7 +401,7 @@ int sock_map_fd(struct socket *sock)
sock->file = file;
file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
file->f_mode = 3;
file->f_mode = FMODE_READ | FMODE_WRITE;
file->f_flags = O_RDWR;
file->f_pos = 0;
fd_install(fd, file);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment