diff options
author | mm <mm@FreeBSD.org> | 2010-05-04 17:40:24 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2010-05-04 17:40:24 +0000 |
commit | 6dc3ed99a0862fafbe76f87b5b84a42d0a23f622 (patch) | |
tree | 87761f11ece45c72f5c78a45d1a1ca65fde67051 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c | |
parent | 551564c95b96239d355e9b3bd713d815204ace7a (diff) | |
download | FreeBSD-src-6dc3ed99a0862fafbe76f87b5b84a42d0a23f622.zip FreeBSD-src-6dc3ed99a0862fafbe76f87b5b84a42d0a23f622.tar.gz |
Speed up ZFS list operation with objset prefetching.
Partial import of OpenSolaris onnv revisions:
8415:8809e849f63e, 10474:0e96dd3b905a
PR: kern/146297
Submitted by: myself
Approved by: pjd, delphij (mentor)
Obtained from: OpenSolaris (Bug ID 6386929, 6755389, 6847118)
MFC after: 2 weeks
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c index 7981e06..c9e00d5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -1213,6 +1213,39 @@ dmu_objset_find_spa(spa_t *spa, const char *name, return (err); } +/* ARGSUSED */ +int +dmu_objset_prefetch(char *name, void *arg) +{ + dsl_dataset_t *ds; + + if (dsl_dataset_hold(name, FTAG, &ds)) + return (0); + + if (!BP_IS_HOLE(&ds->ds_phys->ds_bp)) { + mutex_enter(&ds->ds_opening_lock); + if (!dsl_dataset_get_user_ptr(ds)) { + uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; + zbookmark_t zb; + + zb.zb_objset = ds->ds_object; + zb.zb_object = 0; + zb.zb_level = -1; + zb.zb_blkid = 0; + + (void) arc_read_nolock(NULL, dsl_dataset_get_spa(ds), + &ds->ds_phys->ds_bp, NULL, NULL, + ZIO_PRIORITY_ASYNC_READ, + ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE, + &aflags, &zb); + } + mutex_exit(&ds->ds_opening_lock); + } + + dsl_dataset_rele(ds, FTAG); + return (0); +} + void dmu_objset_set_user(objset_t *os, void *user_ptr) { |