diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
commit | 546db14ee74118296f425f3b91634fb767d67290 (patch) | |
tree | 22b613a3da8d4bf663eec5e155af01b87fdf9094 /fs/nfs/dir.c | |
parent | 1e25e41c4f5474e14452094492dbc169b800e4c8 (diff) |
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles
and IP27 actually works.
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 144 |
1 files changed, 46 insertions, 98 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 6b52b2d54..b7ec225ac 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -308,8 +308,7 @@ static struct page *try_to_get_dirent_page(struct file *file, __u32 cookie, int struct nfs_readdirres rd_res; struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; - struct page *page, **hash; - unsigned long page_cache; + struct page *page, **hash, *page_cache; long offset; __u32 *cookiep; @@ -341,14 +340,14 @@ repeat: goto unlock_out; } - page = page_cache_entry(page_cache); + page = page_cache; if (add_to_page_cache_unique(page, inode, offset, hash)) { page_cache_release(page); goto repeat; } rd_args.fh = NFS_FH(dentry); - rd_res.buffer = (char *)page_cache; + rd_res.buffer = (char *)page_address(page_cache); rd_res.bufsiz = PAGE_CACHE_SIZE; rd_res.cookie = *cookiep; do { @@ -533,13 +532,15 @@ static inline int nfs_dentry_force_reval(struct dentry *dentry, int flags) * If mtime is close to present time, we revalidate * more often. */ +#define NFS_REVALIDATE_NEGATIVE (1 * HZ) 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; + struct inode *dir = dentry->d_parent->d_inode; + unsigned long timeout = NFS_ATTRTIMEO(dir); + long diff = CURRENT_TIME - dir->i_mtime; - if (diff < 5*60) - timeout = 1 * HZ; + if (diff < 5*60 && timeout > NFS_REVALIDATE_NEGATIVE) + timeout = NFS_REVALIDATE_NEGATIVE; return time_after(jiffies, dentry->d_time + timeout); } @@ -581,12 +582,14 @@ static int nfs_lookup_revalidate(struct dentry * dentry, int flags) goto out_bad; } - if (IS_ROOT(dentry)) - goto out_valid; - if (!nfs_dentry_force_reval(dentry, flags)) goto out_valid; + if (IS_ROOT(dentry)) { + __nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); + goto out_valid_renew; + } + /* * Do a new lookup and check the dentry attributes. */ @@ -596,32 +599,29 @@ static int nfs_lookup_revalidate(struct dentry * dentry, int flags) goto out_bad; /* Inode number matches? */ - if (fattr.fileid != inode->i_ino) + if (NFS_FSID(inode) != fattr.fsid || + NFS_FILEID(inode) != fattr.fileid) goto out_bad; /* Filehandle matches? */ - if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh))) { - if (!list_empty(&dentry->d_subdirs)) - shrink_dcache_parent(dentry); - if (dentry->d_count < 2) - goto out_bad; - } + if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh))) + goto out_bad; /* Ok, remeber that we successfully checked it.. */ - nfs_renew_times(dentry); nfs_refresh_inode(inode, &fattr); + out_valid_renew: + nfs_renew_times(dentry); out_valid: return 1; out_bad: + d_drop(dentry); + if (!list_empty(&dentry->d_subdirs)) + shrink_dcache_parent(dentry); /* Purge readdir caches. */ if (dentry->d_parent->d_inode) { - invalidate_inode_pages(dentry->d_parent->d_inode); - nfs_flush_dircache(dentry->d_parent->d_inode); - } - if (inode && S_ISDIR(inode->i_mode)) { - invalidate_inode_pages(inode); - nfs_flush_dircache(inode); + nfs_zap_caches(dentry->d_parent->d_inode); + NFS_CACHEINV(dentry->d_parent->d_inode); } return 0; } @@ -649,21 +649,6 @@ static void nfs_dentry_delete(struct dentry *dentry) dentry->d_name.name, error); } -#ifdef NFS_PARANOIA - /* - * Sanity check: if the dentry has been unhashed and the - * inode still has users, we could have problems ... - */ - if (list_empty(&dentry->d_hash) && dentry->d_inode) { - struct inode *inode = dentry->d_inode; - int max_count = (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink); - if (inode->i_count > max_count) { -printk("nfs_dentry_delete: %s/%s: ino=%ld, count=%d, nlink=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -inode->i_ino, inode->i_count, inode->i_nlink); - } - } -#endif } static kmem_cache_t *nfs_fh_cachep; @@ -750,14 +735,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry) error = -EACCES; inode = nfs_fhget(dentry, &fhandle, &fattr); if (inode) { -#ifdef NFS_PARANOIA -if (inode->i_count > (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink)) { -printk("nfs_lookup: %s/%s ino=%ld in use, count=%d, nlink=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -inode->i_ino, inode->i_count, inode->i_nlink); -show_dentry(&inode->i_dentry); -} -#endif no_entry: d_add(dentry, inode); nfs_renew_times(dentry); @@ -779,14 +756,6 @@ static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, inode = nfs_fhget(dentry, fhandle, fattr); if (inode) { -#ifdef NFS_PARANOIA -if (inode->i_count > (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink)) { -printk("nfs_instantiate: %s/%s ino=%ld in use, count=%d, nlink=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -inode->i_ino, inode->i_count, inode->i_nlink); -show_dentry(&inode->i_dentry); -} -#endif d_instantiate(dentry, inode); nfs_renew_times(dentry); error = 0; @@ -803,16 +772,15 @@ show_dentry(&inode->i_dentry); static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) { int error; - struct nfs_sattr sattr; + struct iattr attr; struct nfs_fattr fattr; struct nfs_fh fhandle; dfprintk(VFS, "NFS: create(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); - sattr.mode = mode; - sattr.uid = sattr.gid = sattr.size = (unsigned) -1; - sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; + attr.ia_mode = mode; + attr.ia_valid = ATTR_MODE; /* * Invalidate the dir cache before the operation to avoid a race. @@ -820,7 +788,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) invalidate_inode_pages(dir); nfs_flush_dircache(dir); error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent), - dentry->d_name.name, &sattr, &fhandle, &fattr); + dentry->d_name.name, &attr, &fhandle, &fattr); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); if (error) @@ -834,23 +802,25 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) { int error; - struct nfs_sattr sattr; + struct iattr attr; struct nfs_fattr fattr; struct nfs_fh fhandle; dfprintk(VFS, "NFS: mknod(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); - sattr.mode = mode; - sattr.uid = sattr.gid = sattr.size = (unsigned) -1; - if (S_ISCHR(mode) || S_ISBLK(mode)) - sattr.size = rdev; /* get out your barf bag */ - sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; + attr.ia_mode = mode; + attr.ia_valid = ATTR_MODE; + /* FIXME: move this to a special nfs_proc_mknod() */ + if (S_ISCHR(mode) || S_ISBLK(mode)) { + attr.ia_size = rdev; /* get out your barf bag */ + attr.ia_valid |= ATTR_SIZE; + } invalidate_inode_pages(dir); nfs_flush_dircache(dir); error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent), - dentry->d_name.name, &sattr, &fhandle, &fattr); + dentry->d_name.name, &attr, &fhandle, &fattr); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); if (error) @@ -864,16 +834,15 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int error; - struct nfs_sattr sattr; + struct iattr attr; struct nfs_fattr fattr; struct nfs_fh fhandle; dfprintk(VFS, "NFS: mkdir(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); - sattr.mode = mode | S_IFDIR; - sattr.uid = sattr.gid = sattr.size = (unsigned) -1; - sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; + attr.ia_valid = ATTR_MODE; + attr.ia_mode = mode | S_IFDIR; /* * Always drop the dentry, we can't always depend on @@ -885,7 +854,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) invalidate_inode_pages(dir); nfs_flush_dircache(dir); error = nfs_proc_mkdir(NFS_DSERVER(dentry), NFS_FH(dentry->d_parent), - dentry->d_name.name, &sattr, &fhandle, &fattr); + dentry->d_name.name, &attr, &fhandle, &fattr); if (!error) dir->i_nlink++; return error; @@ -898,13 +867,6 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) dfprintk(VFS, "NFS: rmdir(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); -#ifdef NFS_PARANOIA -if (dentry->d_inode->i_count > 1) -printk("nfs_rmdir: %s/%s inode busy?? i_count=%d, i_nlink=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -dentry->d_inode->i_count, dentry->d_inode->i_nlink); -#endif - invalidate_inode_pages(dir); nfs_flush_dircache(dir); error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dentry->d_parent), @@ -1082,12 +1044,6 @@ dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count); #endif goto out; } -#ifdef NFS_PARANOIA -if (inode && inode->i_count > inode->i_nlink) -printk("nfs_safe_remove: %s/%s inode busy?? i_count=%d, i_nlink=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -inode->i_count, inode->i_nlink); -#endif /* * Unhash the dentry while we remove the file ... */ @@ -1141,7 +1097,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { - struct nfs_sattr sattr; + struct iattr attr; int error; dfprintk(VFS, "NFS: symlink(%x/%ld, %s, %s)\n", @@ -1160,9 +1116,8 @@ dentry->d_parent->d_name.name, dentry->d_name.name); * Fill in the sattr for the call. * Note: SunOS 4.1.2 crashes if the mode isn't initialized! */ - sattr.mode = S_IFLNK | S_IRWXUGO; - sattr.uid = sattr.gid = sattr.size = (unsigned) -1; - sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; + attr.ia_valid = ATTR_MODE; + attr.ia_mode = S_IFLNK | S_IRWXUGO; /* * Drop the dentry in advance to force a new lookup. @@ -1173,7 +1128,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name); invalidate_inode_pages(dir); nfs_flush_dircache(dir); error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dentry->d_parent), - dentry->d_name.name, symname, &sattr); + dentry->d_name.name, symname, &attr); if (!error) { nfs_renew_times(dentry->d_parent); } else if (error == -EEXIST) { @@ -1332,13 +1287,6 @@ do_rename: * To prevent any new references to the target during the rename, * we unhash the dentry and free the inode in advance. */ -#ifdef NFS_PARANOIA -if (new_inode && - new_inode->i_count > (S_ISDIR(new_inode->i_mode) ? 1 : new_inode->i_nlink)) -printk("nfs_rename: %s/%s inode busy?? i_count=%d, i_nlink=%d\n", -new_dentry->d_parent->d_name.name, new_dentry->d_name.name, -new_inode->i_count, new_inode->i_nlink); -#endif if (!list_empty(&new_dentry->d_hash)) { d_drop(new_dentry); rehash = update; |