X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosd-zfs%2Fosd_xattr.c;h=9c2bac9a8883cb07587a91149a94045531cc85ca;hp=777fdb0a6362258fa1bc46028fb9dfa840556086;hb=69940d2b3a445284e7e10ea04e8cb72ee37a8724;hpb=9b704e4088d867851cdb011f0a2560b1e622555c diff --git a/lustre/osd-zfs/osd_xattr.c b/lustre/osd-zfs/osd_xattr.c index 777fdb0..9c2bac9 100644 --- a/lustre/osd-zfs/osd_xattr.c +++ b/lustre/osd-zfs/osd_xattr.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2014, Intel Corporation. + * Copyright (c) 2012, 2016, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -108,9 +104,9 @@ static inline int __osd_xattr_cache(const struct lu_env *env, struct osd_object *obj) { LASSERT(obj->oo_sa_xattr == NULL); - LASSERT(obj->oo_db != NULL); + LASSERT(obj->oo_dn != NULL); - return __osd_xattr_load(osd_obj2dev(obj), obj->oo_db->db_object, + return __osd_xattr_load(osd_obj2dev(obj), obj->oo_dn->dn_object, &obj->oo_sa_xattr); } @@ -151,8 +147,8 @@ int __osd_xattr_get_large(const struct lu_env *env, struct osd_device *osd, uint64_t xattr, struct lu_buf *buf, const char *name, int *sizep) { - dmu_buf_t *xa_data_db; - sa_handle_t *sa_hdl = NULL; + dnode_t *xa_data_dn; + sa_handle_t *sa_hdl = NULL; uint64_t xa_data_obj, size; int rc; @@ -166,7 +162,7 @@ int __osd_xattr_get_large(const struct lu_env *env, struct osd_device *osd, if (rc) return rc; - rc = __osd_obj2dbuf(env, osd->od_os, xa_data_obj, &xa_data_db); + rc = __osd_obj2dnode(env, osd->od_os, xa_data_obj, &xa_data_dn); if (rc) return rc; @@ -196,13 +192,13 @@ int __osd_xattr_get_large(const struct lu_env *env, struct osd_device *osd, goto out; } - rc = -dmu_read(osd->od_os, xa_data_db->db_object, 0, + rc = -dmu_read(osd->od_os, xa_data_dn->dn_object, 0, size, buf->lb_buf, DMU_READ_PREFETCH); out: sa_handle_destroy(sa_hdl); out_rele: - dmu_buf_rele(xa_data_db, FTAG); + osd_dnode_rele(xa_data_dn); return rc; } @@ -229,6 +225,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) @@ -245,18 +244,17 @@ int osd_xattr_get(const struct lu_env *env, struct dt_object *dt, int rc, size = 0; ENTRY; - LASSERT(obj->oo_db != NULL); + LASSERT(obj->oo_dn != 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)) + (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 || + strcmp(name, XATTR_NAME_POSIX_ACL_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; @@ -265,36 +263,18 @@ int osd_xattr_get(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } -void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj, - int vallen, const char *name, - struct osd_thandle *oh) +/* the function is used to declare EAs when SA is not supported */ +void __osd_xattr_declare_legacy(const struct lu_env *env, + struct osd_object *obj, + int vallen, const char *name, + struct osd_thandle *oh) { struct osd_device *osd = osd_obj2dev(obj); - dmu_buf_t *db = obj->oo_db; - dmu_tx_t *tx = oh->ot_tx; - uint64_t xa_data_obj; - int rc = 0; - int here; - - here = dt_object_exists(&obj->oo_dt); - - /* object may be not yet created */ - if (here) { - LASSERT(db); - LASSERT(obj->oo_sa_hdl); - /* we might just update SA_ZPL_DXATTR */ - dmu_tx_hold_sa(tx, obj->oo_sa_hdl, 1); - - if (obj->oo_xattr == ZFS_NO_OBJECT) - rc = -ENOENT; - } + dmu_tx_t *tx = oh->ot_tx; + uint64_t xa_data_obj; + int rc; - if (!here || rc == -ENOENT) { - /* we'll be updating SA_ZPL_XATTR */ - if (here) { - LASSERT(obj->oo_sa_hdl); - dmu_tx_hold_sa(tx, obj->oo_sa_hdl, 1); - } + if (obj->oo_xattr == ZFS_NO_OBJECT) { /* xattr zap + entry */ dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, (char *) name); /* xattr value obj */ @@ -313,7 +293,6 @@ void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj, dmu_tx_hold_bonus(tx, xa_data_obj); dmu_tx_hold_free(tx, xa_data_obj, vallen, DMU_OBJECT_END); dmu_tx_hold_write(tx, xa_data_obj, 0, vallen); - return; } else if (rc == -ENOENT) { /* * Entry doesn't exist, we need to create a new one and a new @@ -323,11 +302,45 @@ void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj, dmu_tx_hold_zap(tx, obj->oo_xattr, TRUE, (char *) name); dmu_tx_hold_sa_create(tx, ZFS_SA_BASE_ATTR_SIZE); dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, vallen); + } +} + +void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj, + int vallen, const char *name, + struct osd_thandle *oh) +{ + dmu_tx_t *tx = oh->ot_tx; + int bonuslen; + + if (unlikely(obj->oo_destroyed)) + return; + + if (unlikely(!osd_obj2dev(obj)->od_xattr_in_sa)) { + __osd_xattr_declare_legacy(env, obj, vallen, name, oh); return; } - /* An error happened */ - tx->tx_err = -rc; + /* declare EA in SA */ + if (dt_object_exists(&obj->oo_dt)) { + LASSERT(obj->oo_sa_hdl); + /* XXX: it should be possible to skip spill + * declaration if specific EA is part of + * bonus and doesn't grow */ + dmu_tx_hold_spill(tx, obj->oo_dn->dn_object); + return; + } + + bonuslen = osd_obj_bonuslen(obj); + + /* the object doesn't exist, but we've declared bonus + * in osd_declare_object_create() yet */ + if (obj->oo_ea_in_bonus > bonuslen) { + /* spill has been declared already */ + } else if (obj->oo_ea_in_bonus + vallen > bonuslen) { + /* we're about to exceed bonus, let's declare spill */ + dmu_tx_hold_spill(tx, DMU_NEW_OBJECT); + } + obj->oo_ea_in_bonus += vallen; } int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt, @@ -341,9 +354,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); } @@ -356,8 +369,7 @@ int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt, * * No locking is done here. */ -static int -__osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj, +int __osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj, struct osd_thandle *oh) { struct osd_device *osd = osd_obj2dev(obj); @@ -474,8 +486,8 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj, struct osd_thandle *oh) { struct osd_device *osd = osd_obj2dev(obj); - dmu_buf_t *xa_zap_db = NULL; - dmu_buf_t *xa_data_db = NULL; + dnode_t *xa_zap_dn = NULL; + dnode_t *xa_data_dn = NULL; uint64_t xa_data_obj; sa_handle_t *sa_hdl = NULL; dmu_tx_t *tx = oh->ot_tx; @@ -489,12 +501,11 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj, la->la_valid = LA_MODE; la->la_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; - rc = __osd_zap_create(env, osd, &xa_zap_db, tx, la, - obj->oo_db->db_object, 0); + rc = __osd_zap_create(env, osd, &xa_zap_dn, tx, la, 0); if (rc) return rc; - obj->oo_xattr = xa_zap_db->db_object; + obj->oo_xattr = xa_zap_dn->dn_object; rc = osd_object_sa_update(obj, SA_ZPL_XATTR(osd), &obj->oo_xattr, 8, oh); if (rc) @@ -512,8 +523,7 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj, * Entry already exists. * We'll truncate the existing object. */ - rc = __osd_obj2dbuf(env, osd->od_os, xa_data_obj, - &xa_data_db); + rc = __osd_obj2dnode(env, osd->od_os, xa_data_obj, &xa_data_dn); if (rc) goto out; @@ -526,7 +536,7 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj, if (rc) goto out_sa; - rc = -dmu_free_range(osd->od_os, xa_data_db->db_object, + rc = -dmu_free_range(osd->od_os, xa_data_dn->dn_object, 0, DMU_OBJECT_END, tx); if (rc) goto out_sa; @@ -545,11 +555,10 @@ __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, obj, &xa_data_db, tx, la, - obj->oo_xattr); + rc = __osd_object_create(env, obj, &xa_data_dn, tx, la); if (rc) goto out; - xa_data_obj = xa_data_db->db_object; + xa_data_obj = xa_data_dn->dn_object; rc = -sa_handle_get(osd->od_os, xa_data_obj, NULL, SA_HDL_PRIVATE, &sa_hdl); @@ -574,10 +583,10 @@ __osd_xattr_set(const struct lu_env *env, struct osd_object *obj, out_sa: sa_handle_destroy(sa_hdl); out: - if (xa_data_db != NULL) - dmu_buf_rele(xa_data_db, FTAG); - if (xa_zap_db != NULL) - dmu_buf_rele(xa_zap_db, FTAG); + if (xa_data_dn != NULL) + osd_dnode_rele(xa_data_dn); + if (xa_zap_dn != NULL) + osd_dnode_rele(xa_zap_dn); return rc; } @@ -593,25 +602,19 @@ 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 || - strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)) + (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 || + strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) RETURN(-EOPNOTSUPP); - if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_LINKEA_OVERFLOW) && - strcmp(name, XATTR_NAME_LINK) == 0) - RETURN(-ENOSPC); - 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); - up(&obj->oo_guard); + up_write(&obj->oo_guard); RETURN(rc); } @@ -660,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); + LASSERT(obj->oo_dn != 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; @@ -691,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) @@ -734,20 +740,20 @@ int osd_xattr_del(const struct lu_env *env, struct dt_object *dt, ENTRY; LASSERT(handle != NULL); - LASSERT(obj->oo_db != NULL); + LASSERT(obj->oo_dn != NULL); LASSERT(osd_invariant(obj)); LASSERT(dt_object_exists(dt)); oh = container_of0(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_tx != NULL); if (!osd_obj2dev(obj)->od_posix_acl && - (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 || - strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)) + (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 || + strcmp(name, XATTR_NAME_POSIX_ACL_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); } @@ -836,7 +842,7 @@ int osd_xattrs_destroy(const struct lu_env *env, rc = -dmu_object_free(osd->od_os, obj->oo_xattr, tx); if (rc) - CERROR("%s: free xattr "LPU64" failed: rc = %d\n", + CERROR("%s: free xattr %llu failed: rc = %d\n", osd->od_svname, obj->oo_xattr, rc); return rc; @@ -862,8 +868,8 @@ osd_sa_xattr_list(const struct lu_env *env, struct osd_object *obj, const char *name = nvpair_name(nvp); if (!osd_obj2dev(obj)->od_posix_acl && - (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0 || - strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)) + (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 || + strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) continue; len = strlen(name); @@ -888,11 +894,11 @@ int osd_xattr_list(const struct lu_env *env, struct dt_object *dt, int rc, counted; ENTRY; - LASSERT(obj->oo_db != NULL); + LASSERT(obj->oo_dn != NULL); 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) @@ -910,8 +916,8 @@ int osd_xattr_list(const struct lu_env *env, struct dt_object *dt, while ((rc = -zap_cursor_retrieve(zc, za)) == 0) { if (!osd_obj2dev(obj)->od_posix_acl && - (strcmp(za->za_name, POSIX_ACL_XATTR_ACCESS) == 0 || - strcmp(za->za_name, POSIX_ACL_XATTR_DEFAULT) == 0)) { + (strcmp(za->za_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 || + strcmp(za->za_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) { zap_cursor_advance(zc); continue; } @@ -919,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); } @@ -936,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); }