Re: Problem with nfs_silly_delete

Bill Hawes (whawes@star.net)
Sun, 14 Sep 1997 21:49:22 -0400


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

Alan Cox wrote:
>
> Sep 14 20:58:55 roadrunner kernel: NFS nfs_silly_delete failed (err = 2)
> Sep 14 20:58:55 roadrunner kernel: Unable to handle kernel NULL pointer dereference at virtual address 0000001a
>
> It seems any failure case for nfs_silly_delete crashes the kernel

Hi Alan,

Could you give the attached patch a go? It should take care of the
silly_delete problem.

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

--- fs/nfs/dir.c.old Wed Sep 10 09:21:27 1997
+++ fs/nfs/dir.c Sun Sep 14 21:40:51 1997
@@ -642,16 +642,14 @@
error = nfs_proc_rename(NFS_SERVER(dir),
NFS_FH(dir), dentry->d_name.name,
NFS_FH(dir), silly);
- if (error) {
- dput(sdentry);
- return error;
+ if (!error) {
+ nfs_invalidate_dircache(dir);
+ d_move(dentry, sdentry);
+ dentry->d_flags |= DCACHE_NFSFS_RENAMED;
+ /* If we return 0 we don't unlink */
}
- nfs_invalidate_dircache(dir);
- d_move(dentry, sdentry);
dput(sdentry);
- dentry->d_flags |= DCACHE_NFSFS_RENAMED;
-
- return 0; /* don't unlink */
+ return error;
}

static void nfs_silly_delete(struct dentry *dentry)
@@ -670,8 +668,17 @@
if (error < 0)
printk("NFS " __FUNCTION__ " failed (err = %d)\n",
-error);
- dentry->d_inode->i_nlink --;
+ if (dentry->d_inode)
+ dentry->d_inode->i_nlink --;
+ else
+ printk("nfs_silly_delete: negative dentry %s/%s\n",
+ dentry->d_parent->d_name.name,
+ dentry->d_name.name);
nfs_invalidate_dircache(dir);
+ /*
+ * The dentry is unhashed, but we want to make it negative.
+ */
+ d_delete(dentry);
}
}

@@ -700,20 +707,17 @@

error = nfs_sillyrename(dir, dentry);

- if (error == -EBUSY) {
- return -EBUSY;
- } else if (error < 0) {
+ if (error && error != -EBUSY) {
error = nfs_proc_remove(NFS_SERVER(dir),
NFS_FH(dir), dentry->d_name.name);
- if (error < 0)
- return error;
-
- dentry->d_inode->i_nlink --;
- nfs_invalidate_dircache(dir);
- d_delete(dentry);
+ if (!error) {
+ dentry->d_inode->i_nlink --;
+ nfs_invalidate_dircache(dir);
+ d_delete(dentry);
+ }
}

- return 0;
+ return error;
}

static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)

--------------C49832E423205943F8A844D2--