From f6197681c9ba3a56c21c1289568cdf8ad8705b0b Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 26 Aug 2015 20:37:04 -0700 Subject: [PATCH] hammer2 - Fix unlink/reclaim panic, add macro for "BOOT" key * Fix confusion where an inode would erronously be placed on the unlinkq even though it was not moved to the hidden directory. * Add HAMMER2_BOOT_KEY for use by libstand. --- sys/vfs/hammer2/hammer2.h | 2 +- sys/vfs/hammer2/hammer2_chain.c | 2 +- sys/vfs/hammer2/hammer2_disk.h | 1 + sys/vfs/hammer2/hammer2_inode.c | 7 ++++++- sys/vfs/hammer2/hammer2_vnops.c | 9 ++++++--- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/sys/vfs/hammer2/hammer2.h b/sys/vfs/hammer2/hammer2.h index 6bc7e9ad3e..a689bb53c9 100644 --- a/sys/vfs/hammer2/hammer2.h +++ b/sys/vfs/hammer2/hammer2.h @@ -727,7 +727,7 @@ typedef struct hammer2_inode hammer2_inode_t; #define HAMMER2_INODE_RENAME_INPROG 0x0004 #define HAMMER2_INODE_ONRBTREE 0x0008 #define HAMMER2_INODE_RESIZED 0x0010 /* requires inode_fsync */ -#define HAMMER2_INODE_UNUSED0020 0x0020 +#define HAMMER2_INODE_ISDELETED 0x0020 /* deleted, not in ihidden */ #define HAMMER2_INODE_ISUNLINKED 0x0040 #define HAMMER2_INODE_METAGOOD 0x0080 /* inode meta-data good */ diff --git a/sys/vfs/hammer2/hammer2_chain.c b/sys/vfs/hammer2/hammer2_chain.c index 90033550f7..ede3535f98 100644 --- a/sys/vfs/hammer2/hammer2_chain.c +++ b/sys/vfs/hammer2/hammer2_chain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The DragonFly Project. All rights reserved. + * Copyright (c) 2011-2015 The DragonFly Project. All rights reserved. * * This code is derived from software contributed to The DragonFly Project * by Matthew Dillon diff --git a/sys/vfs/hammer2/hammer2_disk.h b/sys/vfs/hammer2/hammer2_disk.h index e750df604f..7c479532ed 100644 --- a/sys/vfs/hammer2/hammer2_disk.h +++ b/sys/vfs/hammer2/hammer2_disk.h @@ -450,6 +450,7 @@ typedef uint32_t hammer2_crc32_t; #define HAMMER2_DIRHASH_FORCED 0x0000000000008000ULL /* bit forced on */ #define HAMMER2_SROOT_KEY 0x0000000000000000ULL /* volume to sroot */ +#define HAMMER2_BOOT_KEY 0xd9b36ce135528000ULL /* sroot to BOOT PFS */ /************************************************************************ * DMSG SUPPORT * diff --git a/sys/vfs/hammer2/hammer2_inode.c b/sys/vfs/hammer2/hammer2_inode.c index 0c4840b118..2d286f182c 100644 --- a/sys/vfs/hammer2/hammer2_inode.c +++ b/sys/vfs/hammer2/hammer2_inode.c @@ -1089,8 +1089,10 @@ hammer2_inode_unlink_finisher(hammer2_inode_t *ip, int isopen) */ if (ip->meta.nlinks == 1) { atomic_set_int(&ip->flags, HAMMER2_INODE_ISUNLINKED); - if (isopen == 0) + if (isopen == 0) { + atomic_set_int(&ip->flags, HAMMER2_INODE_ISDELETED); return 0; + } } hammer2_inode_modify(ip); @@ -1360,6 +1362,8 @@ hammer2_inode_run_unlinkq(hammer2_pfs_t *pmp) error = hammer2_xop_collect(&xop->head, 0); hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); + atomic_clear_int(&ip->flags, HAMMER2_INODE_ISDELETED); + hammer2_inode_unlock(ip); hammer2_inode_drop(ip); /* ipul ref */ @@ -1389,6 +1393,7 @@ hammer2_inode_xop_create(hammer2_xop_t *arg, int clindex) int cache_index = -1; int error; + if (hammer2_debug & 0x0001) kprintf("inode_create lhc %016jx clindex %d\n", xop->lhc, clindex); diff --git a/sys/vfs/hammer2/hammer2_vnops.c b/sys/vfs/hammer2/hammer2_vnops.c index ff943f30d0..1a105525ea 100644 --- a/sys/vfs/hammer2/hammer2_vnops.c +++ b/sys/vfs/hammer2/hammer2_vnops.c @@ -164,15 +164,18 @@ hammer2_vop_reclaim(struct vop_reclaim_args *ap) vclrisdirty(vp); /* - * Once reclaimed the inode is disconnected from the normal flush - * mechanism and must be tracked + * An unlinked inode may have been relinked to the ihidden directory. + * This occurs if the inode was unlinked while open. Reclamation of + * these inodes requires processing we cannot safely do here so add + * the inode to the unlinkq in that situation. * * A reclaim can occur at any time so we cannot safely start a * transaction to handle reclamation of unlinked files. Instead, * the ip is left with a reference and placed on a linked list and * handled later on. */ - if (ip->flags & HAMMER2_INODE_ISUNLINKED) { + if ((ip->flags & HAMMER2_INODE_ISUNLINKED) && + (ip->flags & HAMMER2_INODE_ISDELETED) == 0) { hammer2_inode_unlink_t *ipul; ipul = kmalloc(sizeof(*ipul), pmp->minode, M_WAITOK | M_ZERO); -- 2.41.0