[PATCH] fstatat64 support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The *at patches introduced fstatat and, due to inusfficient research, I
used the newfstat functions generally as the guideline.  The result is
that on 32-bit platforms we don't have all the information needed to
implement fstatat64.

This patch modifies the code to pass up 64-bit information if
__ARCH_WANT_STAT64 is defined.  I renamed the syscall entry point to
make this clear.  Other archs will continue to use the existing code.
On x86-64 the compat code is implemented using a new sys32_ function.
this is what is done for the other stat syscalls as well.


This patch might break some other archs (those which define
__ARCH_WANT_STAT64 and which already wired up the syscall).  Yet
others might need changes to accomodate the compatibility mode.
I really don't want to do that work because all this stat handling
is a mess (more so in glibc, but the kernel is also affected).  It
should be done by the arch maintainers.  I'll provide some
stand-alone test shortly.  Those who are eager could compile glibc
and run 'make check' (no installation needed).


The patch below has been tested on x86 and x86-64.


Signed-off-by: Ulrich Drepper <[email protected]>


--- linux-2.6.15.i686/arch/i386/kernel/syscall_table.S-at	2006-02-06 13:11:24.000000000 -0800
+++ linux-2.6.15.i686/arch/i386/kernel/syscall_table.S	2006-02-06 13:11:34.000000000 -0800
@@ -299,7 +299,7 @@
 	.long sys_mknodat
 	.long sys_fchownat
 	.long sys_futimesat
-	.long sys_newfstatat		/* 300 */
+	.long sys_newfstatat64		/* 300 */
 	.long sys_unlinkat
 	.long sys_renameat
 	.long sys_linkat
--- linux-2.6.15.i686/arch/x86_64/ia32/ia32entry.S-at	2006-02-06 13:05:04.000000000 -0800
+++ linux-2.6.15.i686/arch/x86_64/ia32/ia32entry.S	2006-02-06 13:05:21.000000000 -0800
@@ -677,7 +677,7 @@
 	.quad sys_mknodat
 	.quad sys_fchownat
 	.quad compat_sys_futimesat
-	.quad compat_sys_newfstatat	/* 300 */
+	.quad sys32_fstatat		/* 300 */
 	.quad sys_unlinkat
 	.quad sys_renameat
 	.quad sys_linkat
--- linux-2.6.15.i686/arch/x86_64/ia32/sys_ia32.c-at	2006-02-06 13:05:37.000000000 -0800
+++ linux-2.6.15.i686/arch/x86_64/ia32/sys_ia32.c	2006-02-06 13:08:30.000000000 -0800
@@ -180,6 +180,28 @@
 	return ret;
 }
 
+asmlinkage long
+sys32_fstatat(unsigned 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_stat64(statbuf, &stat);
+
+out:
+	return error;
+}
+
 /*
  * Linux/i386 didn't use to be able to handle more than
  * 4 system call parameters, so these system calls used a memory
--- linux-2.6.15.i686/fs/stat.c-at	2006-02-06 12:55:52.000000000 -0800
+++ linux-2.6.15.i686/fs/stat.c	2006-02-06 13:13:43.000000000 -0800
@@ -261,6 +261,7 @@
 	return error;
 }
 
+#ifndef __ARCH_WANT_STAT64
 asmlinkage long sys_newfstatat(int dfd, char __user *filename,
 				struct stat __user *statbuf, int flag)
 {
@@ -281,6 +282,7 @@
 out:
 	return error;
 }
+#endif
 
 asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf)
 {
@@ -395,6 +397,26 @@
 	return error;
 }
 
+asmlinkage long sys_newfstatat64(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);
+
+out:
+	return error;
+}
 #endif /* __ARCH_WANT_STAT64 */
 
 void inode_add_bytes(struct inode *inode, loff_t bytes)
--- linux-2.6.15.i686/include/asm-i386/unistd.h-at	2006-02-06 13:16:26.000000000 -0800
+++ linux-2.6.15.i686/include/asm-i386/unistd.h	2006-02-06 13:16:42.000000000 -0800
@@ -305,7 +305,7 @@
 #define __NR_mknodat		297
 #define __NR_fchownat		298
 #define __NR_futimesat		299
-#define __NR_newfstatat		300
+#define __NR_newfstatat64	300
 #define __NR_unlinkat		301
 #define __NR_renameat		302
 #define __NR_linkat		303
--- linux-2.6.15.i686/include/asm-x86_64/ia32_unistd.h-at	2006-02-06 13:16:51.000000000 -0800
+++ linux-2.6.15.i686/include/asm-x86_64/ia32_unistd.h	2006-02-06 13:17:00.000000000 -0800
@@ -305,7 +305,7 @@
 #define __NR_ia32_mknodat		297
 #define __NR_ia32_fchownat		298
 #define __NR_ia32_futimesat		299
-#define __NR_ia32_newfstatat		300
+#define __NR_ia32_newfstatat64		300
 #define __NR_ia32_unlinkat		301
 #define __NR_ia32_renameat		302
 #define __NR_ia32_linkat		303
--- linux-2.6.15.i686/include/linux/syscalls.h-at	2006-02-06 12:56:58.000000000 -0800
+++ linux-2.6.15.i686/include/linux/syscalls.h	2006-02-06 13:14:15.000000000 -0800
@@ -557,6 +557,8 @@
 			   int mode);
 asmlinkage long sys_newfstatat(int dfd, char __user *filename,
 			       struct stat __user *statbuf, int flag);
+asmlinkage long sys_newfstatat64(int dfd, char __user *filename,
+				 struct stat64 __user *statbuf, int flag);
 asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf,
 			       int bufsiz);
 asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename,
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux