patch-2.0.31 linux/fs/ncpfs/inode.c
Next file: linux/fs/pipe.c
Previous file: linux/fs/ncpfs/dir.c
Back to the patch index
Back to the overall index
- Lines: 80
- Date:
Tue Aug 5 09:33:12 1997
- Orig file:
v2.0.30/linux/fs/ncpfs/inode.c
- Orig date:
Sat Nov 30 02:21:21 1996
diff -u --recursive --new-file v2.0.30/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
@@ -125,27 +125,36 @@
}
}
+/*
+ * Defer release of inode_info and file_info structures until the inode
+ * has been cleared. This avoids a race condition allowing the inode to
+ * be put back in use before being cleared. Also, temporarily increment
+ * i_count after clear_inode() so that the inode can't be reused.
+ */
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 +163,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);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov