| From: |
| Linux Kernel Mailing List <linux-kernel@vger.kernel.org> |
| To: |
| bk-commits-head@vger.kernel.org |
| Subject: |
| Add pread/pwrite support bits to match the lseek bit. |
| Date: |
| Sat, 07 Aug 2004 23:08:23 +0000 |
ChangeSet 1.1939, 2004/08/07 16:08:23-07:00, torvalds@ppc970.osdl.org
Add pread/pwrite support bits to match the lseek bit.
This also removes the ESPIPE logic from pipes and seq_files,
since the VFS layer now supports it.
arch/mips/kernel/linux32.c | 7 +++++++
fs/fifo.c | 4 +++-
fs/file_table.c | 2 +-
fs/nfsd/nfs4state.c | 7 +++----
fs/open.c | 2 +-
fs/pipe.c | 8 --------
fs/read_write.c | 4 ++--
fs/seq_file.c | 6 +++---
include/linux/fs.h | 6 +++++-
9 files changed, 25 insertions(+), 21 deletions(-)
diff -Nru a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
--- a/arch/mips/kernel/linux32.c 2004-08-07 17:05:46 -07:00
+++ b/arch/mips/kernel/linux32.c 2004-08-07 17:05:46 -07:00
@@ -477,6 +477,9 @@
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);
@@ -509,6 +512,10 @@
if (!file->f_op || !(write = file->f_op->write))
goto out;
if (pos < 0)
+ goto out;
+
+ ret = -ESPIPE;
+ if (!(file->f_mode & FMODE_PWRITE))
goto out;
ret = write(file, buf, count, &pos);
diff -Nru a/fs/fifo.c b/fs/fifo.c
--- a/fs/fifo.c 2004-08-07 17:05:46 -07:00
+++ b/fs/fifo.c 2004-08-07 17:05:46 -07:00
@@ -44,7 +44,9 @@
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:
diff -Nru a/fs/file_table.c b/fs/file_table.c
--- a/fs/file_table.c 2004-08-07 17:05:46 -07:00
+++ b/fs/file_table.c 2004-08-07 17:05:46 -07:00
@@ -117,7 +117,7 @@
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;
diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
--- a/fs/nfsd/nfs4state.c 2004-08-07 17:05:46 -07:00
+++ b/fs/nfsd/nfs4state.c 2004-08-07 17:05:46 -07:00
@@ -1140,10 +1140,9 @@
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 @@
{
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;
}
}
diff -Nru a/fs/open.c b/fs/open.c
--- a/fs/open.c 2004-08-07 17:05:46 -07:00
+++ b/fs/open.c 2004-08-07 17:05:46 -07:00
@@ -781,7 +781,7 @@
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);
diff -Nru a/fs/pipe.c b/fs/pipe.c
--- a/fs/pipe.c 2004-08-07 17:05:46 -07:00
+++ b/fs/pipe.c 2004-08-07 17:05:46 -07:00
@@ -94,10 +94,6 @@
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))
@@ -186,10 +182,6 @@
int do_wakeup;
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. */
diff -Nru a/fs/read_write.c b/fs/read_write.c
--- a/fs/read_write.c 2004-08-07 17:05:46 -07:00
+++ b/fs/read_write.c 2004-08-07 17:05:46 -07:00
@@ -314,7 +314,7 @@
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 @@
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);
}
diff -Nru a/fs/seq_file.c b/fs/seq_file.c
--- a/fs/seq_file.c 2004-08-07 17:05:46 -07:00
+++ b/fs/seq_file.c 2004-08-07 17:05:46 -07:00
@@ -35,6 +35,9 @@
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);
@@ -53,9 +56,6 @@
size_t n;
void *p;
int err = 0;
-
- if (ppos != &file->f_pos)
- return -EPIPE;
down(&m->sem);
/* grab buffer if we didn't have one */
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h 2004-08-07 17:05:46 -07:00
+++ b/include/linux/fs.h 2004-08-07 17:05:46 -07:00
@@ -74,7 +74,11 @@
#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
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html