From 752d77b5561bfb6b70e203d3bfcddd93c9dffa12 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Thu, 29 Aug 2013 15:33:49 -0500 Subject: [PATCH] namei: IH_REALLYCLOSE special inode on delete 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 Tested-by: BuildBot --- src/vol/namei_ops.c | 11 +++++++++-- src/vol/purge.c | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/vol/namei_ops.c b/src/vol/namei_ops.c index bae4039f6..2260b4bb1 100644 --- a/src/vol/namei_ops.c +++ b/src/vol/namei_ops.c @@ -1182,6 +1182,15 @@ namei_dec(IHandle_t * ih, Inode ino, int p1) 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. @@ -1195,8 +1204,6 @@ namei_dec(IHandle_t * ih, Inode ino, int p1) (void)namei_RemoveDataDirectories(&name); } } - FDH_REALLYCLOSE(fdP); - IH_RELEASE(tmp); } else { /* Get a file descriptor handle for this Inode */ fdP = IH_OPEN(ih); diff --git a/src/vol/purge.c b/src/vol/purge.c index c46eb375d..77fe59ed4 100644 --- a/src/vol/purge.c +++ b/src/vol/purge.c @@ -217,13 +217,16 @@ PurgeHeader(Volume * vp) 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 } -- 2.39.5