Re: 2.0.30+pre2 Oops with smbfs

Bill Hawes (whawes@star.net)
Fri, 01 Aug 1997 11:46:19 -0400


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

Mark Cooke wrote:
> I have been using 2.0.30+pre2 for 70odd days before the following oopses
> preceeded a hard lockup. Today I'd added an smbfs mount (for the first
> time with pre2) to an NT4.0 SP3+all hot fixes machine.
>
> After the reboot, I remounted the smbfs share and almost immediately had
> another oops.

I took a look at the smbfs code and found a few possible race
conditions, so hopefully the attached patch will help your problem. I'm
not running smbfs and so haven't tested the code (except to compile it),
but it should be safe.

The changes in smb_put_inode() are similar to those that helped with an
ncpfs problem.

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

--- linux-2.0.30/fs/smbfs/sock.c.old Sun Apr 27 15:53:57 1997
+++ linux-2.0.30/fs/smbfs/sock.c Fri Aug 1 11:08:35 1997
@@ -338,6 +338,8 @@
DPRINTK("smb_receive: Increase packet size from %d to %d\n",
server->packet_size, len + 4);
smb_vfree(server->packet);
+ server->packet = NULL;
+
server->packet_size = 0;
server->packet = smb_vmalloc(len + 4);
if (server->packet == NULL)
--- linux-2.0.30/fs/smbfs/proc.c.old Sun Apr 27 15:53:57 1997
+++ linux-2.0.30/fs/smbfs/proc.c Fri Aug 1 10:34:49 1997
@@ -1685,6 +1685,7 @@
if (server->packet != NULL)
{
smb_vfree(server->packet);
+ server->packet = NULL;
server->packet_size = 0;
}
server->packet = smb_vmalloc(max_xmit);
@@ -1920,6 +1921,7 @@

/* Now make a new packet with the correct size. */
smb_vfree(server->packet);
+ server->packet = NULL;

server->packet = smb_vmalloc(server->max_xmit);
if (server->packet == NULL)
--- linux-2.0.30/fs/smbfs/inode.c.old Sun Dec 1 08:58:05 1996
+++ linux-2.0.30/fs/smbfs/inode.c Fri Aug 1 11:32:57 1997
@@ -96,10 +96,23 @@
struct smb_server *server = SMB_SERVER(inode);
struct smb_inode_info *info = SMB_INOP(inode);

+ if (inode->i_count > 1) {
+ printk("smb_put_inode: in use device %s, inode %ld count=%d\n",
+ kdevname(inode->i_dev), inode->i_ino, inode->i_count);
+ return;
+ }
+
if (S_ISDIR(inode->i_mode))
{
smb_invalid_dir_cache(inode->i_ino);
}
+ clear_inode(inode);
+
+ /*
+ * We don't want the inode to be reused as free if we block here,
+ * so temporarily increment i_count.
+ */
+ inode->i_count++;
if (finfo->opened != 0)
{
if (smb_proc_close(server, finfo->fileid, inode->i_mtime))
@@ -109,7 +122,7 @@
}
}
smb_free_inode_info(info);
- clear_inode(inode);
+ inode->i_count--;
}

static void

--------------48C51173B97447E9A68D9EC6--