patch for 2.1.74 NFS client

Bill Hawes (whawes@star.net)
Sun, 21 Dec 1997 13:40:35 -0500


This is a multi-part message in MIME format.
--------------33E7EC8C83A33433B05D0ECB
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

This patch makes the "busy inode" messages a little smarter. The busy
inode test now compares the use count against i_nlink for files, and
against 1 for directories.

I've also made the dir cache invalidation more consistent by always
invalidating in advance of an operation that changes the directory.
Since such operations will be done with the parent directory semaphore
held, this will ensure that the directory cache won't be stale in
between the time when the server performs the operation and the reply is
received.

In nfs/inode.c, the mount now checks for errors from rpciod_up().

In write.c, I've enabled a warning message in the event a page is
already locked when we're trying to write it.

Regards,
Bill
--------------33E7EC8C83A33433B05D0ECB
Content-Type: text/plain; charset=us-ascii; name="nfs_client74-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="nfs_client74-patch"

--- linux-2.1.74/fs/nfs/dir.c.old Fri Dec 19 00:22:33 1997
+++ linux-2.1.74/fs/nfs/dir.c Sun Dec 21 14:22:14 1997
@@ -439,7 +439,8 @@
*/
if (list_empty(&dentry->d_hash) && dentry->d_inode) {
struct inode *inode = dentry->d_inode;
- if (inode->i_count > 1) {
+ 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);
@@ -499,7 +500,7 @@
inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
if (inode) {
#ifdef NFS_PARANOIA
-if (inode->i_count > 1)
+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);
@@ -511,6 +512,11 @@
error = 0;
}
}
+#ifdef NFS_PARANOIA
+if (error)
+printk("nfs_lookup: %s/%s failed, error=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, error);
+#endif
out:
return error;
}
@@ -555,7 +561,7 @@
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
if (inode) {
#ifdef NFS_PARANOIA
-if (inode->i_count > 1)
+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);
@@ -669,8 +675,9 @@
return -ENOENT;
}

+ error = -ENAMETOOLONG;
if (dentry->d_name.len > NFS_MAXNAMLEN)
- return -ENAMETOOLONG;
+ goto out;

/* For some reason mode doesn't have the S_IFDIR flag ... */
mode |= S_IFDIR;
@@ -702,6 +709,7 @@
drop:
d_drop(dentry);
}
+out:
return error;
}

@@ -876,11 +884,11 @@
goto out;
} while(sdentry->d_inode != NULL); /* need negative lookup */

+ nfs_invalidate_dircache(dir);
error = nfs_proc_rename(NFS_SERVER(dir),
NFS_FH(dir), dentry->d_name.name,
NFS_FH(dir), silly);
if (!error) {
- nfs_invalidate_dircache(dir);
nfs_renew_times(dentry);
d_move(dentry, sdentry);
dentry->d_flags |= DCACHE_NFSFS_RENAMED;
@@ -1036,10 +1044,10 @@
* can't instantiate the new inode.
*/
d_drop(dentry);
+ nfs_invalidate_dircache(dir);
error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir),
dentry->d_name.name, symname, &sattr);
if (!error) {
- nfs_invalidate_dircache(dir);
nfs_renew_times(dentry->d_parent);
} else if (error == -EEXIST) {
printk("nfs_proc_symlink: %s/%s already exists??\n",
@@ -1068,10 +1076,10 @@
if (dentry->d_name.len > NFS_MAXNAMLEN)
goto out;

+ nfs_invalidate_dircache(dir);
error = nfs_proc_link(NFS_SERVER(inode), NFS_FH(inode), NFS_FH(dir),
dentry->d_name.name);
if (!error) {
- nfs_invalidate_dircache(dir);
inode->i_count ++;
inode->i_nlink ++; /* no need to wait for nfs_refresh_inode() */
d_instantiate(dentry, inode);
@@ -1209,6 +1217,8 @@
d_drop(new_dentry);
rehash = update;
}
+ nfs_invalidate_dircache(new_dir);
+ nfs_invalidate_dircache(old_dir);
error = nfs_proc_rename(NFS_SERVER(old_dir),
NFS_FH(old_dir), old_dentry->d_name.name,
NFS_FH(new_dir), new_dentry->d_name.name);
@@ -1221,8 +1231,6 @@
new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count);
#endif
if (!error) {
- nfs_invalidate_dircache(new_dir);
- nfs_invalidate_dircache(old_dir);
/* Update the dcache if needed */
if (update)
d_move(old_dentry, new_dentry);
--- linux-2.1.74/fs/nfs/inode.c.old Fri Dec 19 00:22:33 1997
+++ linux-2.1.74/fs/nfs/inode.c Sat Dec 20 22:47:06 1997
@@ -260,12 +260,8 @@
server->client = clnt;

/* Fire up rpciod if not yet running */
-#ifdef RPCIOD_RESULT
- if (rpciod_up())
+ if (rpciod_up() != 0)
goto out_no_iod;
-#else
- rpciod_up();
-#endif

/*
* Keep the super block locked while we try to get
@@ -290,13 +286,11 @@
printk("nfs_read_super: get root inode failed\n");
iput(root_inode);
rpciod_down();
-#ifdef RPCIOD_RESULT
goto out_shutdown;

out_no_iod:
- printk("nfs_read_super: couldn't start rpciod!\n");
+ printk("NFS: couldn't start rpciod!\n");
out_shutdown:
-#endif
rpc_shutdown_client(server->client);
goto out_unlock;

--- linux-2.1.74/fs/nfs/write.c.old Fri Dec 19 00:22:33 1997
+++ linux-2.1.74/fs/nfs/write.c Sat Dec 20 22:47:06 1997
@@ -832,7 +832,7 @@
req->wb_flags |= NFS_WRITE_WANTLOCK;

if (WB_WANTLOCK(req) && test_and_set_bit(PG_locked, &page->flags)) {
- dprintk("NFS: page already locked in writeback_lock!\n");
+ printk("NFS: page already locked in writeback_lock!\n");
task->tk_timeout = 2 * HZ;
rpc_sleep_on(&write_queue, task, NULL, NULL);
return;

--------------33E7EC8C83A33433B05D0ECB--