When we delete a special inode, we should IH_REALLYCLOSE it, to ensure
no other cached file handles are open for that special inode. However,
currently PurgeHeader_r does this, and then IH_DECs the special
inodes. On namei, calling IH_DEC on a special inode causes the inode
to be opened, so we create a cached file handle right after we closed
all cached file handles for that inode with IH_REALLYCLOSE.
Making namei IH_DEC not open an FdHandle_t for the given file is
non-trivial, at least when dec'ing the linktable. So instead, just
make namei IH_DEC itself issue the IH_REALLYCLOSE right before the
actual unlink() call.
With this, we can keep the cached file handle open for special inodes
until right before they are actually deleted, so we don't issue extra
unnecessary open()s and close()s.
Change-Id: I35b234ab429bc7cd0f29654cc8f854c82c961071
Reviewed-on: http://gerrit.openafs.org/10196
Reviewed-by: D Brashear <shadow@your-file-system.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
namei_UnlockLinkCount(fdP, (Inode) 0);
}
+ /* We should IH_REALLYCLOSE right before deleting the special file from
+ * disk, to ensure that somebody else cannot create a special inode,
+ * then IH_OPEN that special inode and get back a cached fd for the
+ * file we are deleting here (instead of an fd for the file they just
+ * created). */
+ IH_REALLYCLOSE(tmp);
+ FDH_REALLYCLOSE(fdP);
+ IH_RELEASE(tmp);
+
if ((code = OS_UNLINK(name.n_path)) == 0) {
if (type == VI_LINKTABLE) {
/* Try to remove directory. If it fails, that's ok.
(void)namei_RemoveDataDirectories(&name);
}
}
- FDH_REALLYCLOSE(fdP);
- IH_RELEASE(tmp);
} else {
/* Get a file descriptor handle for this Inode */
fdP = IH_OPEN(ih);
static void
PurgeHeader_r(Volume * vp)
{
+#ifndef AFS_NAMEI_ENV
+ /* namei opens and closes the given ihandle during IH_DEC, so don't try to
+ * also close it here */
IH_REALLYCLOSE(V_diskDataHandle(vp));
+#endif
IH_DEC(V_linkHandle(vp), vp->vnodeIndex[vLarge].handle->ih_ino, V_id(vp));
IH_DEC(V_linkHandle(vp), vp->vnodeIndex[vSmall].handle->ih_ino, V_id(vp));
IH_DEC(V_linkHandle(vp), vp->diskDataHandle->ih_ino, V_id(vp));
#ifdef AFS_NAMEI_ENV
/* And last, but not least, the link count table itself. */
- IH_REALLYCLOSE(V_linkHandle(vp));
IH_DEC(V_linkHandle(vp), vp->linkHandle->ih_ino, V_parentId(vp));
#endif
}