Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cff2b760 authored by Ulrich Drepper's avatar Ulrich Drepper Committed by Linus Torvalds
Browse files

[PATCH] fstatat64 support



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: default avatarUlrich Drepper <drepper@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 25bf368b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -299,7 +299,7 @@ ENTRY(sys_call_table)
	.long sys_mknodat
	.long sys_fchownat
	.long sys_futimesat
	.long sys_newfstatat		/* 300 */
	.long sys_fstatat64		/* 300 */
	.long sys_unlinkat
	.long sys_renameat
	.long sys_linkat
+1 −1
Original line number Diff line number Diff line
@@ -677,7 +677,7 @@ ia32_sys_call_table:
	.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
+22 −0
Original line number Diff line number Diff line
@@ -180,6 +180,28 @@ sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
	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
+22 −0
Original line number Diff line number Diff line
@@ -261,6 +261,7 @@ asmlinkage long sys_newlstat(char __user *filename, struct stat __user *statbuf)
	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 @@ asmlinkage long sys_newfstatat(int dfd, char __user *filename,
out:
	return error;
}
#endif

asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf)
{
@@ -395,6 +397,26 @@ asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf)
	return error;
}

asmlinkage long sys_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);

out:
	return error;
}
#endif /* __ARCH_WANT_STAT64 */

void inode_add_bytes(struct inode *inode, loff_t bytes)
+1 −1
Original line number Diff line number Diff line
@@ -305,7 +305,7 @@
#define __NR_mknodat		297
#define __NR_fchownat		298
#define __NR_futimesat		299
#define __NR_newfstatat		300
#define __NR_fstatat64		300
#define __NR_unlinkat		301
#define __NR_renameat		302
#define __NR_linkat		303
Loading