linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Attempt at "stat light" implementation
@ 2009-04-07  6:23 Oleg Drokin
  2009-04-07 10:23 ` Andreas Dilger
                   ` (3 more replies)
  0 siblings, 4 replies; 25+ messages in thread
From: Oleg Drokin @ 2009-04-07  6:23 UTC (permalink / raw)
  To: linux-fsdevel

[-- Attachment #1: Type: text/plain, Size: 1151 bytes --]

Hello!

  Just as we discussed earlier today, here is a simple version that should do everything we need.
  I have separated stat fields into arbitrary categories based on my idea of how this needs to be done,
  that could of course be refined in other ways if desired.
  Only x86* syscall tables updated for now and no 64bit syscalls (probably we don't need them anyway, just
  need to always return 64 bit structure).

  I quickly realized that perhaps we can use just one extra syscall for fstat, and stat/lstat could be
  implemented as statat with just current cwd, though I do not know how desirable that is.

  Also I though that it would be kind of useful to allow the bitmask to be compatible with existing statat
  flags usage so that we do not need a new statat.

  Also perhaps the ->getattr just needs a prototype change to accept the flags argument and if the FS cares
  about it - to use it, but I did not want to do this huge patch touching every FS right now if only to save
  my time should this approach to be determined as undesirable for one reason or another, so
  for now I add a ->getattr_light

  Any comments?

Bye,
    Oleg

[-- Attachment #2: stat_light.diff --]
[-- Type: text/plain, Size: 11379 bytes --]

--- ./arch/x86/ia32/ia32entry.S.orig	2009-04-07 01:49:27.000000000 -0400
+++ ./arch/x86/ia32/ia32entry.S	2009-04-07 01:52:44.000000000 -0400
@@ -828,4 +828,7 @@
 	.quad sys_dup3			/* 330 */
 	.quad sys_pipe2
 	.quad sys_inotify_init1
+	.quad sys_fstatlight
+	.quad sys_lstatlight
+	.quad sys_statlight
 ia32_syscall_end:
--- ./arch/x86/include/asm/unistd_32.h.orig	2009-04-07 01:26:02.000000000 -0400
+++ ./arch/x86/include/asm/unistd_32.h	2009-04-07 01:38:39.000000000 -0400
@@ -338,6 +338,9 @@
 #define __NR_dup3		330
 #define __NR_pipe2		331
 #define __NR_inotify_init1	332
+#define __NR_fstat_light	333
+#define __NR_lstat_light	334
+#define __NR_stat_light		335
 
 #ifdef __KERNEL__
 
--- ./arch/x86/include/asm/unistd_64.h.orig	2009-04-07 01:26:12.000000000 -0400
+++ ./arch/x86/include/asm/unistd_64.h	2009-04-07 01:53:40.000000000 -0400
@@ -653,7 +653,12 @@
 __SYSCALL(__NR_pipe2, sys_pipe2)
 #define __NR_inotify_init1			294
 __SYSCALL(__NR_inotify_init1, sys_inotify_init1)
-
+#define __NR_fstat_light			295
+__SYSCALL(__NR_fstat_light, sys_fstatlight)
+#define __NR_lstat_light			296
+__SYSCALL(__NR_lstat_light, sys_lstatlight)
+#define __NR_stat_light				297
+__SYSCALL(__NR_inotify_init1, sys_statlight)
 
 #ifndef __NO_STUBS
 #define __ARCH_WANT_OLD_READDIR
--- ./fs/stat.c.orig	2009-04-07 00:23:22.000000000 -0400
+++ ./fs/stat.c	2009-04-07 01:51:49.000000000 -0400
@@ -37,7 +37,8 @@
 
 EXPORT_SYMBOL(generic_fillattr);
 
-int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat,
+		unsigned int flags)
 {
 	struct inode *inode = dentry->d_inode;
 	int retval;
@@ -46,6 +47,9 @@
 	if (retval)
 		return retval;
 
+	if (inode->i_op->getattr_light)
+		return inode->i_op->getattr_light(mnt, dentry, stat, flags);
+
 	if (inode->i_op->getattr)
 		return inode->i_op->getattr(mnt, dentry, stat);
 
@@ -55,53 +59,56 @@
 
 EXPORT_SYMBOL(vfs_getattr);
 
-int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
+int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat,
+		unsigned int flags)
 {
 	struct path path;
 	int error;
 
 	error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path);
 	if (!error) {
-		error = vfs_getattr(path.mnt, path.dentry, stat);
+		error = vfs_getattr(path.mnt, path.dentry, stat, flags);
 		path_put(&path);
 	}
 	return error;
 }
 
-int vfs_stat(char __user *name, struct kstat *stat)
+int vfs_stat(char __user *name, struct kstat *stat, unsigned int flags)
 {
-	return vfs_stat_fd(AT_FDCWD, name, stat);
+	return vfs_stat_fd(AT_FDCWD, name, stat, flags);
 }
 
 EXPORT_SYMBOL(vfs_stat);
 
-int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
+int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat,
+		 unsigned int flags)
 {
 	struct path path;
 	int error;
 
 	error = user_path_at(dfd, name, 0, &path);
 	if (!error) {
-		error = vfs_getattr(path.mnt, path.dentry, stat);
+		error = vfs_getattr(path.mnt, path.dentry, stat, flags);
 		path_put(&path);
 	}
 	return error;
 }
 
-int vfs_lstat(char __user *name, struct kstat *stat)
+int vfs_lstat(char __user *name, struct kstat *stat, unsigned int flags)
 {
-	return vfs_lstat_fd(AT_FDCWD, name, stat);
+	return vfs_lstat_fd(AT_FDCWD, name, stat, flags);
 }
 
 EXPORT_SYMBOL(vfs_lstat);
 
-int vfs_fstat(unsigned int fd, struct kstat *stat)
+int vfs_fstat(unsigned int fd, struct kstat *stat, unsigned int flags)
 {
 	struct file *f = fget(fd);
 	int error = -EBADF;
 
 	if (f) {
-		error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
+		error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat,
+				    flags);
 		fput(f);
 	}
 	return error;
@@ -155,7 +162,7 @@
 SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -166,7 +173,7 @@
 SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -177,7 +184,7 @@
 SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -240,7 +247,7 @@
 SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -251,7 +258,7 @@
 SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -270,9 +277,9 @@
 		goto out;
 
 	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+		error = vfs_lstat_fd(dfd, filename, &stat, STAT_EVERYTHING);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -285,7 +292,43 @@
 SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
+
+	if (!error)
+		error = cp_new_stat(&stat, statbuf);
+
+	return error;
+}
+
+SYSCALL_DEFINE3(statlight, char __user *, filename,
+	        struct stat __user *, statbuf, unsigned int, flags)
+{
+	struct kstat stat;
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat, flags);
+
+	if (!error)
+		error = cp_new_stat(&stat, statbuf);
+
+	return error;
+}
+
+SYSCALL_DEFINE3(lstatlight, char __user *, filename,
+		struct stat __user *, statbuf, unsigned int, flags)
+{
+	struct kstat stat;
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat, flags);
+
+	if (!error)
+		error = cp_new_stat(&stat, statbuf);
+
+	return error;
+}
+
+SYSCALL_DEFINE3(fstatlight, unsigned int, fd, struct stat __user *, statbuf,
+		unsigned int, flags)
+{
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat, flags);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
@@ -370,7 +413,7 @@
 SYSCALL_DEFINE2(stat64, char __user *, filename, struct stat64 __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat(filename, &stat);
+	int error = vfs_stat(filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat64(&stat, statbuf);
@@ -381,7 +424,7 @@
 SYSCALL_DEFINE2(lstat64, char __user *, filename, struct stat64 __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat(filename, &stat);
+	int error = vfs_lstat(filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat64(&stat, statbuf);
@@ -392,7 +435,7 @@
 SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
 {
 	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
+	int error = vfs_fstat(fd, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat64(&stat, statbuf);
@@ -410,9 +453,9 @@
 		goto out;
 
 	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
+		error = vfs_lstat_fd(dfd, filename, &stat, STAT_EVERYTHING);
 	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+		error = vfs_stat_fd(dfd, filename, &stat, STAT_EVERYTHING);
 
 	if (!error)
 		error = cp_new_stat64(&stat, statbuf);
--- ./include/linux/fcntl.h.orig	2009-04-07 00:31:36.000000000 -0400
+++ ./include/linux/fcntl.h	2009-04-07 00:44:41.000000000 -0400
@@ -40,6 +40,14 @@
                                            unlinking file.  */
 #define AT_SYMLINK_FOLLOW	0x400   /* Follow symbolic links.  */
 
+/* Bits to define what fields the "stat light" syscall must fill in struct stat,
+ * should not intersect with abovr AT_* bits */
+#define STAT_NLINK	0x01000		/* nlink */
+#define STAT_TIMES	0x02000		/* atime, mtime, ctime */
+#define STAT_SIZE	0x04000		/* File size and blocks */
+#define STAT_ACCESS	0x08000		/* mode, user, group */
+#define STAT_EVERYTHING 0x0f000		/* Just a normal stat */
+
 #ifdef __KERNEL__
 
 #ifndef force_o_largefile
--- ./include/linux/fs.h.orig	2009-04-07 00:30:52.000000000 -0400
+++ ./include/linux/fs.h	2009-04-07 01:03:58.000000000 -0400
@@ -1354,6 +1354,8 @@
 	int (*permission) (struct inode *, int);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
+	int (*getattr_light) (struct vfsmount *mnt, struct dentry *,
+			      struct kstat *, unsigned int);
 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
@@ -2062,7 +2064,8 @@
 extern const struct inode_operations page_symlink_inode_operations;
 extern int generic_readlink(struct dentry *, char __user *, int);
 extern void generic_fillattr(struct inode *, struct kstat *);
-extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *,
+		       unsigned int);
 void inode_add_bytes(struct inode *inode, loff_t bytes);
 void inode_sub_bytes(struct inode *inode, loff_t bytes);
 loff_t inode_get_bytes(struct inode *inode);
@@ -2070,11 +2073,11 @@
 
 extern int vfs_readdir(struct file *, filldir_t, void *);
 
-extern int vfs_stat(char __user *, struct kstat *);
-extern int vfs_lstat(char __user *, struct kstat *);
-extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
-extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
-extern int vfs_fstat(unsigned int, struct kstat *);
+extern int vfs_stat(char __user *, struct kstat *, unsigned int);
+extern int vfs_lstat(char __user *, struct kstat *, unsigned int);
+extern int vfs_stat_fd(int dfd, char __user *, struct kstat *, unsigned int);
+extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *, unsigned int);
+extern int vfs_fstat(unsigned int, struct kstat *, unsigned int);
 
 extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 		    unsigned long arg);
--- ./include/linux/syscalls.h.orig	2009-04-07 01:18:06.000000000 -0400
+++ ./include/linux/syscalls.h	2009-04-07 01:57:34.000000000 -0400
@@ -304,6 +304,13 @@
 				struct stat __user *statbuf);
 asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf);
 asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf);
+asmlinkage long sys_fstatlight(unsigned int fd,
+			       struct stat __user *statbuf,
+			       unsigned int);
+asmlinkage long sys_statlight(char __user *filename,
+			      struct stat __user *statbuf, unsigned int);
+asmlinkage long sys_lstatlight(char __user *filename,
+			       struct stat __user *statbuf, unsigned int);
 #if BITS_PER_LONG == 32
 asmlinkage long sys_stat64(char __user *filename,
 				struct stat64 __user *statbuf);

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2009-04-12 20:55 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-07  6:23 Attempt at "stat light" implementation Oleg Drokin
2009-04-07 10:23 ` Andreas Dilger
2009-04-07 14:54   ` Oleg Drokin
2009-04-07 17:52     ` Christoph Hellwig
2009-04-07 15:22   ` jim owens
2009-04-07 15:38     ` Oleg Drokin
2009-04-07 16:20       ` jim owens
2009-04-07 17:32 ` Jamie Lokier
2009-04-07 17:38   ` Jeff Garzik
2009-04-07 17:56     ` Jamie Lokier
2009-04-07 18:21       ` Andreas Dilger
2009-04-07 19:30         ` Ulrich Drepper
2009-04-12 20:55           ` Jamie Lokier
2009-04-07 17:41   ` Oleg Drokin
2009-04-07 17:54     ` Jamie Lokier
2009-04-07 18:00       ` Oleg Drokin
2009-04-07 18:18     ` Andreas Dilger
2009-04-07 18:31     ` Nicholas Miell
2009-04-07 17:49 ` Christoph Hellwig
2009-04-07 17:56   ` Oleg Drokin
2009-04-07 18:28     ` Andreas Dilger
2009-04-07 18:50       ` Jamie Lokier
2009-04-07 19:48       ` Jeff Garzik
2009-04-07 19:47   ` Jeff Garzik
2009-04-07 20:18 ` Evgeniy Polyakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).