Separate out common fstatat code into vfs_fstatat
Oleg Drokin [Wed, 8 Apr 2009 16:05:42 +0000 (20:05 +0400)]
This is a version incorporating Christoph's suggestion.

Separate out common *fstatat functionality into a single function
instead of duplicating it all over the code.

Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

arch/arm/kernel/sys_oabi-compat.c
arch/s390/kernel/compat_linux.c
arch/sparc/kernel/sys_sparc32.c
arch/x86/ia32/sys_ia32.c
fs/compat.c
fs/stat.c
include/linux/fs.h

index e04173c..d59a0cd 100644 (file)
@@ -177,21 +177,12 @@ asmlinkage long sys_oabi_fstatat64(int dfd,
                                   int flag)
 {
        struct kstat stat;
-       int error = -EINVAL;
+       int error;
 
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-               goto out;
-
-       if (flag & AT_SYMLINK_NOFOLLOW)
-               error = vfs_lstat_fd(dfd, filename, &stat);
-       else
-               error = vfs_stat_fd(dfd, filename, &stat);
-
-       if (!error)
-       error = cp_oldabi_stat64(&stat, statbuf);
-
-out:
-       return error;
+       error = vfs_fstatat(dfd, filename, &stat, flag);
+       if (error)
+               return error;
+       return cp_oldabi_stat64(&stat, statbuf);
 }
 
 struct oabi_flock64 {
index 6cc87d8..002c70d 100644 (file)
@@ -702,20 +702,12 @@ asmlinkage long sys32_fstatat64(unsigned int dfd, char __user *filename,
                                struct stat64_emu31 __user* statbuf, int flag)
 {
        struct kstat stat;
-       int error = -EINVAL;
-
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-               goto out;
-
-       if (flag & AT_SYMLINK_NOFOLLOW)
-               error = vfs_lstat_fd(dfd, filename, &stat);
-       else
-               error = vfs_stat_fd(dfd, filename, &stat);
+       int error;
 
-       if (!error)
-               error = cp_stat64(statbuf, &stat);
-out:
-       return error;
+       error = vfs_fstatat(dfd, filename, &stat, flag);
+       if (error)
+               return error;
+       return cp_stat64(statbuf, &stat);
 }
 
 /*
index e800503..f5000a4 100644 (file)
@@ -206,21 +206,12 @@ asmlinkage long compat_sys_fstatat64(unsigned int dfd, char __user *filename,
                struct compat_stat64 __user * statbuf, int flag)
 {
        struct kstat stat;
-       int error = -EINVAL;
-
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-               goto out;
-
-       if (flag & AT_SYMLINK_NOFOLLOW)
-               error = vfs_lstat_fd(dfd, filename, &stat);
-       else
-               error = vfs_stat_fd(dfd, filename, &stat);
-
-       if (!error)
-               error = cp_compat_stat64(&stat, statbuf);
+       int error;
 
-out:
-       return error;
+       error = vfs_fstatat(dfd, filename, &stat, flag);
+       if (error)
+               return error;
+       return cp_compat_stat64(&stat, statbuf);
 }
 
 asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
index efac92f..085a8c3 100644 (file)
@@ -129,21 +129,12 @@ asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename,
                              struct stat64 __user *statbuf, int flag)
 {
        struct kstat stat;
-       int error = -EINVAL;
+       int error;
 
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-               goto out;
-
-       if (flag & AT_SYMLINK_NOFOLLOW)
-               error = vfs_lstat_fd(dfd, filename, &stat);
-       else
-               error = vfs_stat_fd(dfd, filename, &stat);
-
-       if (!error)
-               error = cp_stat64(statbuf, &stat);
-
-out:
-       return error;
+       error = vfs_fstatat(dfd, filename, &stat, flag);
+       if (error)
+               return error;
+       return cp_stat64(statbuf, &stat);
 }
 
 /*
index 3f84d5f..dda72e2 100644 (file)
@@ -204,21 +204,12 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename,
                struct compat_stat __user *statbuf, int flag)
 {
        struct kstat stat;
-       int error = -EINVAL;
-
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-               goto out;
-
-       if (flag & AT_SYMLINK_NOFOLLOW)
-               error = vfs_lstat_fd(dfd, filename, &stat);
-       else
-               error = vfs_stat_fd(dfd, filename, &stat);
-
-       if (!error)
-               error = cp_compat_stat(&stat, statbuf);
+       int error;
 
-out:
-       return error;
+       error = vfs_fstatat(dfd, filename, &stat, flag);
+       if (error)
+               return error;
+       return cp_compat_stat(&stat, statbuf);
 }
 #endif
 
index 2db740a..5471166 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -109,6 +109,24 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
 
 EXPORT_SYMBOL(vfs_fstat);
 
+int vfs_fstatat(int dfd, char __user *filename, struct kstat *stat, int flag)
+{
+       int error = -EINVAL;
+
+       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+               goto out;
+
+       if (flag & AT_SYMLINK_NOFOLLOW)
+               error = vfs_lstat_fd(dfd, filename, stat);
+       else
+               error = vfs_stat_fd(dfd, filename, stat);
+out:
+       return error;
+}
+
+EXPORT_SYMBOL(vfs_fstatat);
+
+
 #ifdef __ARCH_WANT_OLD_STAT
 
 /*
@@ -264,21 +282,12 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, char __user *, filename,
                struct stat __user *, statbuf, int, flag)
 {
        struct kstat stat;
-       int error = -EINVAL;
-
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-               goto out;
-
-       if (flag & AT_SYMLINK_NOFOLLOW)
-               error = vfs_lstat_fd(dfd, filename, &stat);
-       else
-               error = vfs_stat_fd(dfd, filename, &stat);
-
-       if (!error)
-               error = cp_new_stat(&stat, statbuf);
+       int error;
 
-out:
-       return error;
+       error = vfs_fstatat(dfd, filename, &stat, flag);
+       if (error)
+               return error;
+       return cp_new_stat(&stat, statbuf);
 }
 #endif
 
@@ -404,21 +413,12 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename,
                struct stat64 __user *, statbuf, int, flag)
 {
        struct kstat stat;
-       int error = -EINVAL;
-
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-               goto out;
-
-       if (flag & AT_SYMLINK_NOFOLLOW)
-               error = vfs_lstat_fd(dfd, filename, &stat);
-       else
-               error = vfs_stat_fd(dfd, filename, &stat);
-
-       if (!error)
-               error = cp_new_stat64(&stat, statbuf);
+       int error;
 
-out:
-       return error;
+       error = vfs_fstatat(dfd, filename, &stat, flag);
+       if (error)
+               return error;
+       return cp_new_stat64(&stat, statbuf);
 }
 #endif /* __ARCH_WANT_STAT64 */
 
index e766be0..257f4d3 100644 (file)
@@ -2302,6 +2302,7 @@ 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_fstatat(int , char __user *, struct kstat *, int);
 
 extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                    unsigned long arg);