fs/nfs/dir.c | 8 +++++++- fs/nfs/inode.c | 2 +- fs/nfs/nfs3proc.c | 7 ++++--- fs/nfs/nfs4proc.c | 18 +++++++++++------- fs/nfs/proc.c | 7 ++++--- include/linux/nfs_xdr.h | 3 ++- 6 files changed, 29 insertions(+), 16 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.8-32-fix_create/fs/nfs/dir.c linux-2.6.8-33-getattr/fs/nfs/dir.c --- linux-2.6.8-32-fix_create/fs/nfs/dir.c 2004-08-09 22:50:35.000000000 -0700 +++ linux-2.6.8-33-getattr/fs/nfs/dir.c 2004-08-09 23:06:23.000000000 -0700 @@ -982,12 +982,18 @@ static int nfs_instantiate(struct dentry /* We may have been initialized further down */ if (dentry->d_inode) return 0; - if (fhandle->size == 0 || !(fattr->valid & NFS_ATTR_FATTR)) { + if (fhandle->size == 0) { struct inode *dir = dentry->d_parent->d_inode; error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); if (error) goto out_err; } + if (!(fattr->valid & NFS_ATTR_FATTR)) { + struct nfs_server *server = NFS_SB(dentry->d_sb); + error = server->rpc_ops->getattr(server, fhandle, fattr); + if (error < 0) + goto out_err; + } inode = nfs_fhget(dentry->d_sb, fhandle, fattr); if (inode) { d_instantiate(dentry, inode); diff -u --recursive --new-file --show-c-function linux-2.6.8-32-fix_create/fs/nfs/inode.c linux-2.6.8-33-getattr/fs/nfs/inode.c --- linux-2.6.8-32-fix_create/fs/nfs/inode.c 2004-08-09 22:51:28.000000000 -0700 +++ linux-2.6.8-33-getattr/fs/nfs/inode.c 2004-08-09 22:54:51.000000000 -0700 @@ -961,7 +961,7 @@ __nfs_revalidate_inode(struct nfs_server /* Protect against RPC races by saving the change attribute */ verifier = nfs_save_change_attribute(inode); - status = NFS_PROTO(inode)->getattr(inode, &fattr); + status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); if (status) { dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", inode->i_sb->s_id, diff -u --recursive --new-file --show-c-function linux-2.6.8-32-fix_create/fs/nfs/nfs3proc.c linux-2.6.8-33-getattr/fs/nfs/nfs3proc.c --- linux-2.6.8-32-fix_create/fs/nfs/nfs3proc.c 2004-08-09 22:51:28.000000000 -0700 +++ linux-2.6.8-33-getattr/fs/nfs/nfs3proc.c 2004-08-09 22:57:20.000000000 -0700 @@ -92,14 +92,15 @@ nfs3_proc_get_root(struct nfs_server *se * One function for each procedure in the NFS protocol. */ static int -nfs3_proc_getattr(struct inode *inode, struct nfs_fattr *fattr) +nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fattr *fattr) { int status; dprintk("NFS call getattr\n"); fattr->valid = 0; - status = rpc_call(NFS_CLIENT(inode), NFS3PROC_GETATTR, - NFS_FH(inode), fattr, 0); + status = rpc_call(server->client, NFS3PROC_GETATTR, + fhandle, fattr, 0); dprintk("NFS reply getattr\n"); return status; } diff -u --recursive --new-file --show-c-function linux-2.6.8-32-fix_create/fs/nfs/nfs4proc.c linux-2.6.8-33-getattr/fs/nfs/nfs4proc.c --- linux-2.6.8-32-fix_create/fs/nfs/nfs4proc.c 2004-08-09 22:51:28.000000000 -0700 +++ linux-2.6.8-33-getattr/fs/nfs/nfs4proc.c 2004-08-09 23:06:15.000000000 -0700 @@ -305,6 +305,11 @@ static int _nfs4_do_open(struct inode *d if (status) goto out_err; update_changeattr(dir, &o_res.cinfo); + if (!(f_attr.valid & NFS_ATTR_FATTR)) { + status = server->rpc_ops->getattr(server, &o_res.fh, &f_attr); + if (status < 0) + goto out_err; + } status = -ENOMEM; inode = nfs_fhget(dir->i_sb, &o_res.fh, &f_attr); @@ -734,11 +739,10 @@ out: return status; } -static int _nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr) +static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { - struct nfs_server *server = NFS_SERVER(inode); struct nfs4_getattr_arg args = { - .fh = NFS_FH(inode), + .fh = fhandle, .bitmask = server->attr_bitmask, }; struct nfs4_getattr_res res = { @@ -752,16 +756,16 @@ static int _nfs4_proc_getattr(struct ino }; fattr->valid = 0; - return rpc_call_sync(NFS_CLIENT(inode), &msg, 0); + return rpc_call_sync(server->client, &msg, 0); } -static int nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr) +static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { struct nfs4_exception exception = { }; int err; do { - err = nfs4_handle_exception(NFS_SERVER(inode), - _nfs4_proc_getattr(inode, fattr), + err = nfs4_handle_exception(server, + _nfs4_proc_getattr(server, fhandle, fattr), &exception); } while (exception.retry); return err; diff -u --recursive --new-file --show-c-function linux-2.6.8-32-fix_create/fs/nfs/proc.c linux-2.6.8-33-getattr/fs/nfs/proc.c --- linux-2.6.8-32-fix_create/fs/nfs/proc.c 2004-08-09 22:51:28.000000000 -0700 +++ linux-2.6.8-33-getattr/fs/nfs/proc.c 2004-08-09 22:56:09.000000000 -0700 @@ -87,14 +87,15 @@ nfs_proc_get_root(struct nfs_server *ser * One function for each procedure in the NFS protocol. */ static int -nfs_proc_getattr(struct inode *inode, struct nfs_fattr *fattr) +nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fattr *fattr) { int status; dprintk("NFS call getattr\n"); fattr->valid = 0; - status = rpc_call(NFS_CLIENT(inode), NFSPROC_GETATTR, - NFS_FH(inode), fattr, 0); + status = rpc_call(server->client, NFSPROC_GETATTR, + fhandle, fattr, 0); dprintk("NFS reply getattr\n"); return status; } diff -u --recursive --new-file --show-c-function linux-2.6.8-32-fix_create/include/linux/nfs_xdr.h linux-2.6.8-33-getattr/include/linux/nfs_xdr.h --- linux-2.6.8-32-fix_create/include/linux/nfs_xdr.h 2004-08-09 22:51:37.000000000 -0700 +++ linux-2.6.8-33-getattr/include/linux/nfs_xdr.h 2004-08-09 22:53:49.000000000 -0700 @@ -669,7 +669,8 @@ struct nfs_rpc_ops { int (*getroot) (struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); - int (*getattr) (struct inode *, struct nfs_fattr *); + int (*getattr) (struct nfs_server *, struct nfs_fh *, + struct nfs_fattr *); int (*setattr) (struct dentry *, struct nfs_fattr *, struct iattr *); int (*lookup) (struct inode *, struct qstr *,