patch for 2.0.30 ncpfs -- testers needed!

Bill Hawes (whawes@star.net)
Thu, 24 Jul 1997 13:29:53 -0400


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

I've attached a patch for 2.0.30 ncpfs to fix some inode-related
problems, and need some testers with Novell servers. The patch has been
tested by one user on a high-volume Novell server, and it cleared up a
number of problems he was having.

The patch was originally developed in conjunction with a general inode
patch I'm working on, but the changes to ncpfs should work independently
of the other changes.

So, if you're using a Novell server, please check this out and let me
know of any problems.

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

--- linux-2.0.30/fs/ncpfs/inode.c.old Sat Nov 30 05:21:21 1996
+++ linux-2.0.30/fs/ncpfs/inode.c Tue Jul 22 17:24:35 1997
@@ -125,27 +125,35 @@
}
}

+/*
+ * WSH 07/08/97: Defer release of inode and file structures until inode has
+ * been cleared. This avoids a race condition in case the inode is put back
+ * in use before being cleared.
+ */
static void
ncp_put_inode(struct inode *inode)
{
- struct nw_file_info *finfo = NCP_FINFO(inode);
- struct super_block *sb = inode->i_sb;
+ struct super_block *sb = inode->i_sb;
+ struct ncp_server *server = NCP_SERVER(inode);
+ struct ncp_inode_info *iinfo = NCP_INOP(inode);
+ struct nw_file_info *finfo = NCP_FINFO(inode);

+ /*
+ * This operation may block, so we lock before checking the count.
+ */
lock_super(sb);
- if (finfo->opened != 0)
- {
- if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0)
- {
- /* We can't do anything but complain. */
- printk("ncp_put_inode: could not close\n");
- }
- }

+ if (inode->i_count > 1) {
+printk("ncp_put_inode: inode in use device %s, inode %ld, count=%d\n",
+kdevname(inode->i_dev), inode->i_ino, inode->i_count);
+ goto unlock;
+ }
+
DDPRINTK("ncp_put_inode: put %s\n",
- finfo->i.entryName);
-
- ncp_free_inode_info(NCP_INOP(inode));
-
+ finfo->i.entryName);
+ /*
+ * This operation should never block.
+ */
if (S_ISDIR(inode->i_mode))
{
DDPRINTK("ncp_put_inode: put directory %ld\n",
@@ -154,6 +162,28 @@
}

clear_inode(inode);
+
+ /*
+ * After clearing the inode i_count will be 0 in 2.0.xx kernels.
+ * To keep the inode from being reused as free if we block while
+ * closing the file, increment i_count temporarily.
+ */
+ inode->i_count++;
+
+ if (finfo->opened != 0)
+ {
+ if (ncp_close_file(server, finfo->file_handle) != 0)
+ {
+ /* We can't do anything but complain. */
+ printk("ncp_put_inode: could not close %s\n",
+ finfo->i.entryName);
+ }
+ }
+
+ ncp_free_inode_info(iinfo);
+ inode->i_count--;
+
+unlock:
unlock_super(sb);
}

--- linux-2.0.30/fs/ncpfs/dir.c.old Sat Nov 30 05:21:21 1996
+++ linux-2.0.30/fs/ncpfs/dir.c Mon Jul 14 12:34:26 1997
@@ -1067,7 +1067,8 @@
}
if (ncp_find_dir_inode(dir, name) != NULL)
{
- iput(dir);
+ /* WSH: A failure here results in two calls to iput() */
+ /* iput(dir); */
error = -EBUSY;
}
else
@@ -1115,7 +1116,8 @@
}
if (ncp_find_dir_inode(dir, name) != NULL)
{
- iput(dir);
+ /* WSH: A failure here results in two calls to iput() */
+ /* iput(dir); */
error = -EBUSY;
}
else

--------------B53FFDCD46870EB4A8DB38BB--