]> git.hungrycats.org Git - linux/commitdiff
Add infrastructure for the VFS layer to mark files seekable.
authorLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 7 Aug 2004 05:12:52 +0000 (22:12 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 7 Aug 2004 05:12:52 +0000 (22:12 -0700)
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.

fs/fifo.c
fs/file_table.c
fs/nfsd/nfs4state.c
fs/open.c
fs/pipe.c
fs/read_write.c
include/linux/fs.h
net/socket.c

index 7a6a018303d77c6b5094853a57ba67c58a0ffbe0..fcdc9952c71215f9b690eec18244049b48b3cf33 100644 (file)
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -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:
index 5d56ec5db141ebfc45be159712853a03cc29d8b2..8a4bd0398e34daf51dfa8ee0e4e5f16553136d79 100644 (file)
@@ -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;
index 4df0dedef709d079328c40731cb926a7be81eb2d..342003bd23d465153c9396c5042403cddcd8f563 100644 (file)
@@ -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;
        }
 }
 
index 854c5de744dbad3f735976b6594bba1705133bc6..098ac8d30db23d1cc7859999c9c9ac5c00889ba1 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -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);
index 737271c0c9b9e7f36c69932cdb539c5a4602110a..f0e16609595a5edc9fe3a0c3d23bfeb7f206c7c3 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -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);
index 481332642515c0a19e70f7da5b31743b7067cbda..6b226d11b6068889d588fbeb97835d1686144275 100644 (file)
@@ -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 = default_llseek;
-       if (file->f_op && file->f_op->llseek)
-               fn = file->f_op->llseek;
+       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,7 +313,9 @@ asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf,
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_read(file, buf, count, &pos);
+               ret = -ESPIPE;
+               if (file->f_mode & FMODE_LSEEK)
+                       ret = vfs_read(file, buf, count, &pos);
                fput_light(file, fput_needed);
        }
 
@@ -329,7 +334,9 @@ asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf,
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_write(file, buf, count, &pos);
+               ret = -ESPIPE;
+               if (file->f_mode & FMODE_LSEEK)  
+                       ret = vfs_write(file, buf, count, &pos);
                fput_light(file, fput_needed);
        }
 
index 22dd6acdf9f1f210c48e6fa126ebe2a18a9d77c2..44dbcaea3ebda27f5cd79ebdbbae589af29f2e37 100644 (file)
@@ -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
index 5bb81ec300e2078d10bccd2c05b49375bbb9cea4..58398204d92cd0d89ffb964ab85208b1c8dcc366 100644 (file)
@@ -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);