diff -u --recursive --new-file linux-2.2.7-ac4/fs/autofs/root.c linux-2.2.7-ac4-patched/fs/autofs/root.c --- linux-2.2.7-ac4/fs/autofs/root.c Sat Apr 24 06:20:37 1999 +++ linux-2.2.7-ac4-patched/fs/autofs/root.c Wed May 12 23:15:43 1999 @@ -168,7 +168,7 @@ * yet completely filled in, and revalidate has to delay such * lookups.. */ -static int autofs_revalidate(struct dentry * dentry) +static int autofs_revalidate(struct dentry * dentry, int flags) { struct inode * dir = dentry->d_parent->d_inode; struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); @@ -241,7 +241,7 @@ d_add(dentry, NULL); up(&dir->i_sem); - autofs_revalidate(dentry); + autofs_revalidate(dentry, 0); down(&dir->i_sem); /* diff -u --recursive --new-file linux-2.2.7-ac4/fs/coda/dir.c linux-2.2.7-ac4-patched/fs/coda/dir.c --- linux-2.2.7-ac4/fs/coda/dir.c Sat Apr 24 06:20:37 1999 +++ linux-2.2.7-ac4-patched/fs/coda/dir.c Wed May 12 23:15:43 1999 @@ -44,7 +44,7 @@ static int coda_readdir(struct file *file, void *dirent, filldir_t filldir); /* dentry ops */ -static int coda_dentry_revalidate(struct dentry *de); +static int coda_dentry_revalidate(struct dentry *de, int); static void coda_dentry_delete(struct dentry *); /* support routines */ @@ -778,7 +778,7 @@ } /* called when a cache lookup succeeds */ -static int coda_dentry_revalidate(struct dentry *de) +static int coda_dentry_revalidate(struct dentry *de, int flags) { int valid = 1; struct inode *inode = de->d_inode; diff -u --recursive --new-file linux-2.2.7-ac4/fs/devpts/root.c linux-2.2.7-ac4-patched/fs/devpts/root.c --- linux-2.2.7-ac4/fs/devpts/root.c Sat Apr 24 06:20:37 1999 +++ linux-2.2.7-ac4-patched/fs/devpts/root.c Wed May 12 23:15:43 1999 @@ -18,7 +18,7 @@ static int devpts_root_readdir(struct file *,void *,filldir_t); static struct dentry *devpts_root_lookup(struct inode *,struct dentry *); -static int devpts_revalidate(struct dentry *); +static int devpts_revalidate(struct dentry *, int); static struct file_operations devpts_root_operations = { NULL, /* llseek */ @@ -116,7 +116,7 @@ * the pty really does still exist. Never revalidate negative dentries; * for simplicity (fix later?) */ -static int devpts_revalidate(struct dentry * dentry) +static int devpts_revalidate(struct dentry * dentry, int flags) { struct devpts_sb_info *sbi; diff -u --recursive --new-file linux-2.2.7-ac4/fs/hfs/sysdep.c linux-2.2.7-ac4-patched/fs/hfs/sysdep.c --- linux-2.2.7-ac4/fs/hfs/sysdep.c Wed Dec 23 23:10:36 1998 +++ linux-2.2.7-ac4-patched/fs/hfs/sysdep.c Wed May 12 23:15:43 1999 @@ -18,7 +18,7 @@ #include #include -static int hfs_revalidate_dentry(struct dentry *); +static int hfs_revalidate_dentry(struct dentry *, int); static int hfs_hash_dentry(struct dentry *, struct qstr *); static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); static void hfs_dentry_iput(struct dentry *, struct inode *); @@ -89,7 +89,7 @@ iput(inode); } -static int hfs_revalidate_dentry(struct dentry *dentry) +static int hfs_revalidate_dentry(struct dentry *dentry, int flags) { struct inode *inode = dentry->d_inode; int diff; diff -u --recursive --new-file linux-2.2.7-ac4/fs/namei.c linux-2.2.7-ac4-patched/fs/namei.c --- linux-2.2.7-ac4/fs/namei.c Tue May 11 21:35:40 1999 +++ linux-2.2.7-ac4-patched/fs/namei.c Wed May 12 23:15:44 1999 @@ -219,12 +219,12 @@ /* * Internal lookup() using the new generic dcache. */ -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name) +static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) { struct dentry * dentry = d_lookup(parent, name); if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry) && !d_invalidate(dentry)) { + if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { dput(dentry); dentry = NULL; } @@ -239,7 +239,7 @@ * We get the directory semaphore, and after getting that we also * make sure that nobody added the entry to the dcache in the meantime.. */ -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name) +static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) { struct dentry * result; struct inode *dir = parent->d_inode; @@ -252,7 +252,7 @@ * FIXME! This could use version numbering or similar to * avoid unnecessary cache lookups. */ - result = cached_lookup(parent, name); + result = cached_lookup(parent, name, flags); if (!result) { struct dentry * dentry = d_alloc(parent, name); result = ERR_PTR(-ENOMEM); @@ -386,9 +386,9 @@ /* This does the actual lookups.. */ dentry = reserved_lookup(base, &this); if (!dentry) { - dentry = cached_lookup(base, &this); + dentry = cached_lookup(base, &this, flags); if (!dentry) { - dentry = real_lookup(base, &this); + dentry = real_lookup(base, &this, flags); if (IS_ERR(dentry)) break; } diff -u --recursive --new-file linux-2.2.7-ac4/fs/ncpfs/dir.c linux-2.2.7-ac4-patched/fs/ncpfs/dir.c --- linux-2.2.7-ac4/fs/ncpfs/dir.c Tue May 11 21:35:40 1999 +++ linux-2.2.7-ac4-patched/fs/ncpfs/dir.c Wed May 12 23:15:44 1999 @@ -111,14 +111,14 @@ /* * Dentry operations routines */ -static int ncp_lookup_validate(struct dentry *); +static int ncp_lookup_validate(struct dentry *, int); static int ncp_hash_dentry(struct dentry *, struct qstr *); static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *); static void ncp_delete_dentry(struct dentry *); struct dentry_operations ncp_dentry_operations = { - ncp_lookup_validate, /* d_validate(struct dentry *) */ + ncp_lookup_validate, /* d_revalidate(struct dentry *, int) */ ncp_hash_dentry, /* d_hash */ ncp_compare_dentry, /* d_compare */ ncp_delete_dentry /* d_delete(struct dentry *) */ @@ -344,7 +344,7 @@ static int -ncp_lookup_validate(struct dentry * dentry) +ncp_lookup_validate(struct dentry * dentry, int flags) { struct ncp_server *server; struct inode *dir = dentry->d_parent->d_inode; diff -u --recursive --new-file linux-2.2.7-ac4/fs/nfs/dir.c linux-2.2.7-ac4-patched/fs/nfs/dir.c --- linux-2.2.7-ac4/fs/nfs/dir.c Tue May 11 21:35:40 1999 +++ linux-2.2.7-ac4-patched/fs/nfs/dir.c Thu May 13 22:07:24 1999 @@ -52,9 +52,8 @@ }; static int nfs_safe_remove(struct dentry *); +static int _nfs_safe_remove(struct dentry *, struct rpc_cred *); -static int nfs_dir_open(struct inode *, struct file *); -static int nfs_dir_release(struct inode *, struct file *); static ssize_t nfs_dir_read(struct file *, char *, size_t, loff_t *); static int nfs_readdir(struct file *, void *, filldir_t); static struct dentry *nfs_lookup(struct inode *, struct dentry *); @@ -76,9 +75,9 @@ NULL, /* select - default */ NULL, /* ioctl - default */ NULL, /* mmap */ - nfs_dir_open, /* open */ + nfs_open, /* open */ NULL, /* flush */ - nfs_dir_release, /* release */ + nfs_release, /* release */ NULL /* fsync */ }; @@ -105,28 +104,6 @@ nfs_revalidate, /* revalidate */ }; -static int -nfs_dir_open(struct inode *dir, struct file *filp) -{ - struct dentry *dentry = filp->f_dentry; - struct rpc_auth *auth = NFS_CLIENT(dir)->cl_auth; - - NFS_FILE_CRED(filp) = rpcauth_lookupcred(auth, 0); - return 0; -} - -int -nfs_dir_release(struct inode *dir, struct file *filp) -{ - struct rpc_auth *auth = NFS_CLIENT(dir)->cl_auth; - - if (NFS_FILE_CRED(filp)) { - rpcauth_releasecred(auth, NFS_FILE_CRED(filp)); - NFS_FILE_CRED(filp) = NULL; - } - return 0; -} - static ssize_t nfs_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos) { @@ -382,8 +359,6 @@ nfs_invalidate_dircache_sb(NULL); } -#define NFS_REVALIDATE_INTERVAL (5*HZ) - /* * Whenever an NFS operation succeeds, we know that the dentry * is valid, so we update the revalidation timestamp. @@ -393,6 +368,48 @@ dentry->d_time = jiffies; } +static inline int nfs_dentry_force_reval(struct dentry *dentry, int flags) +{ + struct inode *inode = dentry->d_inode; + unsigned long timeout = NFS_ATTRTIMEO(inode); + + /* + * If it's the last lookup in a series, we use a stricter + * cache consistency check by looking at the parent mtime. + * + * If it's been modified in the last hour, be really strict. + * (This still means that we can avoid doing unnecessary + * work on directories like /usr/share/bin etc which basically + * never change). + */ + if (!(flags & LOOKUP_CONTINUE)) { + long diff = CURRENT_TIME - dentry->d_parent->d_inode->i_mtime; + + if (diff < 15*60) + timeout = 0; + } + + return time_after(jiffies,dentry->d_time + timeout); +} + +/* + * We judge how long we want to trust negative + * dentries by looking at the parent inode mtime. + * + * If mtime is close to present time, we revalidate + * more often. + */ +static inline int nfs_neg_need_reval(struct dentry *dentry) +{ + unsigned long timeout = 30 * HZ; + long diff = CURRENT_TIME - dentry->d_parent->d_inode->i_mtime; + + if (diff < 5*60) + timeout = 1 * HZ; + + return time_after(jiffies, dentry->d_time + timeout); +} + /* * This is called every time the dcache has a lookup hit, * and we should check whether we can really trust that @@ -405,7 +422,7 @@ * we do a new lookup and verify that the dentry is still * correct. */ -static int nfs_lookup_revalidate(struct dentry * dentry) +static int nfs_lookup_revalidate(struct dentry * dentry, int flags) { struct dentry * parent = dentry->d_parent; struct inode * inode = dentry->d_inode; @@ -414,11 +431,15 @@ struct nfs_fattr fattr; /* - * If we don't have an inode, let's just assume - * a 5-second "live" time for negative dentries. + * If we don't have an inode, let's look at the parent + * directory mtime to get a hint about how often we + * should validate things.. */ - if (!inode) - goto do_lookup; + if (!inode) { + if (nfs_neg_need_reval(dentry)) + goto out_bad; + goto out_valid; + } if (is_bad_inode(inode)) { dfprintk(VFS, "nfs_lookup_validate: %s/%s has dud inode\n", @@ -426,30 +447,33 @@ goto out_bad; } - if (_nfs_revalidate_inode(NFS_DSERVER(dentry), dentry)) - goto out_bad; - - if (time_before(jiffies,dentry->d_time+NFS_ATTRTIMEO(inode))) - goto out_valid; - - if (IS_ROOT(dentry)) + if (!nfs_dentry_force_reval(dentry, flags)) goto out_valid; -do_lookup: /* * Do a new lookup and check the dentry attributes. */ error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent), dentry->d_name.name, &fhandle, &fattr); - if (dentry->d_inode == NULL) { - if (error == -ENOENT && - time_before(jiffies,dentry->d_time+NFS_REVALIDATE_INTERVAL)) + + /* + * For a root dentry we only really want to refresh the attributes + */ + if (IS_ROOT(dentry)) { + if (error) goto out_valid; - goto out_bad; + goto out_refresh; } + if (error) goto out_bad; + /* + * Did something happen to the inode while we slept in the RPC call? + */ + if (is_bad_inode(inode)) + goto out_bad; + /* Inode number matches? */ if (fattr.fileid != inode->i_ino) goto out_bad; @@ -460,6 +484,7 @@ goto out_bad; } +out_refresh: /* Ok, remeber that we successfully checked it.. */ nfs_renew_times(dentry); nfs_refresh_inode(inode, &fattr); @@ -486,12 +511,17 @@ dentry->d_flags); if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { + struct rpc_auth *auth = NULL; + struct rpc_cred *cred = NFS_DCRED(dentry); int error; - + dentry->d_flags &= ~DCACHE_NFSFS_RENAMED; + NFS_DCRED(dentry) = NULL; /* Unhash it first */ d_drop(dentry); - error = nfs_safe_remove(dentry); + error = _nfs_safe_remove(dentry, cred); + if (cred && auth) + rpcauth_releasecred(auth, cred); if (error) printk("NFS: can't silly-delete %s/%s, error=%d\n", dentry->d_parent->d_name.name, @@ -525,7 +555,7 @@ } struct dentry_operations nfs_dentry_operations = { - nfs_lookup_revalidate, /* d_validate(struct dentry *) */ + nfs_lookup_revalidate, /* d_revalidate(struct dentry *, int) */ NULL, /* d_hash */ NULL, /* d_compare */ nfs_dentry_delete, /* d_delete(struct dentry *) */ @@ -573,9 +603,10 @@ error = -ENOMEM; if (!dentry->d_fsdata) { - dentry->d_fsdata = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); + dentry->d_fsdata = kmalloc(sizeof(struct nfs_dentry), GFP_KERNEL); if (!dentry->d_fsdata) goto out; + memset(dentry->d_fsdata, 0, sizeof(struct nfs_dentry)); } dentry->d_op = &nfs_dentry_operations; @@ -909,7 +940,7 @@ * We update inode->i_nlink and free the inode prior to the operation * to avoid possible races if the server reuses the inode. */ -static int nfs_safe_remove(struct dentry *dentry) +static int _nfs_safe_remove(struct dentry *dentry, struct rpc_cred *cred) { struct inode *dir = dentry->d_parent->d_inode; struct inode *inode = dentry->d_inode; @@ -958,7 +989,7 @@ } nfs_invalidate_dircache(dir); error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dentry->d_parent), - dentry->d_name.name); + cred, dentry->d_name.name); /* * Rehash the negative dentry if the operation succeeded. */ @@ -967,6 +998,12 @@ out: return error; } + +static int nfs_safe_remove(struct dentry *dentry) +{ + return _nfs_safe_remove(dentry, NULL); +} + /* We do silly rename. In case sillyrename() returns -EBUSY, the inode * belongs to an active ".nfs..." file and we return -EBUSY. diff -u --recursive --new-file linux-2.2.7-ac4/fs/nfs/file.c linux-2.2.7-ac4-patched/fs/nfs/file.c --- linux-2.2.7-ac4/fs/nfs/file.c Thu May 13 13:38:11 1999 +++ linux-2.2.7-ac4-patched/fs/nfs/file.c Thu May 13 13:41:13 1999 @@ -34,8 +34,6 @@ #define NFSDBG_FACILITY NFSDBG_FILE -static int nfs_file_open(struct inode *, struct file *); -static int nfs_file_release(struct inode *, struct file *); static int nfs_file_mmap(struct file *, struct vm_area_struct *); static ssize_t nfs_file_read(struct file *, char *, size_t, loff_t *); static ssize_t nfs_file_write(struct file *, const char *, size_t, loff_t *); @@ -50,9 +48,9 @@ NULL, /* select - default */ NULL, /* ioctl - default */ nfs_file_mmap, /* mmap */ - nfs_file_open, /* open */ + nfs_open, /* open */ nfs_file_flush, /* flush */ - nfs_file_release, /* release */ + nfs_release, /* release */ nfs_fsync, /* fsync */ NULL, /* fasync */ NULL, /* check_media_change */ @@ -95,28 +93,6 @@ nfs_file_flush(struct file *file) { return nfs_fsync(file, file->f_dentry); -} - -static int -nfs_file_open(struct inode *inode, struct file *filp) -{ - struct dentry *dentry = filp->f_dentry; - struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; - - NFS_FILE_CRED(filp) = rpcauth_lookupcred(auth, 0); - return 0; -} - -int -nfs_file_release(struct inode *inode, struct file *filp) -{ - struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; - - if (NFS_FILE_CRED(filp)) { - rpcauth_releasecred(auth, NFS_FILE_CRED(filp)); - NFS_FILE_CRED(filp) = NULL; - } - return 0; } static ssize_t diff -u --recursive --new-file linux-2.2.7-ac4/fs/nfs/inode.c linux-2.2.7-ac4-patched/fs/nfs/inode.c --- linux-2.2.7-ac4/fs/nfs/inode.c Tue May 11 21:35:40 1999 +++ linux-2.2.7-ac4-patched/fs/nfs/inode.c Thu May 13 14:02:04 1999 @@ -195,6 +195,7 @@ struct nfs_server *server; struct rpc_xprt *xprt; struct rpc_clnt *clnt; + struct nfs_dentry *root_d_fsdata = NULL; struct nfs_fh *root_fh; struct inode *root_inode; unsigned int authflavor; @@ -288,9 +289,11 @@ * Keep the super block locked while we try to get * the root fh attributes. */ - root_fh = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); - if (!root_fh) + root_d_fsdata = kmalloc(sizeof(*root_d_fsdata), GFP_KERNEL); + if (!root_d_fsdata) goto out_no_fh; + memset(root_d_fsdata, 0, sizeof(*root_d_fsdata)); + root_fh = &root_d_fsdata->fh; *root_fh = data->root; if (nfs_proc_getattr(server, root_fh, &fattr) != 0) @@ -303,7 +306,7 @@ if (!sb->s_root) goto out_no_root; sb->s_root->d_op = &nfs_dentry_operations; - sb->s_root->d_fsdata = root_fh; + sb->s_root->d_fsdata = root_d_fsdata; /* Fire up the writeback cache */ if (nfs_reqlist_init(server) < 0) { @@ -330,7 +333,7 @@ out_no_fattr: printk("nfs_read_super: get root fattr failed\n"); out_free_fh: - kfree(root_fh); + kfree(root_d_fsdata); out_no_fh: rpciod_down(); goto out_shutdown; @@ -689,6 +692,25 @@ error = nfs_refresh_inode(inode, &fattr); out: return error; +} + +int nfs_open(struct inode *inode, struct file *filp) +{ + struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; + + NFS_FILE_CRED(filp) = rpcauth_lookupcred(auth, 0); + return 0; +} + +int nfs_release(struct inode *inode, struct file *filp) +{ + struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; + + if (NFS_FILE_CRED(filp)) { + rpcauth_releasecred(auth, NFS_FILE_CRED(filp)); + NFS_FILE_CRED(filp) = NULL; + } + return 0; } diff -u --recursive --new-file linux-2.2.7-ac4/fs/nfs/proc.c linux-2.2.7-ac4-patched/fs/nfs/proc.c --- linux-2.2.7-ac4/fs/nfs/proc.c Tue May 11 21:35:40 1999 +++ linux-2.2.7-ac4-patched/fs/nfs/proc.c Wed May 12 23:32:02 1999 @@ -163,13 +163,16 @@ } int -nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, const char *name) +nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, + struct rpc_cred *cred, const char *name) { struct nfs_diropargs arg = { dir, name }; int status; dprintk("NFS call remove %s\n", name); - status = rpc_call(server->client, NFSPROC_REMOVE, &arg, NULL, 0); + status = rpc_do_call(server->client, cred, + NFSPROC_REMOVE, &arg, NULL, 0, + NULL, NULL); dprintk("NFS reply remove: %d\n", status); return status; } diff -u --recursive --new-file linux-2.2.7-ac4/fs/smbfs/dir.c linux-2.2.7-ac4-patched/fs/smbfs/dir.c --- linux-2.2.7-ac4/fs/smbfs/dir.c Sat Apr 24 06:20:38 1999 +++ linux-2.2.7-ac4-patched/fs/smbfs/dir.c Wed May 12 23:15:44 1999 @@ -191,14 +191,14 @@ /* * Dentry operations routines */ -static int smb_lookup_validate(struct dentry *); +static int smb_lookup_validate(struct dentry *, int); static int smb_hash_dentry(struct dentry *, struct qstr *); static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *); static void smb_delete_dentry(struct dentry *); static struct dentry_operations smbfs_dentry_operations = { - smb_lookup_validate, /* d_validate(struct dentry *) */ + smb_lookup_validate, /* d_revalidate(struct dentry *) */ smb_hash_dentry, /* d_hash */ smb_compare_dentry, /* d_compare */ smb_delete_dentry /* d_delete(struct dentry *) */ @@ -208,7 +208,7 @@ * This is the callback when the dcache has a lookup hit. */ static int -smb_lookup_validate(struct dentry * dentry) +smb_lookup_validate(struct dentry * dentry, int flags) { struct inode * inode = dentry->d_inode; unsigned long age = jiffies - dentry->d_time; diff -u --recursive --new-file linux-2.2.7-ac4/fs/umsdos/dir.c linux-2.2.7-ac4-patched/fs/umsdos/dir.c --- linux-2.2.7-ac4/fs/umsdos/dir.c Sat Apr 24 06:20:38 1999 +++ linux-2.2.7-ac4-patched/fs/umsdos/dir.c Wed May 12 23:15:44 1999 @@ -30,7 +30,7 @@ */ /* nothing for now ... */ -static int umsdos_dentry_validate(struct dentry *dentry) +static int umsdos_dentry_validate(struct dentry *dentry, int flags) { return 1; } @@ -46,7 +46,7 @@ struct dentry_operations umsdos_dentry_operations = { - umsdos_dentry_validate, /* d_validate(struct dentry *) */ + umsdos_dentry_validate, /* d_revalidate(struct dentry *, int) */ NULL, /* d_hash */ NULL, /* d_compare */ umsdos_dentry_dput, /* d_delete(struct dentry *) */ diff -u --recursive --new-file linux-2.2.7-ac4/fs/vfat/namei.c linux-2.2.7-ac4-patched/fs/vfat/namei.c --- linux-2.2.7-ac4/fs/vfat/namei.c Sat Apr 24 06:20:38 1999 +++ linux-2.2.7-ac4-patched/fs/vfat/namei.c Wed May 12 23:15:44 1999 @@ -71,7 +71,7 @@ static int vfat_hash(struct dentry *parent, struct qstr *qstr); static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b); -static int vfat_revalidate(struct dentry *dentry); +static int vfat_revalidate(struct dentry *dentry, int); static struct dentry_operations vfat_dentry_ops[4] = { { @@ -106,7 +106,7 @@ MOD_DEC_USE_COUNT; } -static int vfat_revalidate(struct dentry *dentry) +static int vfat_revalidate(struct dentry *dentry, int flags) { PRINTK1(("vfat_revalidate: %s\n", dentry->d_name.name)); if (dentry->d_time == dentry->d_parent->d_inode->i_version) { diff -u --recursive --new-file linux-2.2.7-ac4/include/linux/dcache.h linux-2.2.7-ac4-patched/include/linux/dcache.h --- linux-2.2.7-ac4/include/linux/dcache.h Fri Mar 19 17:08:57 1999 +++ linux-2.2.7-ac4-patched/include/linux/dcache.h Wed May 12 23:15:44 1999 @@ -77,7 +77,7 @@ }; struct dentry_operations { - int (*d_revalidate)(struct dentry *); + int (*d_revalidate)(struct dentry *, int); int (*d_hash) (struct dentry *, struct qstr *); int (*d_compare) (struct dentry *, struct qstr *, struct qstr *); void (*d_delete)(struct dentry *); diff -u --recursive --new-file linux-2.2.7-ac4/include/linux/nfs_fs.h linux-2.2.7-ac4-patched/include/linux/nfs_fs.h --- linux-2.2.7-ac4/include/linux/nfs_fs.h Tue May 11 21:35:42 1999 +++ linux-2.2.7-ac4-patched/include/linux/nfs_fs.h Thu May 13 13:47:50 1999 @@ -55,7 +55,7 @@ */ #define NFS_SUPER_MAGIC 0x6969 -#define NFS_FH(dentry) ((struct nfs_fh *) ((dentry)->d_fsdata)) +#define NFS_FH(dentry) (&((struct nfs_dentry *) ((dentry)->d_fsdata))->fh) #define NFS_DSERVER(dentry) (&(dentry)->d_sb->u.nfs_sb.s_server) #define NFS_SERVER(inode) (&(inode)->i_sb->u.nfs_sb.s_server) #define NFS_CLIENT(inode) (NFS_SERVER(inode)->client) @@ -83,6 +83,7 @@ #define NFS_CLUSTERS(inode) ((inode)->u.nfs_i.dirty) #define NFS_FILE_CRED(filp) ((struct rpc_cred*)((filp)->private_data)) +#define NFS_DCRED(dentry) (((struct nfs_dentry *) ((dentry)->d_fsdata))->cred) /* * These are the default flags for swap requests @@ -104,6 +105,14 @@ #define FLUSH_WAIT 4 /* wait for completion */ #define FLUSH_STABLE 8 /* commit to stable storage */ +/* + * Structure for dentry->d_fsdata + */ +struct nfs_dentry { + struct nfs_fh fh; + struct rpc_cred* cred; +}; + /* * linux/fs/nfs/proc.c @@ -130,7 +139,7 @@ const char *name, struct nfs_sattr *sattr, struct nfs_fh *fhandle, struct nfs_fattr *fattr); extern int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, - const char *name); + struct rpc_cred *cred, const char *name); extern int nfs_proc_rename(struct nfs_server *server, struct nfs_fh *old_dir, const char *old_name, struct nfs_fh *new_dir, const char *new_name); @@ -160,6 +169,8 @@ struct nfs_fattr *); extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); 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 nfs_server *, struct dentry *); extern int __nfs_wait_on_inode(struct inode *, int flag); extern void nfs_unlock_inode(struct inode *inode); diff -u --recursive --new-file linux-2.2.7-ac4/net/sunrpc/sched.c linux-2.2.7-ac4-patched/net/sunrpc/sched.c --- linux-2.2.7-ac4/net/sunrpc/sched.c Tue May 11 21:35:45 1999 +++ linux-2.2.7-ac4-patched/net/sunrpc/sched.c Thu May 13 00:06:40 1999 @@ -167,6 +167,7 @@ printk(KERN_ERR "RPC: task w/ running timer in rpc_make_runnable!!\n"); return; } + task->tk_flags |= RPC_TASK_RUNNING; if (RPC_IS_ASYNC(task)) { int status; status = rpc_add_wait_queue(&schedq, task); @@ -181,7 +182,6 @@ } else { wake_up(&task->tk_wait); } - task->tk_flags |= RPC_TASK_RUNNING; } @@ -443,7 +443,10 @@ task->tk_pid); if (current->pid == rpciod_pid) printk(KERN_ERR "RPC: rpciod waiting on sync task!\n"); - sleep_on(&task->tk_wait); + + sti(); + __wait_event(task->tk_wait, RPC_IS_RUNNING(task)); + cli(); /* * When the task received a signal, remove from