diff -u --recursive --new-file linux-2.2.18-lockd/fs/lockd/clntproc.c linux-2.2.18-inode/fs/lockd/clntproc.c --- linux-2.2.18-lockd/fs/lockd/clntproc.c Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/fs/lockd/clntproc.c Tue Dec 12 20:32:21 2000 @@ -46,13 +46,11 @@ { struct nlm_args *argp = &req->a_args; struct nlm_lock *lock = &argp->lock; - struct dentry *dentry = fl->fl_file->f_dentry; - struct nfs_fh *fh = NFS_FH(dentry); memset(argp, 0, sizeof(*argp)); nlmclnt_next_cookie(&argp->cookie); argp->state = nsm_local_state; - memcpy(&lock->fh, fh, sizeof(*fh)); + memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(lock->fh)); lock->caller = system_utsname.nodename; lock->oh.data = req->a_owner; lock->oh.len = sprintf(req->a_owner, "%d@%s", diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/dir.c linux-2.2.18-inode/fs/nfs/dir.c --- linux-2.2.18-lockd/fs/nfs/dir.c Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/fs/nfs/dir.c Tue Dec 12 20:32:21 2000 @@ -131,7 +131,7 @@ struct file *file = desc->file; struct dentry *dir = file->f_dentry; struct inode *inode = dir->d_inode; - struct nfs_fattr dir_attr; + struct rpc_cred *cred = nfs_file_cred(file); void *buffer = (void *)page_address(page); int plus = NFS_USE_READDIRPLUS(inode); int error; @@ -139,11 +139,9 @@ dfprintk(VFS, "NFS: nfs_readdir_filler() reading cookie %Lu into page %lu.\n", (long long)desc->entry->cookie, page->offset); again: - error = NFS_CALL(readdir, inode, (dir, &dir_attr, - nfs_file_cred(file), + error = NFS_PROTO(inode)->readdir(inode, cred, desc->entry->cookie, buffer, - NFS_SERVER(inode)->dtsize, plus)); - nfs_refresh_inode(inode, &dir_attr); + NFS_SERVER(inode)->dtsize, plus); /* We requested READDIRPLUS, but the server doesn't grok it */ if (desc->plus && error == -ENOTSUPP) { NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS; @@ -339,7 +337,7 @@ struct file *file = desc->file; struct dentry *dir = file->f_dentry; struct inode *inode = dir->d_inode; - struct nfs_fattr dir_attr; + struct rpc_cred *cred = nfs_file_cred(file); struct page *page = NULL; unsigned long cache_page; u32 *p; @@ -358,11 +356,8 @@ } page = page_cache_entry(cache_page); p = (u32 *)page_address(page); - status = NFS_CALL(readdir, inode, (dir, &dir_attr, - nfs_file_cred(file), - desc->target, p, - NFS_SERVER(inode)->dtsize, 0)); - nfs_refresh_inode(inode, &dir_attr); + status = NFS_PROTO(inode)->readdir(inode, cred, desc->target, p, + NFS_SERVER(inode)->dtsize, 0); if (status >= 0) { p = desc->decode(p, desc->entry, 0); if (IS_ERR(p)) @@ -521,11 +516,10 @@ */ static int nfs_lookup_revalidate(struct dentry * dentry, int flags) { - struct dentry *dir = dentry->d_parent; - struct inode *inode = dentry->d_inode, - *dir_i = dir->d_inode; + struct inode *dir = dentry->d_parent->d_inode; + struct inode *inode = dentry->d_inode; struct nfs_fh fhandle; - struct nfs_fattr fattr, dir_attr; + struct nfs_fattr fattr; int error; /* @@ -541,7 +535,7 @@ if (is_bad_inode(inode)) { dfprintk(VFS, "nfs_lookup_validate: %s/%s has dud inode\n", - dir->d_name.name, dentry->d_name.name); + dentry->d_parent->d_name.name, dentry->d_name.name); goto out_bad; } @@ -549,7 +543,7 @@ goto out_valid; if (IS_ROOT(dentry)) { - __nfs_revalidate_inode(dentry); + __nfs_revalidate_inode(NFS_SERVER(inode), inode); goto out_valid_renew; } @@ -559,8 +553,7 @@ /* * Do a new lookup and check the dentry attributes. */ - error = NFS_CALL(lookup, dir_i, (dir, &dir_attr, - &dentry->d_name, &fhandle, &fattr)); + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); if (error < 0) goto out_bad; @@ -570,18 +563,12 @@ NFS_FILEID(inode) != fattr.fileid) goto out_bad; - /* Filehandle matches? */ - if (NFS_FH(dentry)->size == 0) - goto out_bad; + /* Ok, remember that we successfully checked it.. */ + nfs_refresh_inode(inode, &fattr); - if (NFS_FH(dentry)->size != fhandle.size || - memcmp(NFS_FH(dentry)->data, fhandle.data, fhandle.size)) + if (nfs_inode_is_stale(inode, &fhandle, &fattr)) goto out_bad; - /* Ok, remeber that we successfully checked it.. */ - nfs_refresh_inode(inode, &fattr); - nfs_refresh_inode(dir_i, &dir_attr); - out_valid_renew: nfs_renew_times(dentry); out_valid: @@ -593,10 +580,9 @@ if (have_submounts(dentry)) goto out_valid; d_drop(dentry); - if (dentry->d_parent->d_inode) - NFS_CACHEINV(dentry->d_parent->d_inode); + nfs_zap_caches(dir); if (inode && S_ISDIR(inode->i_mode)) - NFS_CACHEINV(inode); + nfs_zap_caches(inode); return 0; } @@ -611,33 +597,6 @@ } } -__inline__ struct nfs_fh *nfs_fh_alloc(void) -{ - struct nfs_fh *p; - - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (!p) - return NULL; - memset(p, 0, sizeof(*p)); - return p; -} - -__inline__ void nfs_fh_free(struct nfs_fh *p) -{ - kfree(p); -} - -/* - * Called when the dentry is being freed to release private memory. - */ -static void nfs_dentry_release(struct dentry *dentry) -{ - if (dentry->d_fsdata) { - nfs_fh_free(dentry->d_fsdata); - dentry->d_fsdata = NULL; - } -} - /* * Called when the dentry loses inode. * We use it to clean up silly-renamed files. @@ -654,44 +613,33 @@ NULL, /* d_hash */ NULL, /* d_compare */ nfs_dentry_delete, /* d_delete(struct dentry *) */ - nfs_dentry_release, /* d_release(struct dentry *) */ + NULL, /* d_release(struct dentry *) */ nfs_dentry_iput /* d_iput */ }; -static struct dentry *nfs_lookup(struct inode *dir_i, struct dentry * dentry) +static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry) { - struct dentry *dir = dentry->d_parent; struct inode *inode; int error; struct nfs_fh fhandle; - struct nfs_fattr fattr, dir_attr; + struct nfs_fattr fattr; dfprintk(VFS, "NFS: lookup(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -ENAMETOOLONG; - if (dentry->d_name.len > NFS_SERVER(dir_i)->namelen) + if (dentry->d_name.len > NFS_SERVER(dir)->namelen) goto out; dentry->d_op = &nfs_dentry_operations; - if (!dentry->d_fsdata) { - dentry->d_fsdata = nfs_fh_alloc(); - if (!dentry->d_fsdata) { - error = -ENOMEM; - goto out; - } - } - #if NFS_FIXME inode = nfs_dircache_lookup(dir_i, dentry); if (inode) goto no_entry; #endif - error = NFS_CALL(lookup, dir_i, (dir, &dir_attr, - &dentry->d_name, &fhandle, &fattr)); - nfs_refresh_inode(dir_i, &dir_attr); + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); inode = NULL; if (error == -ENOENT) goto no_entry; @@ -734,16 +682,15 @@ * that the operation succeeded on the server, but an error in the * reply path made it appear to have failed. */ -static int nfs_create(struct inode *dir_i, struct dentry *dentry, int mode) +static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) { - struct dentry *dir = dentry->d_parent; struct iattr attr; - struct nfs_fattr fattr, dir_attr; + struct nfs_fattr fattr; struct nfs_fh fhandle; int error; dfprintk(VFS, "NFS: create(%x/%ld, %s\n", - dir_i->i_dev, dir_i->i_ino, dentry->d_name.name); + dir->i_dev, dir->i_ino, dentry->d_name.name); #ifdef NFSD_BROKEN_UID /* We set uid/gid in the request because IBM's broken nfsd @@ -767,10 +714,9 @@ * select the appropriate create strategy. Currently open_namei * does not pass the create flags. */ - nfs_zap_caches(dir_i); - error = NFS_CALL(create, dir_i, (dir, &dir_attr, &dentry->d_name, - &attr, 0, &fhandle, &fattr)); - nfs_refresh_inode(dir_i, &dir_attr); + nfs_zap_caches(dir); + error = NFS_PROTO(dir)->create(dir, &dentry->d_name, + &attr, 0, &fhandle, &fattr); if (!error && fhandle.size != 0) error = nfs_instantiate(dentry, &fhandle, &fattr); if (error || fhandle.size == 0) @@ -781,16 +727,15 @@ /* * See comments for nfs_proc_create regarding failed operations. */ -static int nfs_mknod(struct inode *dir_i, struct dentry *dentry, int mode, int rdev) +static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) { - struct dentry *dir = dentry->d_parent; struct iattr attr; - struct nfs_fattr fattr, dir_attr; + struct nfs_fattr fattr; struct nfs_fh fhandle; int error; dfprintk(VFS, "NFS: mknod(%x/%ld, %s\n", - dir_i->i_dev, dir_i->i_ino, dentry->d_name.name); + dir->i_dev, dir->i_ino, dentry->d_name.name); #ifdef NFSD_BROKEN_UID attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID; @@ -803,10 +748,9 @@ #endif - nfs_zap_caches(dir_i); - error = NFS_CALL(mknod, dir_i, (dir, &dir_attr, &dentry->d_name, - &attr, rdev, &fhandle, &fattr)); - nfs_refresh_inode(dir_i, &dir_attr); + nfs_zap_caches(dir); + error = NFS_PROTO(dir)->mknod(dir, &dentry->d_name, + &attr, rdev, &fhandle, &fattr); if (!error && fhandle.size != 0) error = nfs_instantiate(dentry, &fhandle, &fattr); if (error || fhandle.size == 0) @@ -817,16 +761,15 @@ /* * See comments for nfs_proc_create regarding failed operations. */ -static int nfs_mkdir(struct inode *dir_i, struct dentry *dentry, int mode) +static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { - struct dentry *dir = dentry->d_parent; struct iattr attr; - struct nfs_fattr fattr, dir_attr; + struct nfs_fattr fattr; struct nfs_fh fhandle; int error; dfprintk(VFS, "NFS: mkdir(%x/%ld, %s)\n", - dir_i->i_dev, dir_i->i_ino, dentry->d_name.name); + dir->i_dev, dir->i_ino, dentry->d_name.name); #ifdef NFSD_BROKEN_UID attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID; @@ -838,10 +781,8 @@ attr.ia_mode = mode | S_IFDIR; #endif - nfs_zap_caches(dir_i); - error = NFS_CALL(mkdir, dir_i, (dir, &dir_attr, - &dentry->d_name, &attr, &fhandle, &fattr)); - nfs_refresh_inode(dir_i, &dir_attr); + nfs_zap_caches(dir); + error = NFS_PROTO(dir)->mkdir(dir, &dentry->d_name, &attr, &fhandle, &fattr); if (!error && fhandle.size != 0) error = nfs_instantiate(dentry, &fhandle, &fattr); @@ -850,18 +791,15 @@ return error; } -static int nfs_rmdir(struct inode *dir_i, struct dentry *dentry) +static int nfs_rmdir(struct inode *dir, struct dentry *dentry) { - struct dentry *dir = dentry->d_parent; - struct nfs_fattr dir_attr; int error; dfprintk(VFS, "NFS: rmdir(%x/%ld, %s\n", - dir_i->i_dev, dir_i->i_ino, dentry->d_name.name); + dir->i_dev, dir->i_ino, dentry->d_name.name); - nfs_zap_caches(dir_i); - error = NFS_CALL(rmdir, dir_i, (dir, &dir_attr, &dentry->d_name)); - nfs_refresh_inode(dir_i, &dir_attr); + nfs_zap_caches(dir); + error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); /* Free the inode */ if (!error) @@ -925,12 +863,10 @@ return sdentry; } -static int nfs_sillyrename(struct inode *dir_i, struct dentry *dentry) +static int nfs_sillyrename(struct inode *dir, struct dentry *dentry) { - struct dentry *dir = dentry->d_parent; static unsigned int sillycounter = 0; - struct nfs_fattr dir_attr; - const int i_inosize = sizeof(dir_i->i_ino)*2; + const int i_inosize = sizeof(dir->i_ino)*2; const int countersize = sizeof(sillycounter)*2; const int slen = strlen(".nfs") + i_inosize + countersize; struct qstr qsilly; @@ -985,12 +921,10 @@ goto out; } while(sdentry->d_inode != NULL); /* need negative lookup */ - nfs_zap_caches(dir_i); + nfs_zap_caches(dir); qsilly.name = silly; qsilly.len = strlen(silly); - error = NFS_CALL(rename, dir_i, (dir, &dir_attr, &dentry->d_name, - dir, &dir_attr, &qsilly)); - nfs_refresh_inode(dir_i, &dir_attr); + error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, dir, &qsilly); if (!error) { nfs_renew_times(dentry); d_move(dentry, sdentry); @@ -1011,9 +945,7 @@ */ static int nfs_safe_remove(struct dentry *dentry) { - struct nfs_fattr dir_attr; - struct dentry *dir = dentry->d_parent; - struct inode *dir_i = dir->d_inode, + struct inode *dir = dentry->d_parent->d_inode, *inode = dentry->d_inode; int error = 0, rehash = 0; @@ -1049,11 +981,10 @@ goto out; } - nfs_zap_caches(dir_i); + nfs_zap_caches(dir); if (inode) NFS_CACHEINV(inode); - error = NFS_CALL(remove, dir_i, (dir, &dir_attr, &dentry->d_name)); - nfs_refresh_inode(dir_i, &dir_attr); + error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); if (error < 0) goto out; @@ -1096,20 +1027,19 @@ } static int -nfs_symlink(struct inode *dir_i, struct dentry *dentry, const char *symname) +nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { - struct dentry *dir = dentry->d_parent; - struct nfs_fattr dir_attr, sym_attr; + struct nfs_fattr sym_attr; struct nfs_fh sym_fh; struct iattr attr; struct qstr qsymname; int error, mode, maxlen; dfprintk(VFS, "NFS: symlink(%x/%ld, %s, %s)\n", - dir_i->i_dev, dir_i->i_ino, dentry->d_name.name, symname); + dir->i_dev, dir->i_ino, dentry->d_name.name, symname); error = -ENAMETOOLONG; - maxlen = (NFS_PROTO(dir_i)->version==2) ? NFS2_MAXPATHLEN : NFS3_MAXPATHLEN; + maxlen = (NFS_PROTO(dir)->version==2) ? NFS2_MAXPATHLEN : NFS3_MAXPATHLEN; if (strlen(symname) > maxlen) goto out; @@ -1137,11 +1067,9 @@ qsymname.name = symname; qsymname.len = strlen(symname); - nfs_zap_caches(dir_i); - error = NFS_CALL(symlink, dir_i, (dir, &dir_attr, - &dentry->d_name, &qsymname, &attr, - &sym_fh, &sym_attr)); - nfs_refresh_inode(dir_i, &dir_attr); + nfs_zap_caches(dir); + error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname, + &attr, &sym_fh, &sym_attr); if (!error && sym_fh.size != 0 && (sym_attr.valid & NFS_ATTR_FATTR)) { error = nfs_instantiate(dentry, &sym_fh, &sym_attr); } else { @@ -1157,11 +1085,9 @@ } static int -nfs_link(struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry) +nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { - struct dentry *dir = dentry->d_parent; struct inode *inode = old_dentry->d_inode; - struct nfs_fattr old_attr, dir_attr; int error; dfprintk(VFS, "NFS: link(%s/%s -> %s/%s)\n", @@ -1174,12 +1100,9 @@ * we can't use the existing dentry. */ d_drop(dentry); - nfs_zap_caches(dir_i); + nfs_zap_caches(dir); NFS_CACHEINV(inode); - error = NFS_CALL(link, inode, (old_dentry, &old_attr, - dir, &dir_attr, &dentry->d_name)); - nfs_refresh_inode(inode, &old_attr); - nfs_refresh_inode(dir_i, &dir_attr); + error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); return error; } @@ -1214,7 +1137,6 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { - struct nfs_fattr old_attr, new_attr; struct inode * old_inode = old_dentry->d_inode; struct inode * new_inode = new_dentry->d_inode; struct dentry * dentry = NULL, *rehash = NULL; @@ -1296,12 +1218,8 @@ nfs_zap_caches(new_dir); nfs_zap_caches(old_dir); - error = NFS_CALL(rename, old_dir, - (old_dentry->d_parent, &old_attr, &old_dentry->d_name, - new_dentry->d_parent, &new_attr, &new_dentry->d_name)); - nfs_refresh_inode(old_dir, &old_attr); - nfs_refresh_inode(new_dir, &new_attr); - + error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, + new_dir, &new_dentry->d_name); out: /* Update the dcache if needed */ if (rehash) @@ -1315,14 +1233,11 @@ } int -nfs_permission(struct inode *i, int msk) +nfs_permission(struct inode *inode, int mask) { - struct nfs_fattr fattr; - struct dentry *de = NULL; - int err = vfs_permission(i, msk); - struct list_head *start, *tmp; + int error = vfs_permission(inode, mask); - if (!NFS_PROTO(i)->access) + if (!NFS_PROTO(inode)->access) goto out; /* * Trust UNIX mode bits except: @@ -1332,28 +1247,18 @@ * 3) When ACLs may overturn a negative answer */ if (!capable(CAP_DAC_OVERRIDE) && !capable(CAP_DAC_READ_SEARCH) && (current->fsuid != 0) && (current->fsgid != 0) - && err != -EACCES) + && error != -EACCES) goto out; - tmp = start = &i->i_dentry; - while ((tmp = tmp->next) != start) { - de = list_entry(tmp, struct dentry, d_alias); - if (de->d_inode == i) - break; - } - if (!de || de->d_inode != i) - return 0; + error = NFS_PROTO(inode)->access(inode, mask, 0); - err = NFS_CALL(access, i, (de, msk, &fattr, 0)); - - if (err == -EACCES && NFS_CLIENT(i)->cl_droppriv && + if (error == -EACCES && NFS_CLIENT(inode)->cl_droppriv && current->uid != 0 && current->gid != 0 && (current->fsuid != current->uid || current->fsgid != current->gid)) - err = NFS_CALL(access, i, (de, msk, &fattr, 1)); + error = NFS_PROTO(inode)->access(inode, mask, 1); - nfs_refresh_inode(i, &fattr); out: - return err; + return error; } /* diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/file.c linux-2.2.18-inode/fs/nfs/file.c --- linux-2.2.18-lockd/fs/nfs/file.c Tue Dec 12 20:31:57 2000 +++ linux-2.2.18-inode/fs/nfs/file.c Tue Dec 12 20:32:21 2000 @@ -111,13 +111,14 @@ nfs_file_read(struct file * file, char * buf, size_t count, loff_t *ppos) { struct dentry * dentry = file->f_dentry; + struct inode * inode = dentry->d_inode; ssize_t result; dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long) *ppos); - result = nfs_revalidate_inode(dentry); + result = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (!result) result = generic_file_read(file, buf, count, ppos); return result; @@ -127,12 +128,13 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) { struct dentry *dentry = file->f_dentry; + struct inode *inode = dentry->d_inode; int status; dfprintk(VFS, "nfs: mmap(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); - status = nfs_revalidate_inode(dentry); + status = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (!status) status = generic_file_mmap(file, vma); return status; @@ -182,10 +184,8 @@ rpages = NFS_SERVER(inode)->rpages; result = nfs_pagein_inode(inode, index, rpages); if (result < 0) - goto out_bad; + return result; return 0; - out_bad: - return result; } /* @@ -205,7 +205,7 @@ result = -EBUSY; if (IS_SWAPFILE(inode)) goto out_swapfile; - result = nfs_revalidate_inode(dentry); + result = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (result) goto out; diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/inode.c linux-2.2.18-inode/fs/nfs/inode.c --- linux-2.2.18-lockd/fs/nfs/inode.c Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/fs/nfs/inode.c Tue Dec 12 21:56:33 2000 @@ -40,11 +40,10 @@ #include #include -#define CONFIG_NFS_SNAPSHOT 1 #define NFSDBG_FACILITY NFSDBG_VFS #define NFS_PARANOIA 1 -static struct inode * __nfs_fhget(struct super_block *, struct nfs_fattr *); +static struct inode * __nfs_fhget(struct super_block *, struct nfs_fh *, struct nfs_fattr *); static void nfs_read_inode(struct inode *); static void nfs_put_inode(struct inode *); @@ -53,8 +52,6 @@ static void nfs_put_super(struct super_block *); static int nfs_statfs(struct super_block *, struct statfs *, int); static void nfs_umount_begin(struct super_block *); -static struct nfs_file *nfs_file_alloc(void); -static void nfs_file_free(struct nfs_file *p); static struct super_operations nfs_sops = { nfs_read_inode, /* read inode */ @@ -256,7 +253,7 @@ return NULL; } - inode = __nfs_fhget(sb, &fattr); + inode = __nfs_fhget(sb, rootfh, &fattr); return inode; } @@ -273,8 +270,7 @@ struct nfs_server *server; struct rpc_xprt *xprt = 0; struct rpc_clnt *clnt = 0; - struct nfs_fh *root_fh = NULL, - *root = &data->root, + struct nfs_fh *root = &data->root, fh; struct inode *root_inode = NULL; unsigned int authflavor; @@ -419,17 +415,11 @@ * Keep the super block locked while we try to get * the root fh attributes. */ - root_fh = nfs_fh_alloc(); - if (!root_fh) - goto out_no_fh; - memcpy((u8*)root_fh, (u8*)root, sizeof(*root_fh)); - /* Did getting the root inode fail? */ if ((root->size > NFS_SB_FHSIZE(sb) || ! (root_inode = nfs_get_root(sb, root))) && (data->flags & NFS_MOUNT_VER3)) { data->flags &= ~NFS_MOUNT_VER3; - nfs_fh_free(root_fh); rpciod_down(); rpc_shutdown_client(server->client); goto nfsv3_try_again; @@ -441,8 +431,6 @@ goto failure_put_root; sb->s_root->d_op = &nfs_dentry_operations; - sb->s_root->d_fsdata = root_fh; - sb->u.nfs_sb.s_root = root_fh; /* Get some general file system info */ if (server->rpc_ops->statfs(server, root, &fsinfo) >= 0) { @@ -518,9 +506,6 @@ failure_put_root: if (root_inode) iput(root_inode); - if (root_fh) - nfs_fh_free(root_fh); - out_no_fh: rpciod_down(); failure_unlock: @@ -552,7 +537,7 @@ struct nfs_fsinfo res; struct statfs tmp; - error = server->rpc_ops->statfs(server, NFS_FH(sb->s_root), &res); + error = server->rpc_ops->statfs(server, NFS_FH(sb->s_root->d_inode), &res); if (error) { printk(KERN_NOTICE "nfs_statfs: statfs error = %d\n", -error); memset(&res, 0, sizeof(res)); @@ -590,46 +575,6 @@ #endif /* - * Free all unused dentries in an inode's alias list. - * - * Subtle note: we have to be very careful not to cause - * any IO operations with the stale dentries, as this - * could cause file corruption. But since the dentry - * count is 0 and all pending IO for a dentry has been - * flushed when the count went to 0, we're safe here. - * Also returns the number of unhashed dentries - */ -static int -nfs_free_dentries(struct inode *inode) -{ - struct list_head *tmp, *head = &inode->i_dentry; - int unhashed; - -restart: - tmp = head->next; - unhashed = 0; - while (tmp != head) { - struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); - dget(dentry); - if (!list_empty(&dentry->d_subdirs)) - shrink_dcache_parent(dentry); - dprintk("nfs_free_dentries: found %s/%s, d_count=%d, hashed=%d\n", - dentry->d_parent->d_name.name, dentry->d_name.name, - dentry->d_count, !list_empty(&dentry->d_hash)); - if (dentry->d_count == 1) { - d_drop(dentry); - dput(dentry); - goto restart; - } - if (list_empty(&dentry->d_hash)) - unhashed++; - tmp = tmp->next; - dput(dentry); - } - return unhashed; -} - -/* * Zap the caches. */ void nfs_zap_caches(struct inode *inode) @@ -657,7 +602,7 @@ * Fill in inode information from the fattr. */ static void -nfs_fill_inode(struct inode *inode, struct nfs_fattr *fattr) +nfs_fill_inode(struct inode *inode, struct nfs_fh *fh, struct nfs_fattr *fattr) { /* * Check whether the mode has been set, as we only want to @@ -697,25 +642,15 @@ NFS_CACHE_ISIZE(inode) = fattr->size; NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); NFS_ATTRTIMEO_UPDATE(inode) = jiffies; + memcpy(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh)); } nfs_refresh_inode(inode, fattr); } -static struct inode * -nfs_make_new_inode(struct super_block *sb, struct nfs_fattr *fattr) -{ - struct inode *inode = get_empty_inode(); - - if (!inode) - return NULL; - inode->i_sb = sb; - inode->i_dev = sb->s_dev; - inode->i_flags = 0; - inode->i_ino = nfs_fattr_to_ino_t(fattr); - nfs_read_inode(inode); - nfs_fill_inode(inode, fattr); - return inode; -} +struct nfs_find_desc { + struct nfs_fh *fh; + struct nfs_fattr *fattr; +}; /* * In NFSv3 we can have 64bit inode numbers. In order to support @@ -726,50 +661,39 @@ static int nfs_find_actor(struct inode *inode, unsigned long ino, void *opaque) { - struct nfs_fattr *fattr = (struct nfs_fattr *)opaque; + struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque; + struct nfs_fh *fh = desc->fh; + struct nfs_fattr *fattr = desc->fattr; + if (NFS_FSID(inode) != fattr->fsid) return 0; if (NFS_FILEID(inode) != fattr->fileid) return 0; - if (inode->i_mode && - (fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT)) - return 0; - if (is_bad_inode(inode)) - return 0; - if (NFS_FLAGS(inode) & NFS_INO_STALE) + if (memcmp(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh)) != 0) return 0; return 1; } -static int -nfs_inode_is_stale(struct inode *inode, struct nfs_fattr *fattr) +int +nfs_inode_is_stale(struct inode *inode, struct nfs_fh *fh, struct nfs_fattr *fattr) { - int unhashed; - int is_stale = 0; - if (inode->i_mode && - (fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT)) - is_stale = 1; + /* Empty inodes are not stale */ + if (!inode->i_mode) + return 0; - if (is_bad_inode(inode)) - is_stale = 1; + if ((fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT)) + return 1; - /* - * If the inode seems stale, free up cached dentries. - */ - unhashed = nfs_free_dentries(inode); + if (is_bad_inode(inode)) + return 1; - /* Assume we're holding an i_count - * - * NB: sockets sometimes have volatile file handles - * don't invalidate their inodes even if all dentries are - * unhashed. - */ - if (unhashed && inode->i_count == unhashed + 1 - && !S_ISSOCK(inode->i_mode) && !S_ISFIFO(inode->i_mode)) - is_stale = 1; + /* Has the filehandle changed? If so is the old one stale? */ + if (memcmp(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh)) != 0 && + __nfs_revalidate_inode(NFS_SERVER(inode),inode) == -ESTALE) + return 1; - return is_stale; + return 0; } /* @@ -778,8 +702,6 @@ * the vfs read_inode function because there is no way to pass the * file handle or current attributes into the read_inode function. * - * We provide a special check for NetApp .snapshot directories to avoid - * inode aliasing problems. All snapshot inodes are anonymous (unhashed). */ struct inode * nfs_fhget(struct dentry *dentry, struct nfs_fh *fhandle, @@ -791,40 +713,16 @@ dentry->d_parent->d_name.name, dentry->d_name.name, (long long) fattr->fileid); - /* Install the file handle in the dentry */ - memcpy(NFS_FH(dentry), (u8*)fhandle, sizeof(*fhandle)); - -#ifdef CONFIG_NFS_SNAPSHOT - /* - * Check for NetApp snapshot dentries, and get an - * unhashed inode to avoid aliasing problems. - */ - if ((dentry->d_parent->d_inode->u.nfs_i.flags & NFS_IS_SNAPSHOT) || - (dentry->d_name.len == 9 && - memcmp(dentry->d_name.name, ".snapshot", 9) == 0)) { - struct inode *inode = nfs_make_new_inode(sb, fattr); - if (!inode) - goto out; - inode->u.nfs_i.flags |= NFS_IS_SNAPSHOT; - dprintk("NFS: nfs_fhget(snapshot ino=%ld)\n", inode->i_ino); - out: - return inode; - } -#endif - return __nfs_fhget(sb, fattr); + return __nfs_fhget(sb, fhandle, fattr); } /* * Look up the inode by super block and fattr->fileid. - * - * Note carefully the special handling of busy inodes (i_count > 1). - * With the kernel 2.1.xx dcache all inodes except hard links must - * have i_count == 1 after iget(). Otherwise, it indicates that the - * server has reused a fileid (i_ino) and we have a stale inode. */ static struct inode * -__nfs_fhget(struct super_block *sb, struct nfs_fattr *fattr) +__nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) { + struct nfs_find_desc desc = { fh, fattr }; struct inode *inode = NULL; unsigned long ino; @@ -833,34 +731,12 @@ ino = nfs_fattr_to_ino_t(fattr); - while((inode = iget4(sb, ino, nfs_find_actor, fattr)) != NULL) { - - /* - * Check for busy inodes, and attempt to get rid of any - * unused local references. If successful, we release the - * inode and try again. - * - * Note that the busy test uses the values in the fattr, - * as the inode may have become a different object. - * (We can probably handle modes changes here, too.) - */ - if (!nfs_inode_is_stale(inode,fattr)) - break; - - dprintk("__nfs_fhget: inode %ld still busy, i_count=%d\n", - inode->i_ino, inode->i_count); - /* Mark the inode as being stale */ - NFS_FLAGS(inode) |= NFS_INO_STALE; - nfs_zap_caches(inode); - iput(inode); - } - - if (!inode) + if (!(inode = iget4(sb, ino, nfs_find_actor, &desc))) goto out_no_inode; - nfs_fill_inode(inode, fattr); - dprintk("NFS: __nfs_fhget(%x/%ld ct=%d)\n", - inode->i_dev, inode->i_ino, inode->i_count); + nfs_fill_inode(inode, fh, fattr); + dprintk("NFS: __nfs_fhget(%x/%Ld ct=%d)\n", + inode->i_dev, (long long)NFS_FILEID(inode), inode->i_count); out: return inode; @@ -896,7 +772,7 @@ goto out; /* Now perform the setattr call */ - error = NFS_CALL(setattr, inode, (dentry, &fattr, attr)); + error = NFS_PROTO(inode)->setattr(inode, &fattr, attr); if (error || !(fattr.valid & NFS_ATTR_FATTR)) { nfs_zap_caches(inode); goto out; @@ -954,52 +830,27 @@ int nfs_revalidate(struct dentry *dentry) { - return nfs_revalidate_inode(dentry); -} - -static __inline__ struct nfs_file *nfs_file_alloc(void) -{ - struct nfs_file *p; - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p) { - memset(p, 0, sizeof(*p)); - p->magic = NFS_FILE_MAGIC; - } - return p; -} - -static __inline__ void nfs_file_free(struct nfs_file *p) -{ - if (p->magic == NFS_FILE_MAGIC) { - p->magic = 0; - kfree(p); - } else - printk(KERN_ERR "NFS: extra file info corrupted!\n"); + struct inode *inode = dentry->d_inode; + return nfs_revalidate_inode(NFS_SERVER(inode), inode); } int nfs_open(struct inode *inode, struct file *filp) { struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; - struct nfs_file *data; + struct rpc_cred *cred = rpcauth_lookupcred(auth, 0); - data = nfs_file_alloc(); - if (!data) - return -ENOMEM; - data->cred = rpcauth_lookupcred(auth, 0); - filp->private_data = data; + filp->private_data = cred; return 0; } int nfs_release(struct inode *inode, struct file *filp) { - struct nfs_file *data = NFS_FILE(filp); struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; struct rpc_cred *cred; cred = nfs_file_cred(filp); if (cred) rpcauth_releasecred(auth, cred); - nfs_file_free(data); return 0; } @@ -1008,17 +859,15 @@ * the cached attributes have to be refreshed. */ int -__nfs_revalidate_inode(struct dentry *dentry) +__nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) { - struct inode *inode = dentry->d_inode; struct nfs_fattr fattr; int status = 0; - dfprintk(PAGECACHE, "NFS: revalidating %s/%s, ino=%ld\n", - dentry->d_parent->d_name.name, dentry->d_name.name, - inode->i_ino); + dfprintk(PAGECACHE, "NFS: revalidating (%x/%Ld)\n", + inode->i_dev, (long long)NFS_FILEID(inode)); - if (!inode || is_bad_inode(inode)) + if (!inode || is_bad_inode(inode) || NFS_STALE(inode)) return -ESTALE; while (NFS_REVALIDATING(inode)) { @@ -1026,58 +875,30 @@ if (status < 0) return status; if (time_before(jiffies,NFS_READTIME(inode)+NFS_ATTRTIMEO(inode))) - return 0; + return NFS_STALE(inode) ? -ESTALE : 0; } NFS_FLAGS(inode) |= NFS_INO_REVALIDATING; - status = NFS_CALL(getattr, inode, (dentry, &fattr)); + status = NFS_PROTO(inode)->getattr(inode, &fattr); if (status) { - int error; - u32 *fh; - struct dentry *dir = dentry->d_parent; - struct nfs_fh fhandle; - struct nfs_fattr dir_attr; - - dfprintk(PAGECACHE, "nfs_revalidate_inode: %s/%s getattr failed, ino=%ld, error=%d\n", - dentry->d_parent->d_name.name, dentry->d_name.name, - inode->i_ino, status); - nfs_zap_caches(inode); - - if (status != -ESTALE) - goto out; - - /* - * A "stale filehandle" error ... show the current fh - * and find out what the filehandle should be. - */ - fh = (u32 *) NFS_FH(dentry); - dfprintk(PAGECACHE, "NFS: bad fh %08x%08x%08x%08x%08x%08x%08x%08x\n", - fh[0],fh[1],fh[2],fh[3],fh[4],fh[5],fh[6],fh[7]); - error = NFS_CALL(lookup, dir->d_inode, (dir, &dir_attr, - &dentry->d_name, &fhandle, &fattr)); - nfs_refresh_inode(dir->d_inode, &dir_attr); - if (error) { - dfprintk(PAGECACHE, "NFS: lookup failed, error=%d\n", error); - goto out; + dfprintk(PAGECACHE, "nfs_revalidate_inode: (%x/%Ld) getattr failed, error=%d\n", + inode->i_dev, (long long)NFS_FILEID(inode), status); + if (status == -ESTALE) { + NFS_FLAGS(inode) |= NFS_INO_STALE; + remove_inode_hash(inode); } - fh = (u32 *) &fhandle; - dfprintk(PAGECACHE, " %08x%08x%08x%08x%08x%08x%08x%08x\n", - fh[0],fh[1],fh[2],fh[3],fh[4],fh[5],fh[6],fh[7]); - if (!IS_ROOT(dentry) && !have_submounts(dentry)) - d_drop(dentry); goto out; } status = nfs_refresh_inode(inode, &fattr); if (status) { - dfprintk(PAGECACHE, "nfs_revalidate_inode: %s/%s refresh failed, ino=%ld, error=%d\n", - dentry->d_parent->d_name.name, dentry->d_name.name, - inode->i_ino, status); + dfprintk(PAGECACHE, "nfs_revalidate_inode: (%x/%Ld) refresh failed, error=%d\n", + inode->i_dev, (long long)NFS_FILEID(inode), status); goto out; } + dfprintk(PAGECACHE, "NFS: (%x/%Ld) revalidation complete\n", + inode->i_dev, (long long)NFS_FILEID(inode)); - dfprintk(PAGECACHE, "NFS: %s/%s revalidation complete\n", - dentry->d_parent->d_name.name, dentry->d_name.name); out: NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING; wake_up(&inode->i_wait); diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/nfs3proc.c linux-2.2.18-inode/fs/nfs/nfs3proc.c --- linux-2.2.18-lockd/fs/nfs/nfs3proc.c Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/fs/nfs/nfs3proc.c Tue Dec 12 20:32:21 2000 @@ -46,65 +46,67 @@ * One function for each procedure in the NFS protocol. */ static int -nfs3_proc_getattr(struct dentry *dentry, struct nfs_fattr *fattr) +nfs3_proc_getattr(struct inode *inode, struct nfs_fattr *fattr) { int status; dprintk("NFS call getattr\n"); fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFS3PROC_GETATTR, - NFS_FH(dentry), fattr, 0); + status = rpc_call(NFS_CLIENT(inode), NFS3PROC_GETATTR, + NFS_FH(inode), fattr, 0); dprintk("NFS reply getattr\n"); return status; } static int -nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, +nfs3_proc_setattr(struct inode *inode, struct nfs_fattr *fattr, struct iattr *sattr) { - struct nfs3_sattrargs arg = { NFS_FH(dentry), sattr, 0, 0 }; + struct nfs3_sattrargs arg = { NFS_FH(inode), sattr, 0, 0 }; int status; dprintk("NFS call setattr\n"); fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFS3PROC_SETATTR, &arg, fattr, 0); + status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0); dprintk("NFS reply setattr\n"); return status; } static int -nfs3_proc_lookup(struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name, +nfs3_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { + struct nfs_fattr dir_attr; struct nfs3_diropargs arg = { NFS_FH(dir), name->name, name->len }; - struct nfs3_diropres res = { dir_attr, fhandle, fattr }; + struct nfs3_diropres res = { &dir_attr, fhandle, fattr }; int status; dprintk("NFS call lookup %s\n", name->name); - dir_attr->valid = 0; + dir_attr.valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_LOOKUP, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, 0); if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_GETATTR, + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR, fhandle, fattr, 0); dprintk("NFS reply lookup: %d\n", status); + nfs_refresh_inode(dir, &dir_attr); return status; } static int -nfs3_proc_access(struct dentry *dentry, int mode, struct nfs_fattr *fattr, int ruid) +nfs3_proc_access(struct inode *inode, int mode, int ruid) { - struct nfs3_accessargs arg = { NFS_FH(dentry), 0 }; - struct nfs3_accessres res = { fattr, 0 }; + struct nfs_fattr fattr; + struct nfs3_accessargs arg = { NFS_FH(inode), 0 }; + struct nfs3_accessres res = { &fattr, 0 }; int status, flags; dprintk("NFS call access\n"); - fattr->valid = 0; + fattr.valid = 0; if (mode & MAY_READ) arg.access |= NFS3_ACCESS_READ; - if (S_ISDIR(dentry->d_inode->i_mode)) { + if (S_ISDIR(inode->i_mode)) { if (mode & MAY_WRITE) arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE; if (mode & MAY_EXEC) @@ -116,7 +118,7 @@ arg.access |= NFS3_ACCESS_EXECUTE; } flags = (ruid) ? RPC_CALL_REALUID : 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFS3PROC_ACCESS, &arg, &res, flags); + status = rpc_call(NFS_CLIENT(inode), NFS3PROC_ACCESS, &arg, &res, flags); dprintk("NFS reply access\n"); if (status == 0 && (arg.access & res.access) != arg.access) @@ -125,28 +127,28 @@ } static int -nfs3_proc_readlink(struct dentry *dentry, struct nfs_fattr *fattr, - void *buffer, unsigned int buflen) +nfs3_proc_readlink(struct inode *inode, void *buffer, unsigned int buflen) { - struct nfs3_readlinkargs args = { NFS_FH(dentry), buffer, buflen }; - struct nfs3_readlinkres res = { fattr, buffer, buflen }; + struct nfs_fattr fattr; + struct nfs3_readlinkargs args = { NFS_FH(inode), buffer, buflen }; + struct nfs3_readlinkres res = { &fattr, buffer, buflen }; int status; dprintk("NFS call readlink\n"); - fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFS3PROC_READLINK, + fattr.valid = 0; + status = rpc_call(NFS_CLIENT(inode), NFS3PROC_READLINK, &args, &res, 0); dprintk("NFS reply readlink: %d\n", status); return status; } static int -nfs3_proc_read(struct dentry *dentry, struct nfs_fattr *fattr, - struct rpc_cred *cred, int flags, +nfs3_proc_read(struct inode *inode, struct rpc_cred *cred, + struct nfs_fattr *fattr, int flags, unsigned long offset, unsigned int count, void *buffer, int *eofp) { - struct nfs_readargs arg = { NFS_FH(dentry), offset, count, 1, + struct nfs_readargs arg = { NFS_FH(inode), offset, count, 1, {{buffer, count}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}} }; struct nfs_readres res = { fattr, count, 0 }; @@ -155,19 +157,19 @@ dprintk("NFS call read %d @ %ld\n", count, offset); fattr->valid = 0; - status = rpc_call_sync(NFS_CLIENT(dentry->d_inode), &msg, flags); + status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); dprintk("NFS reply read: %d\n", status); *eofp = res.eof; return status; } static int -nfs3_proc_write(struct dentry *dentry, struct nfs_fattr *fattr, - struct rpc_cred *cred, int flags, +nfs3_proc_write(struct inode *inode, struct rpc_cred *cred, + struct nfs_fattr *fattr, int flags, unsigned long offset, unsigned int count, void *buffer, struct nfs_writeverf *verf) { - struct nfs_writeargs arg = { NFS_FH(dentry), offset, count, + struct nfs_writeargs arg = { NFS_FH(inode), offset, count, NFS_FILE_SYNC, 1, {{buffer, count}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}} }; @@ -181,7 +183,7 @@ rpcflags |= NFS_RPC_SWAPFLAGS; arg.stable = (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE; - status = rpc_call_sync(NFS_CLIENT(dentry->d_inode), &msg, rpcflags); + status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags); dprintk("NFS reply read: %d\n", status); return status < 0? status : res.count; @@ -192,17 +194,17 @@ * For now, we don't implement O_EXCL. */ static int -nfs3_proc_create(struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name, struct iattr *sattr, int flags, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) +nfs3_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr, + int flags, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { + struct nfs_fattr dir_attr; struct nfs3_createargs arg = { NFS_FH(dir), name->name, name->len, sattr, 0, { 0, 0 } }; - struct nfs3_diropres res = { dir_attr, fhandle, fattr }; + struct nfs3_diropres res = { &dir_attr, fhandle, fattr }; int status; dprintk("NFS call create %s\n", name->name); - dir_attr->valid = 0; + dir_attr.valid = 0; fattr->valid = 0; arg.createmode = NFS3_CREATE_UNCHECKED; @@ -213,7 +215,8 @@ } again: - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_CREATE, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0); + nfs_refresh_inode(dir, &dir_attr); /* If the server doesn't support the exclusive creation semantics, * try again with simple 'guarded' mode. */ @@ -246,7 +249,7 @@ * not sure this buys us anything (and I'd have * to revamp the NFSv3 XDR code) */ fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_SETATTR, + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SETATTR, &arg, fattr, 0); dprintk("NFS reply setattr (post-create): %d\n", status); } @@ -255,16 +258,17 @@ } static int -nfs3_proc_remove(struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name) +nfs3_proc_remove(struct inode *dir, struct qstr *name) { + struct nfs_fattr dir_attr; struct nfs3_diropargs arg = { NFS_FH(dir), name->name, name->len }; - struct rpc_message msg = {NFS3PROC_REMOVE, &arg, dir_attr, NULL }; + struct rpc_message msg = {NFS3PROC_REMOVE, &arg, &dir_attr, NULL }; int status; dprintk("NFS call remove %s\n", name->name); - dir_attr->valid = 0; - status = rpc_call_sync(NFS_CLIENT(dir->d_inode), &msg, 0); + dir_attr.valid = 0; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); + nfs_refresh_inode(dir, &dir_attr); dprintk("NFS reply remove: %d\n", status); return status; } @@ -281,7 +285,7 @@ return -ENOMEM; memset(arg, 0, size); res = (struct nfs_fattr*)(arg + 1); - arg->fh = NFS_FH(dir); + arg->fh = NFS_FH(dir->d_inode); arg->name = name->name; arg->len = name->len; msg->rpc_proc = NFS3PROC_REMOVE; @@ -303,91 +307,96 @@ static int -nfs3_proc_rename(struct dentry *old_dir, struct nfs_fattr *old_attr, - struct qstr *old_name, - struct dentry *new_dir, struct nfs_fattr *new_attr, - struct qstr *new_name) +nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, + struct inode *new_dir, struct qstr *new_name) { + struct nfs_fattr old_dir_attr, new_dir_attr; struct nfs3_renameargs arg = { NFS_FH(old_dir), old_name->name, old_name->len, NFS_FH(new_dir), new_name->name, new_name->len }; - struct nfs3_renameres res = { old_attr, new_attr }; + struct nfs3_renameres res = { &old_dir_attr, &new_dir_attr }; int status; dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); - old_attr->valid = 0; - new_attr->valid = 0; - status = rpc_call(NFS_CLIENT(old_dir->d_inode), NFS3PROC_RENAME, &arg, &res, 0); + old_dir_attr.valid = 0; + new_dir_attr.valid = 0; + status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0); + nfs_refresh_inode(old_dir, &old_dir_attr); + nfs_refresh_inode(new_dir, &new_dir_attr); dprintk("NFS reply rename: %d\n", status); return status; } static int -nfs3_proc_link(struct dentry *dentry, struct nfs_fattr *fattr, - struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name) +nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) { - struct nfs3_linkargs arg = { NFS_FH(dentry), NFS_FH(dir), + struct nfs_fattr dir_attr, fattr; + struct nfs3_linkargs arg = { NFS_FH(inode), NFS_FH(dir), name->name, name->len }; - struct nfs3_linkres res = { dir_attr, fattr }; + struct nfs3_linkres res = { &dir_attr, &fattr }; int status; dprintk("NFS call link %s\n", name->name); - dir_attr->valid = 0; - fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFS3PROC_LINK, &arg, &res, 0); + dir_attr.valid = 0; + fattr.valid = 0; + status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0); + nfs_refresh_inode(dir, &dir_attr); + nfs_refresh_inode(inode, &fattr); dprintk("NFS reply link: %d\n", status); return status; } static int -nfs3_proc_symlink(struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name, struct qstr *path, - struct iattr *sattr, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) +nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, + struct iattr *sattr, struct nfs_fh *fhandle, + struct nfs_fattr *fattr) { + struct nfs_fattr dir_attr; struct nfs3_symlinkargs arg = { NFS_FH(dir), name->name, name->len, path->name, path->len, sattr }; - struct nfs3_diropres res = { dir_attr, fhandle, fattr }; + struct nfs3_diropres res = { &dir_attr, fhandle, fattr }; int status; dprintk("NFS call symlink %s -> %s\n", name->name, path->name); - dir_attr->valid = 0; + dir_attr.valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_SYMLINK, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0); + nfs_refresh_inode(dir, &dir_attr); dprintk("NFS reply symlink: %d\n", status); return status; } static int -nfs3_proc_mkdir(struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name, struct iattr *sattr, +nfs3_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { + struct nfs_fattr dir_attr; struct nfs3_createargs arg = { NFS_FH(dir), name->name, name->len, sattr, 0, { 0, 0 } }; - struct nfs3_diropres res = { dir_attr, fhandle, fattr }; + struct nfs3_diropres res = { &dir_attr, fhandle, fattr }; int status; dprintk("NFS call mkdir %s\n", name->name); - dir_attr->valid = 0; + dir_attr.valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_MKDIR, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0); + nfs_refresh_inode(dir, &dir_attr); dprintk("NFS reply mkdir: %d\n", status); return status; } static int -nfs3_proc_rmdir(struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name) +nfs3_proc_rmdir(struct inode *dir, struct qstr *name) { + struct nfs_fattr dir_attr; struct nfs3_diropargs arg = { NFS_FH(dir), name->name, name->len }; int status; dprintk("NFS call rmdir %s\n", name->name); - dir_attr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_RMDIR, &arg, dir_attr, 0); + dir_attr.valid = 0; + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0); + nfs_refresh_inode(dir, &dir_attr); dprintk("NFS reply rmdir: %d\n", status); return status; } @@ -402,14 +411,14 @@ * readdirplus. */ static int -nfs3_proc_readdir(struct dentry *dir, struct nfs_fattr *dir_attr, - struct rpc_cred *cred, +nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred, u64 cookie, void *entry, unsigned int size, int plus) { + struct nfs_fattr dir_attr; struct nfs3_readdirargs arg = { NFS_FH(dir), cookie, {0, 0}, 0, 0, 0 }; - struct nfs3_readdirres res = { dir_attr, 0, 0, 0, 0 }; + struct nfs3_readdirres res = { &dir_attr, 0, 0, 0, 0 }; struct rpc_message msg = { NFS3PROC_READDIR, &arg, &res, cred }; - u32 *verf = NFS_COOKIEVERF(dir->d_inode); + u32 *verf = NFS_COOKIEVERF(dir); int status; arg.buffer = entry; @@ -428,20 +437,21 @@ dprintk("NFS call readdir%s %d\n", plus? "plus" : "", (unsigned int) cookie); - dir_attr->valid = 0; - status = rpc_call_sync(NFS_CLIENT(dir->d_inode), &msg, 0); + dir_attr.valid = 0; + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); + nfs_refresh_inode(dir, &dir_attr); dprintk("NFS reply readdir: %d\n", status); return status; } static int -nfs3_proc_mknod(struct dentry *dir, struct nfs_fattr *dir_attr, - struct qstr *name, struct iattr *sattr, +nfs3_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr, dev_t rdev, struct nfs_fh *fh, struct nfs_fattr *fattr) { + struct nfs_fattr dir_attr; struct nfs3_mknodargs arg = { NFS_FH(dir), name->name, name->len, 0, sattr, rdev }; - struct nfs3_diropres res = { dir_attr, fh, fattr }; + struct nfs3_diropres res = { &dir_attr, fh, fattr }; int status; switch (sattr->ia_mode & S_IFMT) { @@ -453,9 +463,10 @@ } dprintk("NFS call mknod %s %x\n", name->name, rdev); - dir_attr->valid = 0; + dir_attr.valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFS3PROC_MKNOD, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0); + nfs_refresh_inode(dir, &dir_attr); dprintk("NFS reply mknod: %d\n", status); return status; } diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/proc.c linux-2.2.18-inode/fs/nfs/proc.c --- linux-2.2.18-lockd/fs/nfs/proc.c Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/fs/nfs/proc.c Tue Dec 12 20:32:21 2000 @@ -77,34 +77,34 @@ * One function for each procedure in the NFS protocol. */ static int -nfs_proc_getattr(struct dentry *dentry, fattr *fattr) +nfs_proc_getattr(struct inode *inode, fattr *fattr) { int status; dprintk("NFS call getattr\n"); fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFSPROC_GETATTR, - NFS_FH(dentry), fattr, 0); + status = rpc_call(NFS_CLIENT(inode), NFSPROC_GETATTR, + NFS_FH(inode), fattr, 0); dprintk("NFS reply getattr\n"); return status; } static int -nfs_proc_setattr(struct dentry *dentry, fattr *fattr, +nfs_proc_setattr(struct inode *inode, fattr *fattr, struct iattr *sattr) { - struct nfs_sattrargs arg = { NFS_FH(dentry), sattr }; + struct nfs_sattrargs arg = { NFS_FH(inode), sattr }; int status; dprintk("NFS call setattr\n"); fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFSPROC_SETATTR, &arg, fattr, 0); + status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0); dprintk("NFS reply setattr\n"); return status; } static int -nfs_proc_lookup(struct dentry *dir, fattr *dir_attr, qstr *name, +nfs_proc_lookup(struct inode *dir, qstr *name, struct nfs_fh *fhandle, fattr *fattr) { struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len }; @@ -112,36 +112,32 @@ int status; dprintk("NFS call lookup %s\n", name->name); - dir_attr->valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFSPROC_LOOKUP, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFSPROC_LOOKUP, &arg, &res, 0); dprintk("NFS reply lookup: %d\n", status); return status; } static int -nfs_proc_readlink(struct dentry *dentry, fattr *fattr, - void *buffer, unsigned int bufsiz) +nfs_proc_readlink(struct inode *inode, void *buffer, unsigned int bufsiz) { - struct nfs_readlinkargs args = { NFS_FH(dentry), buffer, bufsiz }; + struct nfs_readlinkargs args = { NFS_FH(inode), buffer, bufsiz }; struct nfs_readlinkres res = { buffer, bufsiz }; int status; dprintk("NFS call readlink\n"); - fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFSPROC_READLINK, + status = rpc_call(NFS_CLIENT(inode), NFSPROC_READLINK, &args, &res, 0); dprintk("NFS reply readlink: %d\n", status); return status; } static int -nfs_proc_read(struct dentry *dentry, fattr *fattr, - struct rpc_cred *cred, int flags, - unsigned long offset, unsigned int count, +nfs_proc_read(struct inode *inode, struct rpc_cred *cred, fattr *fattr, + int flags, unsigned long offset, unsigned int count, void *buffer, int *eofp) { - struct nfs_readargs arg = { NFS_FH(dentry), offset, count, 1, + struct nfs_readargs arg = { NFS_FH(inode), offset, count, 1, {{ buffer, count }, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}} }; struct nfs_readres res = { fattr, count, 0}; @@ -150,7 +146,7 @@ dprintk("NFS call read %d @ %ld\n", count, offset); fattr->valid = 0; - status = rpc_call_sync(NFS_CLIENT(dentry->d_inode), &msg, flags); + status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); dprintk("NFS reply read: %d\n", status); *eofp = res.eof; @@ -158,12 +154,11 @@ } static int -nfs_proc_write(struct dentry *dentry, fattr *fattr, - struct rpc_cred *cred, int how, - unsigned long offset, unsigned int count, +nfs_proc_write(struct inode *inode, struct rpc_cred *cred, fattr *fattr, + int how, unsigned long offset, unsigned int count, void *buffer, struct nfs_writeverf *verf) { - struct nfs_writeargs arg = {NFS_FH(dentry), offset, count, + struct nfs_writeargs arg = {NFS_FH(inode), offset, count, NFS_FILE_SYNC, 1, {{buffer, count}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}}; @@ -175,7 +170,7 @@ fattr->valid = 0; if (how & NFS_RW_SWAP) flags |= NFS_RPC_SWAPFLAGS; - status = rpc_call_sync(NFS_CLIENT(dentry->d_inode), &msg, flags); + status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); dprintk("NFS reply write: %d\n", status); verf->committed = NFS_FILE_SYNC; /* NFSv2 always syncs data */ @@ -183,8 +178,7 @@ } static int -nfs_proc_create(struct dentry *dir, fattr *dir_attr, - qstr *name, struct iattr *sattr, int flags, +nfs_proc_create(struct inode *dir, qstr *name, struct iattr *sattr, int flags, struct nfs_fh *fhandle, fattr *fattr) { struct nfs_createargs arg = { NFS_FH(dir), name->name, @@ -192,10 +186,9 @@ struct nfs_diropok res = { fhandle, fattr }; int status; - dir_attr->valid = 0; fattr->valid = 0; dprintk("NFS call create %s\n", name->name); - status = rpc_call(NFS_CLIENT(dir->d_inode), NFSPROC_CREATE, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0); dprintk("NFS reply create: %d\n", status); return status; } @@ -204,8 +197,7 @@ * In NFSv2, mknod is grafted onto the create call. */ static int -nfs_proc_mknod(struct dentry *dir, fattr *dir_attr, - qstr *name, struct iattr *sattr, dev_t rdev, +nfs_proc_mknod(struct inode *dir, qstr *name, struct iattr *sattr, dev_t rdev, struct nfs_fh *fhandle, fattr *fattr) { struct nfs_createargs arg = { NFS_FH(dir), name->name, @@ -224,30 +216,27 @@ sattr->ia_size = rdev; /* get out your barf bag */ } - dir_attr->valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFSPROC_CREATE, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0); if (status == -EINVAL && S_ISFIFO(mode)) { sattr->ia_mode = mode; - dir_attr->valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFSPROC_CREATE, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0); } dprintk("NFS reply mknod: %d\n", status); return status; } static int -nfs_proc_remove(struct dentry *dir, fattr *dir_attr, qstr *name) +nfs_proc_remove(struct inode *dir, qstr *name) { struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len }; struct rpc_message msg = { NFSPROC_REMOVE, &arg, NULL, NULL }; int status; - dir_attr->valid = 0; dprintk("NFS call remove %s\n", name->name); - status = rpc_call_sync(NFS_CLIENT(dir->d_inode), &msg, 0); + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); dprintk("NFS reply remove: %d\n", status); return status; @@ -262,7 +251,7 @@ if (!arg) return -ENOMEM; memset(arg, 0, sizeof(*arg)); - arg->fh = NFS_FH(dir); + arg->fh = NFS_FH(dir->d_inode); arg->name = name->name; arg->len = name->len; msg->rpc_proc = NFSPROC_REMOVE; @@ -280,8 +269,8 @@ } static int -nfs_proc_rename(struct dentry *old_dir, fattr *old_attr, qstr *old_name, - struct dentry *new_dir, fattr *new_attr, qstr *new_name) +nfs_proc_rename(struct inode *old_dir, qstr *old_name, + struct inode *new_dir, qstr *new_name) { struct nfs_renameargs arg = { NFS_FH(old_dir), old_name->name, old_name->len, @@ -290,32 +279,26 @@ int status; dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); - old_attr->valid = 0; - new_attr->valid = 0; - status = rpc_call(NFS_CLIENT(old_dir->d_inode), NFSPROC_RENAME, &arg, NULL, 0); + status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0); dprintk("NFS reply rename: %d\n", status); return status; } static int -nfs_proc_link(struct dentry *dentry, fattr *attr, - struct dentry *dir, fattr *dir_attr, qstr *name) +nfs_proc_link(struct inode *inode, struct inode *dir, qstr *name) { - struct nfs_linkargs arg = { NFS_FH(dentry), NFS_FH(dir), + struct nfs_linkargs arg = { NFS_FH(inode), NFS_FH(dir), name->name, name->len }; int status; dprintk("NFS call link %s\n", name->name); - dir_attr->valid = 0; - attr->valid = 0; - status = rpc_call(NFS_CLIENT(dentry->d_inode), NFSPROC_LINK, &arg, NULL, 0); + status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0); dprintk("NFS reply link: %d\n", status); return status; } static int -nfs_proc_symlink(struct dentry *dir, fattr *dir_attr, qstr *name, - qstr *path, struct iattr *sattr, +nfs_proc_symlink(struct inode *dir, qstr *name, qstr *path, struct iattr *sattr, struct nfs_fh *sym_fh, fattr *sym_attr) { struct nfs_symlinkargs arg = { NFS_FH(dir), name->name, name->len, @@ -323,16 +306,14 @@ int status; dprintk("NFS call symlink %s -> %s\n", name->name, path->name); - dir_attr->valid = 0; sym_attr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFSPROC_SYMLINK, &arg, NULL, 0); + status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0); dprintk("NFS reply symlink: %d\n", status); return status; } static int -nfs_proc_mkdir(struct dentry *dir, fattr *dir_attr, qstr *name, - struct iattr *sattr, +nfs_proc_mkdir(struct inode *dir, qstr *name, struct iattr *sattr, struct nfs_fh *fhandle, fattr *fattr) { struct nfs_createargs arg = { NFS_FH(dir), name->name, name->len, @@ -341,22 +322,20 @@ int status; dprintk("NFS call mkdir %s\n", name->name); - dir_attr->valid = 0; fattr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFSPROC_MKDIR, &arg, &res, 0); + status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0); dprintk("NFS reply mkdir: %d\n", status); return status; } static int -nfs_proc_rmdir(struct dentry *dir, fattr *dir_attr, qstr *name) +nfs_proc_rmdir(struct inode *dir, qstr *name) { struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len }; int status; dprintk("NFS call rmdir %s\n", name->name); - dir_attr->valid = 0; - status = rpc_call(NFS_CLIENT(dir->d_inode), NFSPROC_RMDIR, &arg, NULL, 0); + status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0); dprintk("NFS reply rmdir: %d\n", status); return status; } @@ -369,8 +348,7 @@ * from nfs_readdir by calling the decode_entry function directly. */ static int -nfs_proc_readdir(struct dentry *dir, fattr *dir_attr, - struct rpc_cred *cred, +nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred, __u64 cookie, void *entry, unsigned int size, int plus) { struct nfs_readdirargs arg; @@ -378,7 +356,6 @@ struct rpc_message msg = { NFSPROC_READDIR, &arg, &res, cred }; int status; - dir_attr->valid = 0; arg.fh = NFS_FH(dir); arg.cookie = cookie; arg.buffer = entry; @@ -386,9 +363,8 @@ res.buffer = entry; res.bufsiz = size; - dir_attr->valid = 0; dprintk("NFS call readdir %d\n", (unsigned int)cookie); - status = rpc_call_sync(NFS_CLIENT(dir->d_inode), &msg, 0); + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); dprintk("NFS reply readdir: %d\n", status); return status; diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/read.c linux-2.2.18-inode/fs/nfs/read.c --- linux-2.2.18-lockd/fs/nfs/read.c Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/fs/nfs/read.c Tue Dec 12 20:32:21 2000 @@ -42,7 +42,7 @@ struct nfs_read_data { struct rpc_task task; - struct dentry *dentry; + struct inode *inode; struct rpc_cred *cred; struct nfs_readargs args; /* XDR argument struct */ struct nfs_readres res; /* ... and result struct */ @@ -87,11 +87,9 @@ * Read a page synchronously. */ static int -nfs_readpage_sync(struct file *file, struct page *page) +nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; - struct rpc_cred *cred = nfs_file_cred(file); + struct rpc_cred *cred = NULL; struct nfs_fattr fattr; unsigned long offset = nfs_page_offset(page); char *buffer = (char *) page_address(page); @@ -104,19 +102,23 @@ flags |= NFS_RPC_SWAPFLAGS; dprintk("NFS: nfs_readpage_sync(%p)\n", page); + + if (file) + cred = nfs_file_cred(file); + clear_bit(PG_error, &page->flags); do { if ((chunk = rsize) > count) chunk = count; - dprintk("NFS: nfs_proc_read(%s, (%s/%s), %ld, %d, %p)\n", + dprintk("NFS: nfs_proc_read(%s, (%x/%Ld), %ld, %d, %p)\n", NFS_SERVER(inode)->hostname, - dentry->d_parent->d_name.name, dentry->d_name.name, + inode->i_dev, (long long)NFS_FILEID(inode), offset, chunk, buffer); - result = NFS_CALL(read, inode, (dentry, &fattr, cred, flags, - offset, chunk, buffer, &eof)); + result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags, + offset, chunk, buffer, &eof); nfs_refresh_inode(inode, &fattr); /* @@ -180,7 +182,7 @@ static inline void nfs_mark_request_read(struct nfs_page *req) { - struct inode *inode = req->wb_dentry->d_inode; + struct inode *inode = req->wb_inode; if (list_empty(&req->wb_list)) { nfs_list_add_request(req, &inode->u.nfs_i.read); @@ -190,9 +192,8 @@ } static int -nfs_readpage_async(struct file *file, struct page *page) +nfs_readpage_async(struct file *file, struct inode *inode, struct page *page) { - struct inode *inode = file->f_dentry->d_inode; struct nfs_page *req, *new = NULL; int result; @@ -222,7 +223,7 @@ } result = -ENOMEM; - new = nfs_create_request(file, page, 0, PAGE_CACHE_SIZE); + new = nfs_create_request(file, inode, page, 0, PAGE_CACHE_SIZE); if (!new) break; } @@ -258,9 +259,9 @@ data->args.nriov++; } req = nfs_list_entry(data->pages.next); - data->dentry = req->wb_dentry; + data->inode = req->wb_inode; data->cred = req->wb_cred; - data->args.fh = NFS_FH(req->wb_dentry); + data->args.fh = NFS_FH(req->wb_inode); data->args.offset = nfs_page_offset(req->wb_page) + req->wb_offset; data->args.count = count; data->res.fattr = &data->fattr; @@ -286,9 +287,8 @@ } static int -nfs_pagein_one(struct list_head *head, struct dentry *dentry) +nfs_pagein_one(struct list_head *head, struct inode *inode) { - struct inode *inode = dentry->d_inode; struct rpc_task *task; struct rpc_clnt *clnt = NFS_CLIENT(inode); struct nfs_read_data *data; @@ -322,9 +322,9 @@ msg.rpc_cred = data->cred; /* Start the async call */ - dprintk("NFS: %4d initiated read call (req %s/%s count %d nriov %d.\n", + dprintk("NFS: %4d initiated read call (req %x/%Ld count %d nriov %d.\n", task->tk_pid, - dentry->d_parent->d_name.name, dentry->d_name.name, + inode->i_dev, (long long)NFS_FILEID(inode), data->args.count, data->args.nriov); rpc_clnt_sigmask(clnt, &oldset); @@ -349,7 +349,7 @@ while (!list_empty(head)) { pages += nfs_coalesce_requests(head, &one_request, rpages); req = nfs_list_entry(one_request.next); - error = nfs_pagein_one(&one_request, req->wb_dentry); + error = nfs_pagein_one(&one_request, req->wb_inode); if (error < 0) break; } @@ -419,8 +419,7 @@ nfs_readpage_result(struct rpc_task *task) { struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; - struct dentry *dentry = data->dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = data->inode; int count = data->res.count; dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", @@ -440,9 +439,9 @@ set_bit(PG_error, &page->flags); nfs_unlock_page(page); - dprintk("NFS: read (%s/%s %d@%ld)\n", - req->wb_dentry->d_parent->d_name.name, - req->wb_dentry->d_name.name, + dprintk("NFS: read (%x/%Ld %d@%ld)\n", + req->wb_inode->i_dev, + (long long)NFS_FILEID(req->wb_inode), req->wb_bytes, (nfs_page_offset(page) + req->wb_offset)); nfs_unlock_request(req); @@ -465,16 +464,19 @@ int nfs_readpage(struct file *file, struct page *page) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; - int error = 0, - rsize = NFS_SERVER(inode)->rsize; + struct inode *inode; + int error = 0; while (!nfs_lock_page(page)) wait_on_page(page); - dprintk("NFS: nfs_readpage (%p %d@%ld)\n", - page, rsize, page->offset); + if (!file) + inode = page->inode; + else + inode = file->f_dentry->d_inode; + + dprintk("NFS: nfs_readpage (%p %ld@%lu)\n", + page, PAGE_CACHE_SIZE, page->offset); /* * Try to flush any pending writes to the file @@ -484,13 +486,13 @@ goto out_unlock; error = -1; - if (!IS_SWAPFILE(inode) && !PageError(page) && rsize >= PAGE_CACHE_SIZE) - error = nfs_readpage_async(file, page); + if (!PageError(page) && NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) + error = nfs_readpage_async(file, inode, page); if (error >= 0) goto out; - error = nfs_readpage_sync(file, page); + error = nfs_readpage_sync(file, inode, page); if (error < 0 && IS_SWAPFILE(inode)) printk(KERN_ERR "Aiee.. nfs swap-in of page failed!\n"); diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/symlink.c linux-2.2.18-inode/fs/nfs/symlink.c --- linux-2.2.18-lockd/fs/nfs/symlink.c Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/fs/nfs/symlink.c Tue Dec 12 20:32:22 2000 @@ -57,19 +57,16 @@ /* Symlink caching in the page cache is even more simplistic * and straight-forward than readdir caching. */ -static int nfs_symlink_filler(struct dentry *dentry, struct page *page) +static int nfs_symlink_filler(struct inode *inode, struct page *page) { - struct inode *inode = dentry->d_inode; - struct nfs_fattr fattr; void * buffer = (void *)page_address(page); unsigned int error; /* We place the length at the beginning of the page, * in client byte order, followed by the string. */ - error = NFS_CALL(readlink, inode, (dentry, &fattr, buffer, - PAGE_CACHE_SIZE-sizeof(u32)-4)); - nfs_refresh_inode(inode, &fattr); + error = NFS_PROTO(inode)->readlink(inode, buffer, + PAGE_CACHE_SIZE-sizeof(u32)-4); if (error < 0) goto error; flush_dcache_page(page_address(page)); /* Is this correct? */ @@ -90,7 +87,7 @@ /* Caller revalidated the directory inode already. */ page = read_cache_page(inode, 0, - (filler_t *)nfs_symlink_filler, dentry); + (filler_t *)nfs_symlink_filler, inode); if (IS_ERR(page)) goto read_failed; @@ -115,7 +112,7 @@ /* Caller revalidated the directory inode already. */ page = read_cache_page(inode, 0, - (filler_t *)nfs_symlink_filler, dentry); + (filler_t *)nfs_symlink_filler, inode); if (IS_ERR(page)) goto read_failed; diff -u --recursive --new-file linux-2.2.18-lockd/fs/nfs/write.c linux-2.2.18-inode/fs/nfs/write.c --- linux-2.2.18-lockd/fs/nfs/write.c Tue Dec 12 20:31:25 2000 +++ linux-2.2.18-inode/fs/nfs/write.c Tue Dec 12 20:32:22 2000 @@ -66,7 +66,7 @@ */ struct nfs_write_data { struct rpc_task task; - struct dentry *dentry; + struct inode *inode; struct rpc_cred *cred; struct nfs_writeargs args; /* argument struct */ struct nfs_writeres res; /* result struct */ @@ -143,20 +143,21 @@ * Offset is the data offset within the page. */ static int -nfs_writepage_sync(struct file *file, struct page *page, +nfs_writepage_sync(struct file *file, struct inode *inode, struct page *page, unsigned long offset, unsigned int count) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; - struct rpc_cred *cred = nfs_file_cred(file); + struct rpc_cred *cred = NULL; unsigned int wsize = NFS_SERVER(inode)->wsize; int result, refresh = 0, written = 0, flags; u8 *buffer; struct nfs_fattr fattr; struct nfs_writeverf verifier; - dprintk("NFS: nfs_writepage_sync(%s/%s %d@%ld)\n", - dentry->d_parent->d_name.name, dentry->d_name.name, + if (file) + cred = nfs_file_cred(file); + + dprintk("NFS: nfs_writepage_sync(%x/%Ld %d@%ld)\n", + inode->i_dev, (long long)NFS_FILEID(inode), count, nfs_page_offset(page) + offset); buffer = (u8 *) page_address(page) + offset; @@ -168,7 +169,7 @@ if (count < wsize && !IS_SWAPFILE(inode)) wsize = count; - result = NFS_PROTO(inode)->write(dentry, &fattr, cred, flags, + result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags, offset, wsize, buffer, &verifier); nfs_write_attributes(inode, &fattr); @@ -205,14 +206,18 @@ int nfs_writepage(struct file * file, struct page *page) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode; unsigned offset = PAGE_CACHE_SIZE; + if (!file) + inode = page->inode; + else + inode = file->f_dentry->d_inode; if (page->offset >= inode->i_size) return -EIO; if (page->offset + offset > inode->i_size) offset = inode->i_size & (PAGE_CACHE_SIZE-1); - return nfs_writepage_sync(file, page, 0, offset); + return nfs_writepage_sync(file, inode, page, 0, offset); } /* @@ -252,6 +257,8 @@ return; if (!NFS_WBACK_BUSY(req)) printk(KERN_ERR "NFS: unlocked request attempted hashed!\n"); + if (list_empty(&inode->u.nfs_i.writeback)) + inode->i_count++; inode->u.nfs_i.npages++; list_add(&req->wb_hash, &inode->u.nfs_i.writeback); req->wb_count++; @@ -269,12 +276,14 @@ if (!NFS_WBACK_BUSY(req)) printk(KERN_ERR "NFS: unlocked request attempted unhashed!\n"); - inode = req->wb_dentry->d_inode; + inode = req->wb_inode; list_del(&req->wb_hash); INIT_LIST_HEAD(&req->wb_hash); inode->u.nfs_i.npages--; if ((inode->u.nfs_i.npages == 0) != list_empty(&inode->u.nfs_i.writeback)) printk(KERN_ERR "NFS: desynchronized value of nfs_i.npages.\n"); + if (list_empty(&inode->u.nfs_i.writeback)) + iput(inode); if (!nfs_have_writebacks(inode) && !nfs_have_read(inode)) inode_remove_flushd(inode); nfs_release_request(req); @@ -354,7 +363,7 @@ static inline void nfs_mark_request_dirty(struct nfs_page *req) { - struct inode *inode = req->wb_dentry->d_inode; + struct inode *inode = req->wb_inode; if (list_empty(&req->wb_list)) { nfs_list_add_request(req, &inode->u.nfs_i.dirty); @@ -369,7 +378,7 @@ static inline int nfs_dirty_request(struct nfs_page *req) { - struct inode *inode = req->wb_dentry->d_inode; + struct inode *inode = req->wb_inode; return !list_empty(&req->wb_list) && req->wb_list_head == &inode->u.nfs_i.dirty; } @@ -380,7 +389,7 @@ static inline void nfs_mark_request_commit(struct nfs_page *req) { - struct inode *inode = req->wb_dentry->d_inode; + struct inode *inode = req->wb_inode; if (list_empty(&req->wb_list)) { nfs_list_add_request(req, &inode->u.nfs_i.commit); @@ -396,11 +405,10 @@ * two different requests for the same page, and avoids possible deadlock * when we reach the hard limit on the number of dirty pages. */ -struct nfs_page *nfs_create_request(struct file *file, struct page *page, +struct nfs_page *nfs_create_request(struct file *file, struct inode *inode, + struct page *page, unsigned int offset, unsigned int count) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; struct nfs_reqlist *cache = NFS_REQUESTLIST(inode); struct nfs_page *req = NULL; long timeout; @@ -452,9 +460,12 @@ req->wb_offset = offset; req->wb_bytes = count; req->wb_file = file; - file->f_count++; - req->wb_dentry = dentry; - req->wb_cred = nfs_file_cred(file); + if (file) { + file->f_count++; + req->wb_cred = nfs_file_cred(file); + } else + req->wb_cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); + req->wb_inode = inode; req->wb_count = 1; /* register request's existence */ @@ -471,7 +482,7 @@ void nfs_release_request(struct nfs_page *req) { - struct inode *inode = req->wb_dentry->d_inode; + struct inode *inode = req->wb_inode; struct nfs_reqlist *cache = NFS_REQUESTLIST(inode); struct page *page = req->wb_page; @@ -489,7 +500,10 @@ if (NFS_WBACK_BUSY(req)) printk(KERN_ERR "NFS: Request released while still locked!\n"); - fput(req->wb_file); + if (req->wb_file) + fput(req->wb_file); + else + rpcauth_releasecred(NFS_CLIENT(inode)->cl_auth, req->wb_cred); page_cache_release(page); nfs_page_free(req); /* wake up anyone waiting to allocate a request */ @@ -506,7 +520,7 @@ static int nfs_wait_on_request(struct nfs_page *req) { - struct inode *inode = req->wb_dentry->d_inode; + struct inode *inode = req->wb_inode; struct rpc_clnt *clnt = NFS_CLIENT(inode); int retval; @@ -716,10 +730,9 @@ * Note: Should always be called with the Page Lock held! */ static struct nfs_page * -nfs_update_request(struct file* file, struct page *page, +nfs_update_request(struct file* file, struct inode *inode, struct page *page, unsigned int offset, unsigned int bytes) { - struct inode *inode = file->f_dentry->d_inode; struct nfs_page *req, *new = NULL; unsigned long rqend, end; @@ -754,7 +767,7 @@ */ if (inode->u.nfs_i.npages >= MAX_REQUEST_SOFT) nfs_wb_file(inode, file); - new = nfs_create_request(file, page, offset, bytes); + new = nfs_create_request(file, inode, page, offset, bytes); if (!new) return ERR_PTR(-ENOMEM); /* If the region is locked, adjust the timeout */ @@ -891,7 +904,7 @@ * page synchronously. */ if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE) - return nfs_writepage_sync(file, page, offset, count); + return nfs_writepage_sync(file, inode, page, offset, count); /* * Try to find an NFS request corresponding to this page @@ -900,7 +913,7 @@ * it out now. */ do { - req = nfs_update_request(file, page, offset, count); + req = nfs_update_request(file, inode, page, offset, count); if (IS_ERR(req)) status = PTR_ERR(req); if (status != -EBUSY) @@ -967,9 +980,9 @@ data->args.nriov++; } req = nfs_list_entry(data->pages.next); - data->dentry = req->wb_dentry; + data->inode = req->wb_inode; data->cred = req->wb_cred; - data->args.fh = NFS_FH(req->wb_dentry); + data->args.fh = NFS_FH(req->wb_inode); data->args.offset = nfs_page_offset(req->wb_page) + req->wb_offset; data->args.count = count; data->res.fattr = &data->fattr; @@ -987,9 +1000,8 @@ * that has been written but not committed. */ static int -nfs_flush_one(struct list_head *head, struct dentry *dentry, int how) +nfs_flush_one(struct list_head *head, struct inode *inode, int how) { - struct inode *inode = dentry->d_inode; struct rpc_clnt *clnt = NFS_CLIENT(inode); struct nfs_write_data *data; struct rpc_task *task; @@ -1033,10 +1045,10 @@ msg.rpc_resp = &data->res; msg.rpc_cred = data->cred; - dprintk("NFS: %4d initiated write call (req %s/%s count %d nriov %d)\n", + dprintk("NFS: %4d initiated write call (req %x/%Ld count %d nriov %d)\n", task->tk_pid, - dentry->d_parent->d_name.name, - dentry->d_name.name, + inode->i_dev, + (long long)NFS_FILEID(inode), data->args.count, data->args.nriov); rpc_clnt_sigmask(clnt, &oldset); @@ -1066,7 +1078,7 @@ while (!list_empty(head)) { pages += nfs_coalesce_requests(head, &one_request, wpages); req = nfs_list_entry(one_request.next); - error = nfs_flush_one(&one_request, req->wb_dentry, how); + error = nfs_flush_one(&one_request, req->wb_inode, how); if (error < 0) break; } @@ -1092,8 +1104,7 @@ struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; struct nfs_writeargs *argp = &data->args; struct nfs_writeres *resp = &data->res; - struct dentry *dentry = data->dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = data->inode; struct nfs_page *req; struct page *page; @@ -1137,9 +1148,9 @@ nfs_list_remove_request(req); page = req->wb_page; - dprintk("NFS: write (%s/%s %d@%Ld)", - req->wb_dentry->d_parent->d_name.name, - req->wb_dentry->d_name.name, + dprintk("NFS: write (%x/%Ld %d@%Ld)", + req->wb_inode->i_dev, + (long long)NFS_FILEID(req->wb_inode), req->wb_bytes, (long long)(nfs_page_offset(page) + req->wb_offset)); @@ -1180,7 +1191,6 @@ nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data) { struct nfs_page *req; - struct dentry *dentry; struct inode *inode; unsigned long start, end, len; @@ -1190,10 +1200,7 @@ end = 0; start = ~0; req = nfs_list_entry(head->next); - dentry = req->wb_dentry; - data->dentry = dentry; - data->cred = req->wb_cred; - inode = dentry->d_inode; + inode = req->wb_inode; while (!list_empty(head)) { struct nfs_page *req; unsigned long rqstart, rqend; @@ -1207,7 +1214,9 @@ if (rqend > end) end = rqend; } - data->args.fh = NFS_FH(dentry); + data->inode = inode; + data->cred = req->wb_cred; + data->args.fh = NFS_FH(inode); data->args.offset = start; len = end - start; if (end >= inode->i_size || len > (~((u32)0) >> 1)) @@ -1242,7 +1251,7 @@ /* Set up the argument struct */ nfs_commit_rpcsetup(head, data); req = nfs_list_entry(data->pages.next); - clnt = NFS_CLIENT(req->wb_dentry->d_inode); + clnt = NFS_CLIENT(req->wb_inode); rpc_init_task(task, clnt, nfs_commit_done, flags); task->tk_calldata = data; @@ -1278,8 +1287,7 @@ struct nfs_write_data *data = (struct nfs_write_data *)task->tk_calldata; struct nfs_writeres *resp = &data->res; struct nfs_page *req; - struct dentry *dentry = data->dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = data->inode; dprintk("NFS: %4d nfs_commit_done (status %d)\n", task->tk_pid, task->tk_status); @@ -1290,9 +1298,9 @@ req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); - dprintk("NFS: commit (%s/%s %d@%ld)", - req->wb_dentry->d_parent->d_name.name, - req->wb_dentry->d_name.name, + dprintk("NFS: commit (%x/%Ld %d@%ld)", + req->wb_inode->i_dev, + (long long)NFS_FILEID(req->wb_inode), req->wb_bytes, nfs_page_offset(req->wb_page) + req->wb_offset); if (task->tk_status < 0) { diff -u --recursive --new-file linux-2.2.18-lockd/include/linux/nfs_fs.h linux-2.2.18-inode/include/linux/nfs_fs.h --- linux-2.2.18-lockd/include/linux/nfs_fs.h Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/include/linux/nfs_fs.h Tue Dec 12 20:47:41 2000 @@ -54,8 +54,7 @@ /* * Convenience macros */ -#define NFS_FH(dentry) ((struct nfs_fh *) ((dentry)->d_fsdata)) -#define NFS_DSERVER(dentry) (&(dentry)->d_sb->u.nfs_sb.s_server) +#define NFS_FH(inode) (&(inode)->u.nfs_i.fh) #define NFS_SERVER(inode) (&(inode)->i_sb->u.nfs_sb.s_server) #define NFS_CLIENT(inode) (NFS_SERVER(inode)->client) #define NFS_PROTO(inode) (NFS_SERVER(inode)->rpc_ops) @@ -84,12 +83,11 @@ #define NFS_FLAGS(inode) ((inode)->u.nfs_i.flags) #define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING) +#define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE) #define NFS_FILEID(inode) ((inode)->u.nfs_i.fileid) #define NFS_FSID(inode) ((inode)->u.nfs_i.fsid) -#define NFS_FILE(file) ((struct nfs_file *)(file)->private_data) - /* Inode Flags */ #define NFS_USE_READDIRPLUS(inode) ((NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS) ? 1 : 0) @@ -114,24 +112,6 @@ #define FLUSH_STABLE 4 /* commit to stable storage */ -/* - * Structure for file->private_data; - */ -struct nfs_file { - unsigned long magic; /* Magic number */ - struct rpc_cred* cred; /* RPC Credentials */ -}; - -static inline int -nfs_check_file(struct file *file) -{ - if (NFS_FILE(file)->magic != NFS_FILE_MAGIC) { - printk(KERN_ERR "NFS: corrupt file structure!\n"); - return 0; - } - return 1; -} - static inline unsigned long nfs_page_offset(struct page *page) { @@ -147,6 +127,8 @@ /* * linux/fs/nfs/inode.c */ +extern int nfs_inode_is_stale(struct inode *, struct nfs_fh *, + struct nfs_fattr *); extern struct inode *nfs_fhget(struct dentry *, struct nfs_fh *, struct nfs_fattr *); extern struct super_block *nfs_read_super(struct super_block *, void *, int); @@ -155,7 +137,7 @@ extern int nfs_revalidate(struct dentry *); extern int nfs_open(struct inode *, struct file *); extern int nfs_release(struct inode *, struct file *); -extern int __nfs_revalidate_inode(struct dentry *); +extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); extern int nfs_wait_on_inode(struct inode *, int flag); extern void nfs_unlock_inode(struct inode *); @@ -293,12 +275,11 @@ * inline functions */ static inline int -nfs_revalidate_inode(struct dentry *dentry) +nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) { - struct inode *inode = dentry->d_inode; if (time_before(jiffies,NFS_READTIME(inode)+NFS_ATTRTIMEO(inode))) return 0; - return __nfs_revalidate_inode(dentry); + return __nfs_revalidate_inode(server, inode); } static inline off_t @@ -325,11 +306,7 @@ static __inline__ struct rpc_cred * nfs_file_cred(struct file *file) { - if (!NFS_FILE(file) || !nfs_check_file(file)) { - printk("nfs_file_cred: invalid file!\n"); - return NULL; - } - return NFS_FILE(file)->cred; + return (struct rpc_cred *)(file->private_data); } /* NFS root */ diff -u --recursive --new-file linux-2.2.18-lockd/include/linux/nfs_fs_i.h linux-2.2.18-inode/include/linux/nfs_fs_i.h --- linux-2.2.18-lockd/include/linux/nfs_fs_i.h Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/include/linux/nfs_fs_i.h Tue Dec 12 20:32:22 2000 @@ -1,6 +1,7 @@ #ifndef _NFS_FS_i #define _NFS_FS_I +#include #include #include @@ -22,6 +23,11 @@ __u64 fileid; /* + * NFS file handle + */ + struct nfs_fh fh; + + /* * Various flags */ unsigned short flags; @@ -79,12 +85,10 @@ /* * Legal inode flag values */ -#define NFS_INO_LOCKED 0x0001 /* locked for revalidation */ +#define NFS_INO_STALE 0x0001 /* We suspect inode is stale */ #define NFS_INO_ADVISE_RDPLUS 0x0002 /* advise readdirplus */ #define NFS_INO_REVALIDATING 0x0004 /* in nfs_revalidate() */ -#define NFS_INO_INVALIDATE 0x0008 /* zap cache on next occasion */ #define NFS_IS_SNAPSHOT 0x0010 /* a snapshot file */ -#define NFS_INO_STALE 0x0020 /* We suspect inode is stale */ #define NFS_INO_FLUSH 0x0040 /* inode is due for flushing */ /* diff -u --recursive --new-file linux-2.2.18-lockd/include/linux/nfs_page.h linux-2.2.18-inode/include/linux/nfs_page.h --- linux-2.2.18-lockd/include/linux/nfs_page.h Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/include/linux/nfs_page.h Tue Dec 12 21:55:21 2000 @@ -26,7 +26,7 @@ wb_list, /* Defines state of page: */ *wb_list_head; /* read/write/commit */ struct file *wb_file; - struct dentry *wb_dentry; + struct inode *wb_inode; struct rpc_cred *wb_cred; struct page *wb_page; /* page to read in/write out */ struct wait_queue *wb_wait; /* wait queue */ @@ -41,6 +41,7 @@ #define NFS_WBACK_BUSY(req) ((req)->wb_flags & PG_BUSY) extern struct nfs_page *nfs_create_request(struct file *file, + struct inode *inode, struct page *page, unsigned int offset, unsigned int count); diff -u --recursive --new-file linux-2.2.18-lockd/include/linux/nfs_xdr.h linux-2.2.18-inode/include/linux/nfs_xdr.h --- linux-2.2.18-lockd/include/linux/nfs_xdr.h Mon Dec 11 01:49:44 2000 +++ linux-2.2.18-inode/include/linux/nfs_xdr.h Tue Dec 12 20:32:22 2000 @@ -321,48 +321,43 @@ int (*getroot)(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *); - int (*getattr)(struct dentry *, struct nfs_fattr *); - int (*setattr)(struct dentry *, struct nfs_fattr *, struct iattr *); - int (*lookup)(struct dentry *, struct nfs_fattr *, struct qstr *, + int (*getattr)(struct inode *, struct nfs_fattr *); + int (*setattr)(struct inode *, struct nfs_fattr *, struct iattr *); + int (*lookup)(struct inode *, struct qstr *, struct nfs_fh *, struct nfs_fattr *); - int (*access)(struct dentry *, int fmode, struct nfs_fattr *, int); - int (*readlink)(struct dentry *, struct nfs_fattr *, - void *buffer, unsigned int buflen); - int (*read)(struct dentry *, struct nfs_fattr *, - struct rpc_cred *, + int (*access)(struct inode *, int, int); + int (*readlink)(struct inode *, void *buffer, unsigned int buflen); + int (*read)(struct inode *, struct rpc_cred *, + struct nfs_fattr *, int flags, unsigned long offset, unsigned int count, void *buffer, int *eofp); - int (*write)(struct dentry *, struct nfs_fattr *, - struct rpc_cred *, + int (*write)(struct inode *, struct rpc_cred *, + struct nfs_fattr *, int flags, unsigned long offset, unsigned int count, void *buffer, struct nfs_writeverf *verfp); - int (*commit)(struct dentry *, struct nfs_fattr *, + int (*commit)(struct inode *, struct nfs_fattr *, struct rpc_cred *, unsigned long, unsigned int); - int (*create)(struct dentry *, struct nfs_fattr *, - struct qstr *, struct iattr *, int flags, - struct nfs_fh *, struct nfs_fattr *); - int (*remove)(struct dentry *, struct nfs_fattr *, struct qstr *); + int (*create)(struct inode *, struct qstr *, struct iattr *, + int, struct nfs_fh *, struct nfs_fattr *); + int (*remove)(struct inode *, struct qstr *); int (*unlink_setup) (struct rpc_message *, struct dentry *, struct qstr *); void (*unlink_done) (struct dentry *, struct rpc_message *); - int (*rename)(struct dentry *, struct nfs_fattr *, struct qstr *, - struct dentry *, struct nfs_fattr *, struct qstr *); - int (*link)(struct dentry *, struct nfs_fattr *, - struct dentry *, struct nfs_fattr *, struct qstr *); - int (*symlink)(struct dentry *, struct nfs_fattr *, struct qstr *, - struct qstr *, struct iattr *, - struct nfs_fh *, struct nfs_fattr *); - int (*mkdir)(struct dentry *, struct nfs_fattr *, struct qstr *, - struct iattr *, struct nfs_fh *, struct nfs_fattr *); - int (*rmdir)(struct dentry *, struct nfs_fattr *, struct qstr *); - int (*readdir)(struct dentry *, struct nfs_fattr *, - struct rpc_cred *, - __u64 cookie, void *, unsigned int size, int plus); - int (*mknod)(struct dentry *, struct nfs_fattr *, struct qstr *, - struct iattr *, dev_t, - struct nfs_fh *, struct nfs_fattr *); + int (*rename)(struct inode *, struct qstr *, + struct inode *, struct qstr *); + int (*link)(struct inode *, struct inode *, struct qstr *); + int (*symlink)(struct inode *, struct qstr *, struct qstr *, + struct iattr *, struct nfs_fh *, + struct nfs_fattr *); + int (*mkdir)(struct inode *, struct qstr *, struct iattr *, + struct nfs_fh *, struct nfs_fattr *); + int (*rmdir)(struct inode *, struct qstr *); + int (*readdir)(struct inode *, struct rpc_cred *, + __u64, void *, unsigned int, int); + int (*mknod)(struct inode *, struct qstr *, struct iattr *, + dev_t, struct nfs_fh *, struct nfs_fattr *); int (*statfs)(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); __u32 * (*decode_dirent)(__u32 *, struct nfs_entry *, int plus);