LWN.net Logo

Add infrastructure for the VFS layer to mark files seekable.

From:  Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
To:  bk-commits-head@vger.kernel.org
Subject:  Add infrastructure for the VFS layer to mark files seekable.
Date:  Sat, 07 Aug 2004 19:12:52 +0000

ChangeSet 1.1903, 2004/08/07 12:12:52-07:00, torvalds@ppc970.osdl.org

	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.



 fs/fifo.c           |    1 +
 fs/file_table.c     |    2 +-
 fs/nfsd/nfs4state.c |    4 ++--
 fs/open.c           |    2 +-
 fs/pipe.c           |    4 ++--
 fs/read_write.c     |   17 ++++++++++++-----
 include/linux/fs.h  |    1 +
 net/socket.c        |    2 +-
 8 files changed, 21 insertions(+), 12 deletions(-)


diff -Nru a/fs/fifo.c b/fs/fifo.c
--- a/fs/fifo.c	2004-08-07 13:10:28 -07:00
+++ b/fs/fifo.c	2004-08-07 13:10:28 -07:00
@@ -44,6 +44,7 @@
 			goto err_nocleanup;
 	}
 	filp->f_version = 0;
+	filp->f_mode &= ~FMODE_LSEEK;
 
 	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 13:10:27 -07:00
+++ b/fs/file_table.c	2004-08-07 13:10:27 -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;
+	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;
diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
--- a/fs/nfsd/nfs4state.c	2004-08-07 13:10:28 -07:00
+++ b/fs/nfsd/nfs4state.c	2004-08-07 13:10:28 -07:00
@@ -1141,7 +1141,7 @@
 	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 @@
 {
 	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;
 	}
 }
 
diff -Nru a/fs/open.c b/fs/open.c
--- a/fs/open.c	2004-08-07 13:10:27 -07:00
+++ b/fs/open.c	2004-08-07 13:10:28 -07:00
@@ -781,7 +781,7 @@
 	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);
diff -Nru a/fs/pipe.c b/fs/pipe.c
--- a/fs/pipe.c	2004-08-07 13:10:28 -07:00
+++ b/fs/pipe.c	2004-08-07 13:10:28 -07:00
@@ -656,13 +656,13 @@
 	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);
diff -Nru a/fs/read_write.c b/fs/read_write.c
--- a/fs/read_write.c	2004-08-07 13:10:28 -07:00
+++ b/fs/read_write.c	2004-08-07 13:10:28 -07:00
@@ -113,9 +113,12 @@
 {
 	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 @@
 
 	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 @@
 
 	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);
 	}
 
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	2004-08-07 13:10:28 -07:00
+++ b/include/linux/fs.h	2004-08-07 13:10:28 -07:00
@@ -74,6 +74,7 @@
 
 #define FMODE_READ 1
 #define FMODE_WRITE 2
+#define FMODE_LSEEK 4	/* Internal kernel extension */
 
 #define RW_MASK		1
 #define RWA_MASK	2
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	2004-08-07 13:10:28 -07:00
+++ b/net/socket.c	2004-08-07 13:10:28 -07:00
@@ -401,7 +401,7 @@
 
 		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);
-
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

Copyright © 2004, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds