--- ./fs/nfs/dir.c.orig 2005-07-29 13:51:50.000000000 +0200 +++ ./fs/nfs/dir.c 2005-07-29 13:54:08.000000000 +0200 @@ -706,6 +706,7 @@ struct nfs_fh fhandle; struct nfs_fattr fattr; unsigned long verifier; + struct rpc_groups fsg; parent = dget_parent(dentry); lock_kernel(); @@ -739,7 +740,9 @@ goto out_bad; verifier = nfs_save_change_attribute(dir); - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); + fsg.ngroups = 1; + fsg.groups[0] = dir->i_gid; + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr, &fsg); if (error) goto out_bad; if (nfs_compare_fh(NFS_FH(inode), &fhandle)) @@ -837,6 +840,7 @@ int error; struct nfs_fh fhandle; struct nfs_fattr fattr; + struct rpc_groups fsg; dfprintk(VFS, "NFS: lookup(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); @@ -860,7 +864,9 @@ if (nfs_is_exclusive_create(dir, nd)) goto no_entry; - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); + fsg.ngroups = 1; + fsg.groups[0] = dir->i_gid; + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr, &fsg); if (error == -ENOENT) goto no_entry; if (error < 0) { @@ -1077,7 +1083,7 @@ * Code common to create, mkdir, and mknod. */ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, - struct nfs_fattr *fattr) + struct nfs_fattr *fattr, struct rpc_groups *fsg) { struct inode *inode; int error = -EACCES; @@ -1087,7 +1093,7 @@ return 0; if (fhandle->size == 0) { struct inode *dir = dentry->d_parent->d_inode; - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, fsg); if (error) goto out_err; } @@ -1155,6 +1161,7 @@ { struct iattr attr; int status; + struct rpc_groups fsg = { 1, { dir->i_gid } }; dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); @@ -1167,7 +1174,7 @@ lock_kernel(); nfs_begin_data_update(dir); - status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev); + status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev, &fsg); nfs_end_data_update(dir); if (status != 0) goto out_err; @@ -1188,6 +1195,7 @@ { struct iattr attr; int error; + struct rpc_groups fsg = { 1, { dir->i_gid } }; dfprintk(VFS, "NFS: mkdir(%s/%ld, %s\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); @@ -1197,7 +1205,7 @@ lock_kernel(); nfs_begin_data_update(dir); - error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr); + error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr, &fsg); nfs_end_data_update(dir); if (error != 0) goto out_err; @@ -1388,6 +1396,7 @@ struct nfs_fh sym_fh; struct qstr qsymname; int error; + struct rpc_groups fsg = { 1, { dir->i_gid } }; dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name, symname); @@ -1413,7 +1422,7 @@ &attr, &sym_fh, &sym_attr); nfs_end_data_update(dir); if (!error) { - error = nfs_instantiate(dentry, &sym_fh, &sym_attr); + error = nfs_instantiate(dentry, &sym_fh, &sym_attr, &fsg); } else { if (error == -EEXIST) printk("nfs_proc_symlink: %s/%s already exists??\n", --- ./fs/nfs/nfs3proc.c.orig 2005-07-29 13:51:50.000000000 +0200 +++ ./fs/nfs/nfs3proc.c 2005-07-29 13:59:31.000000000 +0200 @@ -132,7 +132,8 @@ static int nfs3_proc_lookup(struct inode *dir, struct qstr *name, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) + struct nfs_fh *fhandle, struct nfs_fattr *fattr, + struct rpc_groups *fsg) { struct nfs_fattr dir_attr; struct nfs3_diropargs arg = { @@ -150,7 +151,7 @@ dprintk("NFS call lookup %s\n", name->name); dir_attr.valid = 0; fattr->valid = 0; - status = nfs3_rpc(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res); + status = nfs3_rpc(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, fsg); if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) status = nfs3_rpc(NFS_CLIENT(dir), NFS3PROC_GETATTR, fhandle, fattr); @@ -337,7 +338,7 @@ } if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, &fhandle, &fattr, fsg); if (status != 0) goto out; @@ -510,7 +511,8 @@ } static int -nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) +nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr, + struct rpc_groups *fsg) { struct nfs_fh fhandle; struct nfs_fattr fattr, dir_attr; @@ -534,11 +536,11 @@ sattr->ia_mode &= ~current->fs->umask; - status = nfs3_rpc(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res); + status = nfs3_rpc(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, fsg); nfs_refresh_inode(dir, &dir_attr); if (status != 0) goto out; - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, &fhandle, &fattr, fsg); if (status != 0) goto out; status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); @@ -616,7 +618,7 @@ static int nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, - dev_t rdev) + dev_t rdev, struct rpc_groups *fsg) { struct nfs_fh fh; struct nfs_fattr fattr, dir_attr; @@ -650,11 +652,11 @@ dir_attr.valid = 0; fattr.valid = 0; - status = nfs3_rpc(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res); + status = nfs3_rpc(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, fsg); nfs_refresh_inode(dir, &dir_attr); if (status != 0) goto out; - status = nfs_instantiate(dentry, &fh, &fattr); + status = nfs_instantiate(dentry, &fh, &fattr, fsg); if (status != 0) goto out; status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); --- ./fs/nfs/nfs4proc.c.orig 2005-07-29 13:51:50.000000000 +0200 +++ ./fs/nfs/nfs4proc.c 2005-07-29 13:54:08.000000000 +0200 @@ -1180,7 +1180,9 @@ return status; } -static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) +static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, + struct nfs_fh *fhandle, struct nfs_fattr *fattr, + struct rpc_groups *fsg) { struct nfs4_exception exception = { }; int err; @@ -1684,13 +1686,13 @@ status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (!status) { update_changeattr(dir, &res.dir_cinfo); - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, &fhandle, &fattr, NULL); } return status; } static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, - struct iattr *sattr) + struct iattr *sattr, struct rpc_groups *fsg) { struct nfs4_exception exception = { }; int err; @@ -1799,13 +1801,13 @@ status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (status == 0) { update_changeattr(dir, &res.dir_cinfo); - status = nfs_instantiate(dentry, &fh, &fattr); + status = nfs_instantiate(dentry, &fh, &fattr, NULL); } return status; } static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, - struct iattr *sattr, dev_t rdev) + struct iattr *sattr, dev_t rdev, struct rpc_groups *fsg) { struct nfs4_exception exception = { }; int err; --- ./fs/nfs/proc.c.orig 2005-07-29 13:51:50.000000000 +0200 +++ ./fs/nfs/proc.c 2005-07-29 13:54:08.000000000 +0200 @@ -147,7 +147,8 @@ static int nfs_proc_lookup(struct inode *dir, struct qstr *name, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) + struct nfs_fh *fhandle, struct nfs_fattr *fattr, + struct rpc_groups *fsg) { struct nfs_diropargs arg = { .fh = NFS_FH(dir), @@ -162,7 +163,7 @@ dprintk("NFS call lookup %s\n", name->name); fattr->valid = 0; - status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_LOOKUP, &arg, &res); + status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_LOOKUP, &arg, &res, fsg); dprintk("NFS reply lookup: %d\n", status); return status; } @@ -251,7 +252,7 @@ dprintk("NFS call create %s\n", dentry->d_name.name); status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, fsg); if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, &fhandle, &fattr, fsg); dprintk("NFS reply create: %d\n", status); return status; } @@ -261,7 +262,7 @@ */ static int nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, - dev_t rdev) + dev_t rdev, struct rpc_groups *fsg) { struct nfs_fh fhandle; struct nfs_fattr fattr; @@ -289,15 +290,15 @@ } fattr.valid = 0; - status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res); + status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, fsg); if (status == -EINVAL && S_ISFIFO(mode)) { sattr->ia_mode = mode; fattr.valid = 0; - status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res); + status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, fsg); } if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, &fhandle, &fattr, fsg); dprintk("NFS reply mknod: %d\n", status); return status; } @@ -408,7 +409,8 @@ } static int -nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) +nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr, + struct rpc_groups *fsg) { struct nfs_fh fhandle; struct nfs_fattr fattr; @@ -426,9 +428,9 @@ dprintk("NFS call mkdir %s\n", dentry->d_name.name); fattr.valid = 0; - status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res); + status = nfs2_rpc(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, fsg); if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); + status = nfs_instantiate(dentry, &fhandle, &fattr, fsg); dprintk("NFS reply mkdir: %d\n", status); return status; } --- ./include/linux/nfs_fs.h.orig 2005-07-29 11:23:51.000000000 +0200 +++ ./include/linux/nfs_fs.h 2005-07-29 13:54:08.000000000 +0200 @@ -363,7 +363,8 @@ extern struct file_operations nfs_dir_operations; extern struct dentry_operations nfs_dentry_operations; -extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); +extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, + struct nfs_fattr *fattr, struct rpc_groups *fsg); /* * linux/fs/nfs/symlink.c --- ./include/linux/nfs_xdr.h.orig 2005-07-29 13:51:50.000000000 +0200 +++ ./include/linux/nfs_xdr.h 2005-07-29 13:54:08.000000000 +0200 @@ -713,8 +713,8 @@ struct nfs_fattr *); int (*setattr) (struct dentry *, struct nfs_fattr *, struct iattr *); - int (*lookup) (struct inode *, struct qstr *, - struct nfs_fh *, struct nfs_fattr *); + int (*lookup) (struct inode *, struct qstr *, struct nfs_fh *, + struct nfs_fattr *, struct rpc_groups *); int (*access) (struct inode *, struct nfs_access_entry *); int (*readlink)(struct inode *, struct page *, unsigned int, unsigned int); @@ -733,12 +733,13 @@ int (*symlink) (struct inode *, struct qstr *, struct qstr *, struct iattr *, struct nfs_fh *, struct nfs_fattr *); - int (*mkdir) (struct inode *, struct dentry *, struct iattr *); + int (*mkdir) (struct inode *, struct dentry *, struct iattr *, + struct rpc_groups *); int (*rmdir) (struct inode *, struct qstr *); int (*readdir) (struct dentry *, struct rpc_cred *, u64, struct page *, unsigned int, int); int (*mknod) (struct inode *, struct dentry *, struct iattr *, - dev_t); + dev_t, struct rpc_groups *); int (*statfs) (struct nfs_server *, struct nfs_fh *, struct nfs_fsstat *); int (*fsinfo) (struct nfs_server *, struct nfs_fh *,