X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-zfs%2Fosd_xattr.c;h=1be83639d972159278df1b3a73bff9ce4524e591;hb=f9ca359284357d145819beb08b316e932f7a3060;hp=66572374de12cbfdfae90052d130a717ddc1288a;hpb=75f0f0675d0eadc634c098d664b7af78547999c9;p=fs%2Flustre-release.git diff --git a/lustre/osd-zfs/osd_xattr.c b/lustre/osd-zfs/osd_xattr.c index 6657237..1be8363 100644 --- a/lustre/osd-zfs/osd_xattr.c +++ b/lustre/osd-zfs/osd_xattr.c @@ -26,10 +26,8 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. - */ -/* - * Copyright (c) 2012, 2013, Intel Corporation. - * Use is subject to license terms. + * + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -91,7 +89,7 @@ int __osd_xattr_load(struct osd_device *osd, uint64_t dnode, nvlist_t **sa) goto out_sa; } - buf = sa_spill_alloc(KM_SLEEP); + buf = osd_zio_buf_alloc(size); if (buf == NULL) { rc = -ENOMEM; goto out_sa; @@ -99,7 +97,7 @@ int __osd_xattr_load(struct osd_device *osd, uint64_t dnode, nvlist_t **sa) rc = -sa_lookup(sa_hdl, SA_ZPL_DXATTR(osd), buf, size); if (rc == 0) rc = -nvlist_unpack(buf, size, sa, KM_SLEEP); - sa_spill_free(buf); + osd_zio_buf_free(buf, size); out_sa: sa_handle_destroy(sa_hdl); @@ -231,6 +229,9 @@ int __osd_xattr_get(const struct lu_env *env, struct osd_object *obj, { int rc; + if (unlikely(!dt_object_exists(&obj->oo_dt) || obj->oo_destroyed)) + return -ENOENT; + /* check SA_ZPL_DXATTR first then fallback to directory xattr */ rc = __osd_sa_xattr_get(env, obj, buf, name, sizep); if (rc != -ENOENT) @@ -241,8 +242,7 @@ int __osd_xattr_get(const struct lu_env *env, struct osd_object *obj, } int osd_xattr_get(const struct lu_env *env, struct dt_object *dt, - struct lu_buf *buf, const char *name, - struct lustre_capa *capa) + struct lu_buf *buf, const char *name) { struct osd_object *obj = osd_dt_obj(dt); int rc, size = 0; @@ -250,16 +250,15 @@ int osd_xattr_get(const struct lu_env *env, struct dt_object *dt, LASSERT(obj->oo_db != NULL); LASSERT(osd_invariant(obj)); - LASSERT(dt_object_exists(dt)); if (!osd_obj2dev(obj)->od_posix_acl && (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 || strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)) RETURN(-EOPNOTSUPP); - down(&obj->oo_guard); + down_read(&obj->oo_guard); rc = __osd_xattr_get(env, obj, buf, name, &size); - up(&obj->oo_guard); + up_read(&obj->oo_guard); if (rc == -ENOENT) rc = -ENODATA; @@ -279,6 +278,9 @@ void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj, int rc = 0; int here; + if (unlikely(obj->oo_destroyed)) + return; + here = dt_object_exists(&obj->oo_dt); /* object may be not yet created */ @@ -344,9 +346,9 @@ int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt, LASSERT(handle != NULL); oh = container_of0(handle, struct osd_thandle, ot_super); - down(&obj->oo_guard); + down_read(&obj->oo_guard); __osd_xattr_declare_set(env, obj, buf->lb_len, name, oh); - up(&obj->oo_guard); + up_read(&obj->oo_guard); RETURN(0); } @@ -377,7 +379,7 @@ __osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj, if (rc) return rc; - dxattr = sa_spill_alloc(KM_SLEEP); + dxattr = osd_zio_buf_alloc(sa_size); if (dxattr == NULL) RETURN(-ENOMEM); @@ -388,7 +390,7 @@ __osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj, rc = osd_object_sa_update(obj, SA_ZPL_DXATTR(osd), dxattr, sa_size, oh); out_free: - sa_spill_free(dxattr); + osd_zio_buf_free(dxattr, sa_size); RETURN(rc); } @@ -530,7 +532,7 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj, goto out_sa; rc = -dmu_free_range(osd->od_os, xa_data_db->db_object, - 0, DMU_OBJECT_END, tx); + 0, DMU_OBJECT_END, tx); if (rc) goto out_sa; } else if (rc == -ENOENT) { @@ -548,7 +550,7 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj, la->la_valid = LA_MODE; la->la_mode = S_IFREG | S_IRUGO | S_IWUSR; - rc = __osd_object_create(env, osd, &xa_data_db, tx, la, + rc = __osd_object_create(env, obj, &xa_data_db, tx, la, obj->oo_xattr); if (rc) goto out; @@ -587,7 +589,7 @@ out: int osd_xattr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, const char *name, int fl, - struct thandle *handle, struct lustre_capa *capa) + struct thandle *handle) { struct osd_object *obj = osd_dt_obj(dt); struct osd_thandle *oh; @@ -596,8 +598,6 @@ int osd_xattr_set(const struct lu_env *env, struct dt_object *dt, LASSERT(handle != NULL); LASSERT(osd_invariant(obj)); - LASSERT(dt_object_exists(dt)); - LASSERT(obj->oo_db); if (!osd_obj2dev(obj)->od_posix_acl && (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 || @@ -610,11 +610,11 @@ int osd_xattr_set(const struct lu_env *env, struct dt_object *dt, oh = container_of0(handle, struct osd_thandle, ot_super); - down(&obj->oo_guard); + down_write(&obj->oo_guard); CDEBUG(D_INODE, "Setting xattr %s with size %d\n", name, (int)buf->lb_len); - rc = osd_xattr_set_internal(env, obj, buf, name, fl, oh, capa); - up(&obj->oo_guard); + rc = osd_xattr_set_internal(env, obj, buf, name, fl, oh); + up_write(&obj->oo_guard); RETURN(rc); } @@ -663,22 +663,22 @@ int osd_declare_xattr_del(const struct lu_env *env, struct dt_object *dt, ENTRY; LASSERT(handle != NULL); - LASSERT(dt_object_exists(dt)); LASSERT(osd_invariant(obj)); oh = container_of0(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_tx != NULL); LASSERT(obj->oo_db != NULL); - down(&obj->oo_guard); - __osd_xattr_declare_del(env, obj, name, oh); - up(&obj->oo_guard); + down_read(&obj->oo_guard); + if (likely(dt_object_exists(&obj->oo_dt) && !obj->oo_destroyed)) + __osd_xattr_declare_del(env, obj, name, oh); + up_read(&obj->oo_guard); RETURN(0); } -int __osd_sa_xattr_del(const struct lu_env *env, struct osd_object *obj, - const char *name, struct osd_thandle *oh) +static int __osd_sa_xattr_del(const struct lu_env *env, struct osd_object *obj, + const char *name, struct osd_thandle *oh) { int rc; @@ -694,13 +694,16 @@ int __osd_sa_xattr_del(const struct lu_env *env, struct osd_object *obj, return rc; } -int __osd_xattr_del(const struct lu_env *env, struct osd_object *obj, - const char *name, struct osd_thandle *oh) +static int __osd_xattr_del(const struct lu_env *env, struct osd_object *obj, + const char *name, struct osd_thandle *oh) { struct osd_device *osd = osd_obj2dev(obj); uint64_t xa_data_obj; int rc; + if (unlikely(!dt_object_exists(&obj->oo_dt) || obj->oo_destroyed)) + return -ENOENT; + /* try remove xattr from SA at first */ rc = __osd_sa_xattr_del(env, obj, name, oh); if (rc != -ENOENT) @@ -729,8 +732,7 @@ int __osd_xattr_del(const struct lu_env *env, struct osd_object *obj, } int osd_xattr_del(const struct lu_env *env, struct dt_object *dt, - const char *name, struct thandle *handle, - struct lustre_capa *capa) + const char *name, struct thandle *handle) { struct osd_object *obj = osd_dt_obj(dt); struct osd_thandle *oh; @@ -749,13 +751,103 @@ int osd_xattr_del(const struct lu_env *env, struct dt_object *dt, strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)) RETURN(-EOPNOTSUPP); - down(&obj->oo_guard); + down_write(&obj->oo_guard); rc = __osd_xattr_del(env, obj, name, oh); - up(&obj->oo_guard); + up_write(&obj->oo_guard); RETURN(rc); } +void osd_declare_xattrs_destroy(const struct lu_env *env, + struct osd_object *obj, struct osd_thandle *oh) +{ + struct osd_device *osd = osd_obj2dev(obj); + zap_attribute_t *za = &osd_oti_get(env)->oti_za; + uint64_t oid = obj->oo_xattr, xid; + dmu_tx_t *tx = oh->ot_tx; + zap_cursor_t *zc; + int rc; + + if (oid == ZFS_NO_OBJECT) + return; /* Nothing to do for SA xattrs */ + + /* Declare to free the ZAP holding xattrs */ + dmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END); + + rc = osd_zap_cursor_init(&zc, osd->od_os, oid, 0); + if (rc) + goto out; + + while (zap_cursor_retrieve(zc, za) == 0) { + LASSERT(za->za_num_integers == 1); + LASSERT(za->za_integer_length == sizeof(uint64_t)); + + rc = -zap_lookup(osd->od_os, oid, za->za_name, + sizeof(uint64_t), 1, &xid); + if (rc) { + CERROR("%s: xattr %s lookup failed: rc = %d\n", + osd->od_svname, za->za_name, rc); + break; + } + dmu_tx_hold_free(tx, xid, 0, DMU_OBJECT_END); + + zap_cursor_advance(zc); + } + + osd_zap_cursor_fini(zc); +out: + if (rc && tx->tx_err == 0) + tx->tx_err = -rc; +} + +int osd_xattrs_destroy(const struct lu_env *env, + struct osd_object *obj, struct osd_thandle *oh) +{ + struct osd_device *osd = osd_obj2dev(obj); + dmu_tx_t *tx = oh->ot_tx; + zap_attribute_t *za = &osd_oti_get(env)->oti_za; + zap_cursor_t *zc; + uint64_t xid; + int rc; + + /* The transaction must have been assigned to a transaction group. */ + LASSERT(tx->tx_txg != 0); + + if (obj->oo_xattr == ZFS_NO_OBJECT) + return 0; /* Nothing to do for SA xattrs */ + + /* Free the ZAP holding the xattrs */ + rc = osd_zap_cursor_init(&zc, osd->od_os, obj->oo_xattr, 0); + if (rc) + return rc; + + while (zap_cursor_retrieve(zc, za) == 0) { + LASSERT(za->za_num_integers == 1); + LASSERT(za->za_integer_length == sizeof(uint64_t)); + + rc = -zap_lookup(osd->od_os, obj->oo_xattr, za->za_name, + sizeof(uint64_t), 1, &xid); + if (rc) { + CERROR("%s: lookup xattr %s failed: rc = %d\n", + osd->od_svname, za->za_name, rc); + } else { + rc = -dmu_object_free(osd->od_os, xid, tx); + if (rc) + CERROR("%s: free xattr %s failed: rc = %d\n", + osd->od_svname, za->za_name, rc); + } + zap_cursor_advance(zc); + } + osd_zap_cursor_fini(zc); + + rc = -dmu_object_free(osd->od_os, obj->oo_xattr, tx); + if (rc) + CERROR("%s: free xattr "LPU64" failed: rc = %d\n", + osd->od_svname, obj->oo_xattr, rc); + + return rc; +} + static int osd_sa_xattr_list(const struct lu_env *env, struct osd_object *obj, const struct lu_buf *lb) @@ -793,7 +885,7 @@ osd_sa_xattr_list(const struct lu_env *env, struct osd_object *obj, } int osd_xattr_list(const struct lu_env *env, struct dt_object *dt, - const struct lu_buf *lb, struct lustre_capa *capa) + const struct lu_buf *lb) { struct osd_object *obj = osd_dt_obj(dt); struct osd_device *osd = osd_obj2dev(obj); @@ -806,7 +898,7 @@ int osd_xattr_list(const struct lu_env *env, struct dt_object *dt, LASSERT(osd_invariant(obj)); LASSERT(dt_object_exists(dt)); - down(&obj->oo_guard); + down_read(&obj->oo_guard); rc = osd_sa_xattr_list(env, obj, lb); if (rc < 0) @@ -833,7 +925,7 @@ int osd_xattr_list(const struct lu_env *env, struct dt_object *dt, rc = strlen(za->za_name); if (lb->lb_buf != NULL) { if (counted + rc + 1 > lb->lb_len) - RETURN(-ERANGE); + GOTO(out_fini, rc = -ERANGE); memcpy(lb->lb_buf + counted, za->za_name, rc + 1); } @@ -850,7 +942,7 @@ int osd_xattr_list(const struct lu_env *env, struct dt_object *dt, out_fini: osd_zap_cursor_fini(zc); out: - up(&obj->oo_guard); + up_read(&obj->oo_guard); RETURN(rc); }