diff options
author | Justin T. Gibbs <[email protected]> | 2015-04-02 22:59:15 +1100 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-04-28 16:25:44 -0700 |
commit | 6ebebaceb1091142b81430291c610d79b6a3073e (patch) | |
tree | 70197ad52e7d910f4a860dcfc1d475aa5d073efc /include | |
parent | 0c66c32d1d8b64a261cceb5f50a9e86777c5d0b2 (diff) |
Illumos 5531 - NULL pointer dereference in dsl_prop_get_ds()
5531 NULL pointer dereference in dsl_prop_get_ds()
Author: Justin T. Gibbs <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Reviewed by: Dan McDonald <[email protected]>
Reviewed by: George Wilson <[email protected]>
Reviewed by: Bayard Bell <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
References:
https://www.illumos.org/issues/5531
https://github.com/illumos/illumos-gate/commit/e57a022
Ported-by: Chris Dunlop <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'include')
-rw-r--r-- | include/sys/dbuf.h | 5 | ||||
-rw-r--r-- | include/sys/dmu.h | 16 | ||||
-rw-r--r-- | include/sys/dsl_dataset.h | 2 |
3 files changed, 22 insertions, 1 deletions
diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h index c2f4f8bd0..dd45261a3 100644 --- a/include/sys/dbuf.h +++ b/include/sys/dbuf.h @@ -262,12 +262,15 @@ int dbuf_hold_impl(struct dnode *dn, uint8_t level, uint64_t blkid, int create, void dbuf_prefetch(struct dnode *dn, uint64_t blkid, zio_priority_t prio); void dbuf_add_ref(dmu_buf_impl_t *db, void *tag); +boolean_t dbuf_try_add_ref(dmu_buf_t *db, objset_t *os, uint64_t obj, + uint64_t blkid, void *tag); uint64_t dbuf_refcount(dmu_buf_impl_t *db); void dbuf_rele(dmu_buf_impl_t *db, void *tag); void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag); -dmu_buf_impl_t *dbuf_find(struct dnode *dn, uint8_t level, uint64_t blkid); +dmu_buf_impl_t *dbuf_find(struct objset *os, uint64_t object, uint8_t level, + uint64_t blkid); int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags); void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx); diff --git a/include/sys/dmu.h b/include/sys/dmu.h index b2f1efae0..aa3e89d60 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -454,7 +454,23 @@ int dmu_spill_hold_existing(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp); */ int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset, void *tag, dmu_buf_t **, int flags); + +/* + * Add a reference to a dmu buffer that has already been held via + * dmu_buf_hold() in the current context. + */ void dmu_buf_add_ref(dmu_buf_t *db, void* tag); + +/* + * Attempt to add a reference to a dmu buffer that is in an unknown state, + * using a pointer that may have been invalidated by eviction processing. + * The request will succeed if the passed in dbuf still represents the + * same os/object/blkid, is ineligible for eviction, and has at least + * one hold by a user other than the syncer. + */ +boolean_t dmu_buf_try_add_ref(dmu_buf_t *, objset_t *os, uint64_t object, + uint64_t blkid, void *tag); + void dmu_buf_rele(dmu_buf_t *db, void *tag); uint64_t dmu_buf_refcount(dmu_buf_t *db); diff --git a/include/sys/dsl_dataset.h b/include/sys/dsl_dataset.h index 7e5c0a7cb..edfc5509e 100644 --- a/include/sys/dsl_dataset.h +++ b/include/sys/dsl_dataset.h @@ -197,6 +197,8 @@ dsl_dataset_phys(dsl_dataset_t *ds) int dsl_dataset_hold(struct dsl_pool *dp, const char *name, void *tag, dsl_dataset_t **dsp); +boolean_t dsl_dataset_try_add_ref(struct dsl_pool *dp, dsl_dataset_t *ds, + void *tag); int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, void *tag, dsl_dataset_t **); void dsl_dataset_rele(dsl_dataset_t *ds, void *tag); |