patch-2.3.23 linux/fs/nfs/dir.c
Next file: linux/fs/nfs/inode.c
Previous file: linux/fs/minix/truncate.c
Back to the patch index
Back to the overall index
- Lines: 323
- Date:
Tue Oct 19 10:22:19 1999
- Orig file:
v2.3.22/linux/fs/nfs/dir.c
- Orig date:
Thu Aug 26 13:05:40 1999
diff -u --recursive --new-file v2.3.22/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
@@ -308,8 +308,7 @@
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 @@
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 @@
* 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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_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_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 @@
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 @@
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 @@
#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_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 @@
* 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 @@
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 @@
* 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;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)