--- /dev/null
+--- linux-2.4.24orig/include/linux/fs.h.orig 2006-07-21 13:03:15.000000000 +0300\r
++++ linux-2.4.24/include/linux/fs.h 2006-07-21 13:03:46.000000000 +0300\r
+@@ -1128,6 +1128,8 @@ extern int open_namei_it(const char *fil\r
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,\r
+ int flags, struct lookup_intent *it);\r
+ extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);\r
++struct dentry * lookup_one_len_getattr(const char * name, struct dentry * base,\r
++ int len);\r
+ extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,\r
+ struct lookup_intent *it);\r
+ extern int filp_close(struct file *, fl_owner_t id);\r
+--- linux-2.4.24orig/fs/nfsd/vfs.c.orig 2006-07-21 12:52:07.000000000 +0300\r
++++ linux-2.4.24/fs/nfsd/vfs.c 2006-07-21 13:28:15.000000000 +0300\r
+@@ -198,6 +198,30 @@ int revalidate_it(struct dentry *dentry,\r
+ return err;\r
+ }\r
+ \r
++struct dentry * lookup_one_len_getattr(const char * name, struct dentry * base,\r
++ int len)\r
++{\r
++ struct lookup_intent it;\r
++ struct dentry *de;\r
++\r
++ intent_init(&it, IT_GETATTR, 0);\r
++\r
++ de = lookup_one_len_it(name, base, len, NULL);\r
++\r
++ if (!IS_ERR(de) && de->d_inode) {\r
++ if (de->d_inode->i_op && de->d_inode->i_op->revalidate_it)\r
++ de->d_inode->i_op->revalidate_it(de, &it);\r
++ else if (de->d_inode->i_op && de->d_inode->i_op->revalidate)\r
++ de->d_inode->i_op->revalidate(de);\r
++ }\r
++\r
++ if (it.it_op_release)\r
++ intent_release(&it);\r
++\r
++ return de;\r
++}\r
++\r
++\r
+ /*\r
+ * Look up one component of a pathname.\r
+ * N.B. After this call _both_ fhp and resfh need an fh_put\r
+@@ -263,7 +287,7 @@ nfsd_lookup(struct svc_rqst *rqstp, stru\r
+ }\r
+ } else {\r
+ fh_lock(fhp);\r
+- dentry = lookup_one_len(name, dparent, len);\r
++ dentry = lookup_one_len_getattr(name, dparent, len);\r
+ err = PTR_ERR(dentry);\r
+ if (IS_ERR(dentry))\r
+ goto out_nfserr;\r
+--- linux-2.4.24orig/fs/nfsd/nfs3xdr.c.orig 2006-07-21 13:02:18.000000000 +0300\r
++++ linux-2.4.24/fs/nfsd/nfs3xdr.c 2006-07-21 13:02:29.000000000 +0300\r
+@@ -715,7 +715,7 @@ encode_entry(struct readdir_cd *cd, cons\r
+ dchild = dchild->d_parent;\r
+ dchild = dget(dchild);\r
+ } else\r
+- dchild = lookup_one_len(name, dparent,namlen);\r
++ dchild = lookup_one_len_getattr(name, dparent,namlen);\r
+ if (IS_ERR(dchild))\r
+ goto noexec;\r
+ if (fh_compose(&fh, exp, dchild, cd->dirfh) != 0 || !dchild->d_inode)\r
/* libc chown() will do extra check, and if the real owner is
* the same as the ones to set, it won't fall into kernel, so
* invoke syscall directly. */
- rc = syscall(SYS_chown, path, st->st_uid, st->st_gid);
+ rc = syscall(SYS_chown, path, -1, -1);
if (rc)
- err_msg("error: chown %s (%u,%u)",
- path, st->st_uid, st->st_gid);
+ err_msg("error: chown %s (%u,%u)", path);
+
+ rc = chmod(path, st->st_mode);
+ if (rc)
+ err_msg("error: chmod %s (%hu)", path, st->st_mode);
+
return rc;
}