From 159c3ca2e6aee2377fbe52f9e738c70c7e930e51 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 17 Jun 2015 00:12:21 -0700 Subject: [PATCH] hammer2 - Refactor frontend part 5/many * Separate the inode lock from the cluster lock. Add a new (possibly temporary) API function hammer2_inode_cluster() which handles initial ip cluster locking. * Begin using the meta-data cached in ip->meta and ip->bref. * Cache bref statistics in ip->bref (might be temporary). --- sys/vfs/hammer2/TODO | 3 + sys/vfs/hammer2/hammer2.h | 6 +- sys/vfs/hammer2/hammer2_inode.c | 69 +++++++--------- sys/vfs/hammer2/hammer2_iocom.c | 3 +- sys/vfs/hammer2/hammer2_ioctl.c | 27 +++++-- sys/vfs/hammer2/hammer2_strategy.c | 6 +- sys/vfs/hammer2/hammer2_subr.c | 4 +- sys/vfs/hammer2/hammer2_syncthr.c | 5 +- sys/vfs/hammer2/hammer2_vfsops.c | 36 +++++++-- sys/vfs/hammer2/hammer2_vnops.c | 121 ++++++++++++++++------------- 10 files changed, 164 insertions(+), 116 deletions(-) diff --git a/sys/vfs/hammer2/TODO b/sys/vfs/hammer2/TODO index c196b1b9cf..9634e8cf8d 100644 --- a/sys/vfs/hammer2/TODO +++ b/sys/vfs/hammer2/TODO @@ -1,3 +1,6 @@ + +* Convert xops and hammer2_update_spans() from cluster back into chain calls + * syncthr leaves inode locks for entire sync, which is wrong. * recovery scan vs unmount. At the moment an unmount does its flushes, diff --git a/sys/vfs/hammer2/hammer2.h b/sys/vfs/hammer2/hammer2.h index 4928f43624..e54b82197f 100644 --- a/sys/vfs/hammer2/hammer2.h +++ b/sys/vfs/hammer2/hammer2.h @@ -679,6 +679,7 @@ struct hammer2_inode { u_int refs; /* +vpref, +flushref */ uint8_t comp_heuristic; hammer2_inode_meta_t meta; /* copy of meta-data */ + hammer2_blockref_t bref; /* copy of bref statistics */ }; typedef struct hammer2_inode hammer2_inode_t; @@ -1063,8 +1064,9 @@ extern int write_thread_wakeup; int hammer2_signal_check(time_t *timep); const char *hammer2_error_str(int error); -hammer2_cluster_t *hammer2_inode_lock(hammer2_inode_t *ip, int how); +void hammer2_inode_lock(hammer2_inode_t *ip, int how); void hammer2_inode_unlock(hammer2_inode_t *ip, hammer2_cluster_t *cluster); +hammer2_cluster_t *hammer2_inode_cluster(hammer2_inode_t *ip, int how); hammer2_mtx_state_t hammer2_inode_lock_temp_release(hammer2_inode_t *ip); void hammer2_inode_lock_temp_restore(hammer2_inode_t *ip, hammer2_mtx_state_t ostate); @@ -1076,7 +1078,7 @@ void hammer2_dev_shlock(hammer2_dev_t *hmp); void hammer2_dev_unlock(hammer2_dev_t *hmp); int hammer2_get_dtype(const hammer2_inode_data_t *ipdata); -int hammer2_get_vtype(const hammer2_inode_data_t *ipdata); +int hammer2_get_vtype(uint8_t type); u_int8_t hammer2_get_obj_type(enum vtype vtype); void hammer2_time_to_timespec(u_int64_t xtime, struct timespec *ts); u_int64_t hammer2_timespec_to_time(const struct timespec *ts); diff --git a/sys/vfs/hammer2/hammer2_inode.c b/sys/vfs/hammer2/hammer2_inode.c index 6f97bc0d1e..dc9f8bc614 100644 --- a/sys/vfs/hammer2/hammer2_inode.c +++ b/sys/vfs/hammer2/hammer2_inode.c @@ -98,11 +98,9 @@ hammer2_inode_cmp(hammer2_inode_t *ip1, hammer2_inode_t *ip2) * accesses to one node. This flag is automatically set if the inode * is locked with HAMMER2_RESOLVE_SHARED. */ -hammer2_cluster_t * +void hammer2_inode_lock(hammer2_inode_t *ip, int how) { - hammer2_cluster_t *cluster; - hammer2_inode_ref(ip); /* @@ -114,18 +112,22 @@ hammer2_inode_lock(hammer2_inode_t *ip, int how) } else { hammer2_mtx_ex(&ip->lock); } +} + +/* + * Create a locked copy of ip->cluster. Note that the copy will have a + * ref on the cluster AND its chains and we don't want a second ref to + * either when we lock it. + * + * Exclusive inode locks set the template focus chain in (ip) + * as a hint. Cluster locks can ALWAYS replace the focus in the + * working copy if the hint does not work out, so beware. + */ +hammer2_cluster_t * +hammer2_inode_cluster(hammer2_inode_t *ip, int how) +{ + hammer2_cluster_t *cluster; - /* - * Create a copy of ip->cluster and lock it. Note that the copy - * will have a ref on the cluster AND its chains and we don't want - * a second ref to either when we lock it. - * - * The copy will not have a focus until it is locked. - * - * Exclusive inode locks set the template focus chain in (ip) - * as a hint. Cluster locks can ALWAYS replace the focus in the - * working copy if the hint does not work out, so beware. - */ cluster = hammer2_cluster_copy(&ip->cluster); hammer2_cluster_lock(cluster, how); hammer2_cluster_resolve(cluster); @@ -138,26 +140,7 @@ hammer2_inode_lock(hammer2_inode_t *ip, int how) if ((how & HAMMER2_RESOLVE_SHARED) == 0) ip->cluster.focus = cluster->focus; - /* - * Initialize pmp->inode_tid and pmp->modify_tid on first access - * to the root of mount that resolves good. - * XXX probably not the best place for this. - */ - if (ip->pmp->inode_tid == 0 && - cluster->error == 0 && cluster->focus) { - const hammer2_inode_data_t *ripdata; - hammer2_pfs_t *pmp = ip->pmp; - hammer2_blockref_t bref; - - ripdata = &hammer2_cluster_rdata(cluster)->ipdata; - hammer2_cluster_bref(cluster, &bref); - pmp->inode_tid = ripdata->meta.pfs_inum + 1; - pmp->modify_tid = bref.modify_tid; - kprintf("PMP focus good set nextino=%ld mod=%016jx\n", - pmp->inode_tid, pmp->modify_tid); - - } - return (cluster); + return cluster; } void @@ -554,12 +537,13 @@ again: if (cluster) { nipdata = &hammer2_cluster_rdata(cluster)->ipdata; nip->meta = nipdata->meta; + hammer2_cluster_bref(cluster, &nip->bref); atomic_set_int(&nip->flags, HAMMER2_INODE_METAGOOD); hammer2_inode_repoint(nip, NULL, cluster); } else { nip->meta.inum = 1; /* PFS inum is always 1 XXX */ /* mtime will be updated when a cluster is available */ - atomic_set_int(&nip->flags, HAMMER2_INODE_METAGOOD); + atomic_set_int(&nip->flags, HAMMER2_INODE_METAGOOD);/*XXX*/ } nip->pip = dip; /* can be NULL */ @@ -645,7 +629,8 @@ hammer2_inode_create(hammer2_trans_t *trans, hammer2_inode_t *dip, * NOTE: hidden inodes do not have iterators. */ retry: - cparent = hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(dip, HAMMER2_RESOLVE_ALWAYS); dipdata = &hammer2_cluster_rdata(cparent)->ipdata; dip_uid = dipdata->meta.uid; dip_gid = dipdata->meta.gid; @@ -1315,7 +1300,8 @@ again: /* * Search for the filename in the directory */ - cparent = hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(dip, HAMMER2_RESOLVE_ALWAYS); cluster = hammer2_cluster_lookup(cparent, &key_next, lhc, lhc + HAMMER2_DIRHASH_LOMASK, 0); while (cluster) { @@ -1606,7 +1592,8 @@ hammer2_inode_install_hidden(hammer2_pfs_t *pmp) * and data chains inherit from their respective file inode *_algo * fields. */ - cparent = hammer2_inode_lock(pmp->iroot, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(pmp->iroot, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(pmp->iroot, HAMMER2_RESOLVE_ALWAYS); ripdata = &hammer2_cluster_rdata(cparent)->ipdata; dip_check_algo = ripdata->meta.check_algo; dip_comp_algo = ripdata->meta.comp_algo; @@ -1699,7 +1686,8 @@ hammer2_inode_move_to_hidden(hammer2_trans_t *trans, KKASSERT(pmp->ihidden != NULL); hammer2_cluster_delete(trans, *cparentp, *clusterp, 0); - dcluster = hammer2_inode_lock(pmp->ihidden, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(pmp->ihidden, HAMMER2_RESOLVE_ALWAYS); + dcluster = hammer2_inode_cluster(pmp->ihidden, HAMMER2_RESOLVE_ALWAYS); error = hammer2_inode_connect(trans, NULL/*XXX*/, clusterp, 0, pmp->ihidden, dcluster, @@ -1948,7 +1936,8 @@ hammer2_hardlink_find(hammer2_inode_t *dip, cparent = NULL; while ((ip = pip) != NULL) { - cparent = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); hammer2_inode_drop(ip); /* loop */ KKASSERT(hammer2_cluster_type(cparent) == HAMMER2_BREF_TYPE_INODE); diff --git a/sys/vfs/hammer2/hammer2_iocom.c b/sys/vfs/hammer2/hammer2_iocom.c index 9d8963db86..4c86f1fd5e 100644 --- a/sys/vfs/hammer2/hammer2_iocom.c +++ b/sys/vfs/hammer2/hammer2_iocom.c @@ -298,7 +298,8 @@ hammer2_update_spans(hammer2_dev_t *hmp, kdmsg_state_t *state) * up later on. */ spmp = hmp->spmp; - cparent = hammer2_inode_lock(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); cluster = hammer2_cluster_lookup(cparent, &key_next, HAMMER2_KEY_MIN, HAMMER2_KEY_MAX, diff --git a/sys/vfs/hammer2/hammer2_ioctl.c b/sys/vfs/hammer2/hammer2_ioctl.c index c671cfbe5c..2874306c27 100644 --- a/sys/vfs/hammer2/hammer2_ioctl.c +++ b/sys/vfs/hammer2/hammer2_ioctl.c @@ -380,8 +380,12 @@ hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data) error = 0; hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ pfs = data; - cparent = hammer2_inode_lock(hmp->spmp->iroot, HAMMER2_RESOLVE_ALWAYS); - rcluster = hammer2_inode_lock(ip->pmp->iroot, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(hmp->spmp->iroot, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(hmp->spmp->iroot, + HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip->pmp->iroot, HAMMER2_RESOLVE_ALWAYS); + rcluster = hammer2_inode_cluster(ip->pmp->iroot, + HAMMER2_RESOLVE_ALWAYS); /* * Search for the first key or specific key. Remember that keys @@ -473,8 +477,11 @@ hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data) error = 0; hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ pfs = data; - cparent = hammer2_inode_lock(hmp->spmp->iroot, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); + hammer2_inode_lock(hmp->spmp->iroot, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + cparent = hammer2_inode_cluster(hmp->spmp->iroot, + HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); pfs->name[sizeof(pfs->name) - 1] = 0; len = strlen(pfs->name); @@ -627,7 +634,8 @@ hammer2_ioctl_pfs_snapshot(hammer2_inode_t *ip, void *data) hammer2_trans_init(&trans, ip->pmp, HAMMER2_TRANS_ISFLUSH | HAMMER2_TRANS_NEWINODE); - cparent = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); error = hammer2_cluster_snapshot(&trans, cparent, pfs); hammer2_inode_unlock(ip, cparent); hammer2_trans_done(&trans); @@ -648,8 +656,10 @@ hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data) ino = data; - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); if (cluster->error) { error = EIO; } else { @@ -681,7 +691,8 @@ hammer2_ioctl_inode_set(hammer2_inode_t *ip, void *data) int dosync = 0; hammer2_trans_init(&trans, ip->pmp, 0); - cparent = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); ripdata = &hammer2_cluster_rdata(cparent)->ipdata; if (ino->ip_data.meta.check_algo != ripdata->meta.check_algo) { diff --git a/sys/vfs/hammer2/hammer2_strategy.c b/sys/vfs/hammer2/hammer2_strategy.c index a8d23478a4..6d2e7edf6d 100644 --- a/sys/vfs/hammer2/hammer2_strategy.c +++ b/sys/vfs/hammer2/hammer2_strategy.c @@ -249,8 +249,10 @@ hammer2_strategy_read(struct vop_strategy_args *ap) /* * Lookup the file offset. */ - cparent = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); cluster = hammer2_cluster_lookup(cparent, &key_dummy, lbase, lbase, HAMMER2_LOOKUP_NODATA | diff --git a/sys/vfs/hammer2/hammer2_subr.c b/sys/vfs/hammer2/hammer2_subr.c index 808a8fc18a..0f161e7454 100644 --- a/sys/vfs/hammer2/hammer2_subr.c +++ b/sys/vfs/hammer2/hammer2_subr.c @@ -107,9 +107,9 @@ hammer2_get_dtype(const hammer2_inode_data_t *ipdata) * Return the directory entry type for an inode */ int -hammer2_get_vtype(const hammer2_inode_data_t *ipdata) +hammer2_get_vtype(uint8_t type) { - switch(ipdata->meta.type) { + switch(type) { case HAMMER2_OBJTYPE_UNKNOWN: return (VBAD); case HAMMER2_OBJTYPE_DIRECTORY: diff --git a/sys/vfs/hammer2/hammer2_syncthr.c b/sys/vfs/hammer2/hammer2_syncthr.c index ffe1ca66c8..3889f9888d 100644 --- a/sys/vfs/hammer2/hammer2_syncthr.c +++ b/sys/vfs/hammer2/hammer2_syncthr.c @@ -185,8 +185,9 @@ hammer2_syncthr_primary(void *arg) * Synchronization scan. */ hammer2_trans_init(&thr->trans, pmp, HAMMER2_TRANS_KEEPMODIFY); - cparent = hammer2_inode_lock(pmp->iroot, - HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(pmp->iroot, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(pmp->iroot, + HAMMER2_RESOLVE_ALWAYS); hammer2_update_pfs_status(thr, cparent); hammer2_inode_unlock(pmp->iroot, NULL); bzero(errors, sizeof(errors)); diff --git a/sys/vfs/hammer2/hammer2_vfsops.c b/sys/vfs/hammer2/hammer2_vfsops.c index ae9b5f0a0b..ace2e00017 100644 --- a/sys/vfs/hammer2/hammer2_vfsops.c +++ b/sys/vfs/hammer2/hammer2_vfsops.c @@ -1029,7 +1029,8 @@ hammer2_vfs_mount(struct mount *mp, char *path, caddr_t data, * cluster->pmp will incorrectly point to spmp and must be fixed * up later on. */ - cparent = hammer2_inode_lock(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); lhc = hammer2_dirhash(label, strlen(label)); cluster = hammer2_cluster_lookup(cparent, &key_next, lhc, lhc + HAMMER2_DIRHASH_LOMASK, @@ -1174,7 +1175,8 @@ hammer2_update_pmps(hammer2_dev_t *hmp) * up later on. */ spmp = hmp->spmp; - cparent = hammer2_inode_lock(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); cluster = hammer2_cluster_lookup(cparent, &key_next, HAMMER2_KEY_MIN, HAMMER2_KEY_MAX, @@ -1272,8 +1274,9 @@ hammer2_write_thread(void *arg) * NOTE: hammer2_write_file_core() may indirectly * modify and modsync the inode. */ - cparent = hammer2_inode_lock(ip, - HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(ip, + HAMMER2_RESOLVE_ALWAYS); if (ip->flags & (HAMMER2_INODE_RESIZED | HAMMER2_INODE_MTIME)) { hammer2_inode_fsync(&trans, ip, cparent); @@ -2220,9 +2223,32 @@ hammer2_vfs_root(struct mount *mp, struct vnode **vpp) *vpp = NULL; error = EINVAL; } else { - cparent = hammer2_inode_lock(pmp->iroot, + hammer2_inode_lock(pmp->iroot, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + cparent = hammer2_inode_cluster(pmp->iroot, HAMMER2_RESOLVE_ALWAYS | HAMMER2_RESOLVE_SHARED); + + /* + * Initialize pmp->inode_tid and pmp->modify_tid on first access + * to the root of mount that resolves good. + * XXX probably not the best place for this. + */ + if (pmp->inode_tid == 0 && + cparent->error == 0 && cparent->focus) { + const hammer2_inode_data_t *ripdata; + hammer2_blockref_t bref; + + ripdata = &hammer2_cluster_rdata(cparent)->ipdata; + hammer2_cluster_bref(cparent, &bref); + pmp->inode_tid = ripdata->meta.pfs_inum + 1; + pmp->modify_tid = bref.modify_tid; + pmp->iroot->meta = ripdata->meta; + hammer2_cluster_bref(cparent, &pmp->iroot->bref); + kprintf("PMP focus good set nextino=%ld mod=%016jx\n", + pmp->inode_tid, pmp->modify_tid); + } + vp = hammer2_igetv(pmp->iroot, cparent, &error); hammer2_inode_unlock(pmp->iroot, cparent); *vpp = vp; diff --git a/sys/vfs/hammer2/hammer2_vnops.c b/sys/vfs/hammer2/hammer2_vnops.c index 95b312bd9c..774e26499a 100644 --- a/sys/vfs/hammer2/hammer2_vnops.c +++ b/sys/vfs/hammer2/hammer2_vnops.c @@ -225,7 +225,8 @@ hammer2_vop_fsync(struct vop_fsync_args *ap) * which call this function will eventually call chain_flush * on the volume root as a catch-all, which is far more optimal. */ - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); atomic_clear_int(&ip->flags, HAMMER2_INODE_MODIFIED); /*vclrisdirty(vp);*/ if (ip->flags & (HAMMER2_INODE_RESIZED|HAMMER2_INODE_MTIME)) @@ -243,21 +244,16 @@ int hammer2_vop_access(struct vop_access_args *ap) { hammer2_inode_t *ip = VTOI(ap->a_vp); - const hammer2_inode_data_t *ripdata; - hammer2_cluster_t *cluster; uid_t uid; gid_t gid; int error; LOCKSTART; - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); - ripdata = &hammer2_cluster_rdata(cluster)->ipdata; - uid = hammer2_to_unix_xid(&ripdata->meta.uid); - gid = hammer2_to_unix_xid(&ripdata->meta.gid); - error = vop_helper_access(ap, uid, gid, - ripdata->meta.mode, ripdata->meta.uflags); - hammer2_inode_unlock(ip, cluster); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | HAMMER2_RESOLVE_SHARED); + uid = hammer2_to_unix_xid(&ip->meta.uid); + gid = hammer2_to_unix_xid(&ip->meta.gid); + error = vop_helper_access(ap, uid, gid, ip->meta.mode, ip->meta.uflags); + hammer2_inode_unlock(ip, NULL); LOCKSTOP; return (error); @@ -267,11 +263,8 @@ static int hammer2_vop_getattr(struct vop_getattr_args *ap) { - const hammer2_inode_data_t *ripdata; - hammer2_cluster_t *cluster; hammer2_pfs_t *pmp; hammer2_inode_t *ip; - hammer2_blockref_t bref; struct vnode *vp; struct vattr *vap; @@ -282,36 +275,32 @@ hammer2_vop_getattr(struct vop_getattr_args *ap) ip = VTOI(vp); pmp = ip->pmp; - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); - ripdata = &hammer2_cluster_rdata(cluster)->ipdata; - KKASSERT(hammer2_cluster_type(cluster) == HAMMER2_BREF_TYPE_INODE); - hammer2_cluster_bref(cluster, &bref); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | HAMMER2_RESOLVE_SHARED); vap->va_fsid = pmp->mp->mnt_stat.f_fsid.val[0]; - vap->va_fileid = ripdata->meta.inum; - vap->va_mode = ripdata->meta.mode; - vap->va_nlink = ripdata->meta.nlinks; - vap->va_uid = hammer2_to_unix_xid(&ripdata->meta.uid); - vap->va_gid = hammer2_to_unix_xid(&ripdata->meta.gid); + vap->va_fileid = ip->meta.inum; + vap->va_mode = ip->meta.mode; + vap->va_nlink = ip->meta.nlinks; + vap->va_uid = hammer2_to_unix_xid(&ip->meta.uid); + vap->va_gid = hammer2_to_unix_xid(&ip->meta.gid); vap->va_rmajor = 0; vap->va_rminor = 0; vap->va_size = ip->meta.size; /* protected by shared lock */ vap->va_blocksize = HAMMER2_PBUFSIZE; - vap->va_flags = ripdata->meta.uflags; - hammer2_time_to_timespec(ripdata->meta.ctime, &vap->va_ctime); - hammer2_time_to_timespec(ripdata->meta.mtime, &vap->va_mtime); - hammer2_time_to_timespec(ripdata->meta.mtime, &vap->va_atime); + vap->va_flags = ip->meta.uflags; + hammer2_time_to_timespec(ip->meta.ctime, &vap->va_ctime); + hammer2_time_to_timespec(ip->meta.mtime, &vap->va_mtime); + hammer2_time_to_timespec(ip->meta.mtime, &vap->va_atime); vap->va_gen = 1; - vap->va_bytes = bref.data_count; - vap->va_type = hammer2_get_vtype(ripdata); + vap->va_bytes = ip->bref.data_count; + vap->va_type = hammer2_get_vtype(ip->meta.type); vap->va_filerev = 0; - vap->va_uid_uuid = ripdata->meta.uid; - vap->va_gid_uuid = ripdata->meta.gid; + vap->va_uid_uuid = ip->meta.uid; + vap->va_gid_uuid = ip->meta.gid; vap->va_vaflags = VA_UID_UUID_VALID | VA_GID_UUID_VALID | VA_FSID_UUID_VALID; - hammer2_inode_unlock(ip, cluster); + hammer2_inode_unlock(ip, NULL); LOCKSTOP; return (0); @@ -348,7 +337,8 @@ hammer2_vop_setattr(struct vop_setattr_args *ap) hammer2_pfs_memory_wait(ip->pmp); hammer2_trans_init(&trans, ip->pmp, 0); - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); ripdata = &hammer2_cluster_rdata(cluster)->ipdata; error = 0; @@ -426,7 +416,8 @@ hammer2_vop_setattr(struct vop_setattr_args *ap) } else { hammer2_extend_file(ip, vap->va_size); } - cluster = hammer2_inode_lock(ip, + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); /* RELOAD */ ripdata = &hammer2_cluster_rdata(cluster)->ipdata; @@ -547,8 +538,9 @@ hammer2_vop_readdir(struct vop_readdir_args *ap) } cookie_index = 0; - cparent = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | HAMMER2_RESOLVE_SHARED); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); ripdata = &hammer2_cluster_rdata(cparent)->ipdata; @@ -588,11 +580,15 @@ hammer2_vop_readdir(struct vop_readdir_args *ap) xip = ip->pip; hammer2_inode_ref(xip); hammer2_inode_unlock(ip, cparent); - xcluster = hammer2_inode_lock(xip, + hammer2_inode_lock(xip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + xcluster = hammer2_inode_cluster(xip, HAMMER2_RESOLVE_ALWAYS | HAMMER2_RESOLVE_SHARED); - cparent = hammer2_inode_lock(ip, + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS | HAMMER2_RESOLVE_SHARED); hammer2_inode_drop(xip); @@ -1152,8 +1148,10 @@ hammer2_vop_nresolve(struct vop_nresolve_args *ap) /* * Note: In DragonFly the kernel handles '.' and '..'. */ - cparent = hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); + hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + cparent = hammer2_inode_cluster(dip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); cluster = hammer2_cluster_lookup(cparent, &key_next, lhc, lhc + HAMMER2_DIRHASH_LOMASK, @@ -1204,7 +1202,8 @@ hammer2_vop_nresolve(struct vop_nresolve_args *ap) hammer2_inode_unlock(ip, NULL); hammer2_cluster_unlock(cluster); hammer2_cluster_drop(cluster); - cluster = hammer2_inode_lock(ip, + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); ripdata = &hammer2_cluster_rdata(cluster)->ipdata; hammer2_inode_drop(ip); @@ -1294,7 +1293,8 @@ hammer2_vop_nlookupdotdot(struct vop_nlookupdotdot_args *ap) LOCKSTOP; return ENOENT; } - cparent = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); *ap->a_vpp = hammer2_igetv(ip, cparent, &error); hammer2_inode_unlock(ip, cparent); @@ -1368,8 +1368,10 @@ hammer2_vop_advlock(struct vop_advlock_args *ap) hammer2_cluster_t *cparent; hammer2_off_t size; - cparent = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | - HAMMER2_RESOLVE_SHARED); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); + cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS | + HAMMER2_RESOLVE_SHARED); ripdata = &hammer2_cluster_rdata(cparent)->ipdata; size = ripdata->meta.size; hammer2_inode_unlock(ip, cparent); @@ -1439,10 +1441,16 @@ hammer2_vop_nlink(struct vop_nlink_args *ap) */ fdip = ip->pip; cdip = hammer2_inode_common_parent(fdip, tdip); - cdcluster = hammer2_inode_lock(cdip, HAMMER2_RESOLVE_ALWAYS); - fdcluster = hammer2_inode_lock(fdip, HAMMER2_RESOLVE_ALWAYS); - tdcluster = hammer2_inode_lock(tdip, HAMMER2_RESOLVE_ALWAYS); - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(cdip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(fdip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(tdip, HAMMER2_RESOLVE_ALWAYS); + cdcluster = hammer2_inode_cluster(cdip, HAMMER2_RESOLVE_ALWAYS); + fdcluster = hammer2_inode_cluster(fdip, HAMMER2_RESOLVE_ALWAYS); + tdcluster = hammer2_inode_cluster(tdip, HAMMER2_RESOLVE_ALWAYS); + + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); + error = hammer2_hardlink_consolidate(&trans, ip, &cluster, cdip, cdcluster, 1); if (error) @@ -1819,9 +1827,12 @@ hammer2_vop_nrename(struct vop_nrename_args *ap) * other pointers. */ cdip = hammer2_inode_common_parent(ip->pip, tdip); - cdcluster = hammer2_inode_lock(cdip, HAMMER2_RESOLVE_ALWAYS); - fdcluster = hammer2_inode_lock(fdip, HAMMER2_RESOLVE_ALWAYS); - tdcluster = hammer2_inode_lock(tdip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(cdip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(fdip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(tdip, HAMMER2_RESOLVE_ALWAYS); + cdcluster = hammer2_inode_cluster(cdip, HAMMER2_RESOLVE_ALWAYS); + fdcluster = hammer2_inode_cluster(fdip, HAMMER2_RESOLVE_ALWAYS); + tdcluster = hammer2_inode_cluster(tdip, HAMMER2_RESOLVE_ALWAYS); /* * Keep a tight grip on the inode so the temporary unlinking from @@ -1857,7 +1868,8 @@ hammer2_vop_nrename(struct vop_nrename_args *ap) * we do use one later remember that it must be reloaded * on any modification to the inode, including connects. */ - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); error = hammer2_hardlink_consolidate(&trans, ip, &cluster, cdip, cdcluster, 0); if (error) @@ -2008,7 +2020,8 @@ hammer2_run_unlinkq(hammer2_trans_t *trans, hammer2_pfs_t *pmp) ip = ipul->ip; kfree(ipul, pmp->minode); - cluster = hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); + cluster = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); ripdata = &hammer2_cluster_rdata(cluster)->ipdata; if (hammer2_debug & 0x400) { kprintf("hammer2: unlink on reclaim: %s refs=%d\n", -- 2.41.0