]> git.hungrycats.org Git - linux/commitdiff
Add pread/pwrite support bits to match the lseek bit.
authorLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 7 Aug 2004 09:08:23 +0000 (02:08 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 7 Aug 2004 09:08:23 +0000 (02:08 -0700)
This also removes the ESPIPE logic from pipes and seq_files,
since the VFS layer now supports it.

arch/mips/kernel/linux32.c
fs/fifo.c
fs/file_table.c
fs/nfsd/nfs4state.c
fs/open.c
fs/pipe.c
fs/read_write.c
fs/seq_file.c
include/linux/fs.h

index bcb3e0c5a3ec75d5c00dadf390888662d88dddd9..afd36307070a8b137fab41bb660c3b0ea5f1e377 100644 (file)
@@ -477,6 +477,9 @@ asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
                goto out;
        if (pos < 0)
                goto out;
+       ret = -ESPIPE;
+       if (!(file->f_mode & FMODE_PREAD))
+               goto out;
        ret = read(file, buf, count, &pos);
        if (ret > 0)
                dnotify_parent(file->f_dentry, DN_ACCESS);
@@ -511,6 +514,10 @@ asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
        if (pos < 0)
                goto out;
 
+       ret = -ESPIPE;
+       if (!(file->f_mode & FMODE_PWRITE))
+               goto out;
+
        ret = write(file, buf, count, &pos);
        if (ret > 0)
                dnotify_parent(file->f_dentry, DN_MODIFY);
index fcdc9952c71215f9b690eec18244049b48b3cf33..a045fa71630cd3090fea8512055eab101c531552 100644 (file)
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -44,7 +44,9 @@ static int fifo_open(struct inode *inode, struct file *filp)
                        goto err_nocleanup;
        }
        filp->f_version = 0;
-       filp->f_mode &= ~FMODE_LSEEK;
+
+       /* We can only do regular read/write on fifos */
+       filp->f_mode &= (FMODE_READ | FMODE_WRITE);
 
        switch (filp->f_mode) {
        case 1:
index 8a4bd0398e34daf51dfa8ee0e4e5f16553136d79..6e97427ff0d8fb39e84793f99f4c2c3be46086b2 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) | FMODE_LSEEK;
+       filp->f_mode   = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
        atomic_set(&filp->f_count, 1);
        filp->f_dentry = dentry;
        filp->f_mapping = dentry->d_inode->i_mapping;
index 342003bd23d465153c9396c5042403cddcd8f563..0ff4425cae9aba831f9817097411cca09408ecf5 100644 (file)
@@ -1140,10 +1140,9 @@ 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 | FMODE_LSEEK;
-               else
+               if (status)
                        return nfserrno(status);
+               filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ;
        }
        return nfs_ok;
 }
@@ -1153,7 +1152,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 | FMODE_LSEEK;
+               filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
        }
 }
 
index 098ac8d30db23d1cc7859999c9c9ac5c00889ba1..22d42e94fc18286833777176cb83c2e703b73c9d 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) | FMODE_LSEEK;
+       f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
        inode = dentry->d_inode;
        if (f->f_mode & FMODE_WRITE) {
                error = get_write_access(inode);
index f0e16609595a5edc9fe3a0c3d23bfeb7f206c7c3..2b42a25a414e465a1a3cb1cb2499dad7cfa0d794 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -94,10 +94,6 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
        struct iovec *iov = (struct iovec *)_iov;
        size_t total_len;
 
-       /* pread is not allowed on pipes. */
-       if (unlikely(ppos != &filp->f_pos))
-               return -ESPIPE;
-
        total_len = iov_length(iov, nr_segs);
        /* Null read succeeds. */
        if (unlikely(total_len == 0))
@@ -187,10 +183,6 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
        struct iovec *iov = (struct iovec *)_iov;
        size_t total_len;
 
-       /* pwrite is not allowed on pipes. */
-       if (unlikely(ppos != &filp->f_pos))
-               return -ESPIPE;
-
        total_len = iov_length(iov, nr_segs);
        /* Null write succeeds. */
        if (unlikely(total_len == 0))
index 6b226d11b6068889d588fbeb97835d1686144275..33ce2284c9d0861615331d87054f41978fed4efc 100644 (file)
@@ -314,7 +314,7 @@ 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)
+               if (file->f_mode & FMODE_PREAD)
                        ret = vfs_read(file, buf, count, &pos);
                fput_light(file, fput_needed);
        }
@@ -335,7 +335,7 @@ 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)  
+               if (file->f_mode & FMODE_PWRITE)  
                        ret = vfs_write(file, buf, count, &pos);
                fput_light(file, fput_needed);
        }
index 8bd7097f3cfb60a57bbb02211e2e26f89a4bfb9d..5a73e085fb4e53ff52e93ddad93ca6b737dfdb21 100644 (file)
@@ -35,6 +35,9 @@ int seq_open(struct file *file, struct seq_operations *op)
        sema_init(&p->sem, 1);
        p->op = op;
        file->private_data = p;
+
+       /* SEQ files support lseek, but not pread/pwrite */
+       file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
        return 0;
 }
 EXPORT_SYMBOL(seq_open);
@@ -54,9 +57,6 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
        void *p;
        int err = 0;
 
-       if (ppos != &file->f_pos)
-               return -EPIPE;
-
        down(&m->sem);
        /* grab buffer if we didn't have one */
        if (!m->buf) {
index 44dbcaea3ebda27f5cd79ebdbbae589af29f2e37..d352f86782589826d2fd4cabc7320efcb421a938 100644 (file)
@@ -74,7 +74,11 @@ 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 */
+
+/* Internal kernel extensions */
+#define FMODE_LSEEK    4
+#define FMODE_PREAD    8
+#define FMODE_PWRITE   FMODE_PREAD     /* These go hand in hand */
 
 #define RW_MASK                1
 #define RWA_MASK       2