lkml.org 
[lkml]   [1998]   [Jan]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectpatch for 2.1.76 nfs client
The attached patch reworks the NFS rename procedure to release the
target inode in advance, following the model used in unlink and rmdir.
This should correct the last known cause of busy inodes after unlinking
a file on the server. It also implicitly handles the case of pending
writes to the target inode, which we weren't testing for previously.

I've also made a minor change to the code to detect invalid fattrs after
a mkdir, to work around problems in certain servers. The fattr mtime
field is now initialized to -1, and if it doesn't change the fattr is
assumed to be invalid.

The next set of NFS patches will address the problem with filehandles
for hardlinks, and will probably be much more extensive. Since it may
take a while to get everything working again, I wanted to release these
changes for testing now.

Regards,
Bill--- linux-2.1.76/fs/nfs/dir.c.old Tue Dec 30 16:08:59 1997
+++ linux-2.1.76/fs/nfs/dir.c Wed Dec 31 18:09:13 1997
@@ -411,7 +411,7 @@
int error;

dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
-#ifdef NFS_DEBUG
+#ifdef NFS_DEBUG_VERBOSE
printk("nfs_dentry_delete: unlinking %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
#endif
@@ -652,6 +652,7 @@
sattr.mode = mode;
sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
+ fattr.mtime.seconds = (unsigned) -1;

nfs_invalidate_dircache(dir);
error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
@@ -659,14 +660,14 @@
if (!error) {
/*
* Some AIX servers reportedly fail to fill out the fattr.
- * Check for a bad mode value and complain, then drop the
- * dentry to force a new lookup.
+ * If the modify time hasn't been set, we drop the dentry
+ * to force a new lookup.
*/
- if (!S_ISDIR(fattr.mode)) {
+ if (fattr.mtime.seconds == (unsigned) -1) {
static int complain = 0;
+ /* N.B. Make this a flag in the superblock */
if (!complain++)
- printk("NFS: buggy server! fattr mode=%x\n",
- fattr.mode);
+ printk("NFS: no fattr after mkdir!\n");
goto drop;
}
error = nfs_instantiate(dentry, &fhandle, &fattr);
@@ -1109,10 +1110,8 @@
* First check whether the target is busy ... we can't
* safely do _any_ rename if the target is in use.
*/
- if (new_dentry->d_count > 1) {
- if (new_inode && S_ISDIR(new_inode->i_mode))
- shrink_dcache_parent(new_dentry);
- }
+ if (new_dentry->d_count > 1 && !list_empty(&new_dentry->d_subdirs))
+ shrink_dcache_parent(new_dentry);
error = -EBUSY;
if (new_dentry->d_count > 1) {
#ifdef NFS_PARANOIA
@@ -1176,28 +1175,33 @@

do_rename:
/*
- * We must prevent any new references to the target while
- * the rename is in progress, so we unhash the dentry.
+ * 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;
}
+ if (new_inode) {
+ d_delete(new_dentry);
+ }
+
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);
- if (rehash) {
- d_add(new_dentry, new_inode);
- }
-#ifdef NFS_PARANOIA
-if (new_dentry->d_count > 1)
-printk("nfs_rename: %s/%s busy after rename, d_count=%d\n",
-new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count);
-#endif
if (!error) {
/* Update the dcache if needed */
+ if (rehash)
+ d_add(new_dentry, NULL);
if (update)
d_move(old_dentry, new_dentry);
}
\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.020 / U:1.324 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site