
[ppc64] cp_compat_stat should copy nanosecond fields
  
Looks like glibc is using stat in some places, so we should modify
it to copy the nanosecond fields. Also speed up stat by only checking
the region once instead of each put_user call.


---

 arch/ppc64/kernel/sys_ppc32.c |   39 ++++++++++++++++++++-------------------
 include/asm-ppc64/compat.h    |    6 +++---
 2 files changed, 23 insertions(+), 22 deletions(-)

diff -puN arch/ppc64/kernel/sys_ppc32.c~ppc64-compat_stat arch/ppc64/kernel/sys_ppc32.c
--- 25/arch/ppc64/kernel/sys_ppc32.c~ppc64-compat_stat	2004-01-13 23:23:15.000000000 -0800
+++ 25-akpm/arch/ppc64/kernel/sys_ppc32.c	2004-01-13 23:23:15.000000000 -0800
@@ -746,30 +746,31 @@ int ppc32_select(u32 n, u32* inp, u32* o
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
 {
-	int err;
+	long err;
 
 	if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
 	    !new_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
-	err  = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
-	err |= put_user(stat->ino, &statbuf->st_ino);
-	err |= put_user(stat->mode, &statbuf->st_mode);
-	err |= put_user(stat->nlink, &statbuf->st_nlink);
-	err |= put_user(stat->uid, &statbuf->st_uid);
-	err |= put_user(stat->gid, &statbuf->st_gid);
-	err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
-	err |= put_user(stat->size, &statbuf->st_size);
-	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-	err |= put_user(0, &statbuf->__unused1);
-	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-	err |= put_user(0, &statbuf->__unused2);
-	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-	err |= put_user(0, &statbuf->__unused3);
-	err |= put_user(stat->blksize, &statbuf->st_blksize);
-	err |= put_user(stat->blocks, &statbuf->st_blocks);
-	err |= put_user(0, &statbuf->__unused4[0]);
-	err |= put_user(0, &statbuf->__unused4[1]);
+	err  = verify_area(VERIFY_WRITE, statbuf, sizeof(*statbuf));
+	err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
+	err |= __put_user(stat->ino, &statbuf->st_ino);
+	err |= __put_user(stat->mode, &statbuf->st_mode);
+	err |= __put_user(stat->nlink, &statbuf->st_nlink);
+	err |= __put_user(stat->uid, &statbuf->st_uid);
+	err |= __put_user(stat->gid, &statbuf->st_gid);
+	err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
+	err |= __put_user(stat->size, &statbuf->st_size);
+	err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime);
+	err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+	err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+	err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+	err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+	err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
+	err |= __put_user(stat->blksize, &statbuf->st_blksize);
+	err |= __put_user(stat->blocks, &statbuf->st_blocks);
+	err |= __put_user(0, &statbuf->__unused4[0]);
+	err |= __put_user(0, &statbuf->__unused4[1]);
 
 	return err;
 }
diff -puN include/asm-ppc64/compat.h~ppc64-compat_stat include/asm-ppc64/compat.h
--- 25/include/asm-ppc64/compat.h~ppc64-compat_stat	2004-01-13 23:23:15.000000000 -0800
+++ 25-akpm/include/asm-ppc64/compat.h	2004-01-13 23:23:15.000000000 -0800
@@ -53,11 +53,11 @@ struct compat_stat {
 	compat_off_t	st_blksize;
 	compat_off_t	st_blocks;
 	compat_time_t	st_atime;
-	u32		__unused1;
+	u32		st_atime_nsec;
 	compat_time_t	st_mtime;
-	u32		__unused2;
+	u32		st_mtime_nsec;
 	compat_time_t	st_ctime;
-	u32		__unused3;
+	u32		st_ctime_nsec;
 	u32		__unused4[2];
 };
 

_
