/** * Copy an extended attribute into the buffer provided, or compute * the required buffer size if \a buf is NULL. * * On success, the number of bytes used or required is stored in \a sizep. * * Note that no locking is done here. * * \param[in] env execution environment * \param[in] obj object for which to retrieve xattr * \param[out] buf buffer to store xattr value in * \param[in] name name of xattr to copy * \param[out] sizep bytes used or required to store xattr * * \retval 0 on success * \retval negative negated errno on failure */ int __osd_xattr_get(const struct lu_env *env, struct osd_object *obj, struct lu_buf *buf, const char *name, int *sizep) { int rc; /* check SA_ZPL_DXATTR first then fallback to directory xattr */ rc = __osd_sa_xattr_get(env, obj, buf, name, sizep); if (rc != -ENOENT) return rc; return __osd_xattr_get_large(env, osd_obj2dev(obj), obj->oo_xattr, buf, name, sizep); }
/* * as we don't know FID, we can't use LU object, so this function * partially duplicate __osd_xattr_get() which is built around * LU-object and uses it to cache data like regular EA dnode, etc */ static int osd_find_parent_by_dnode(const struct lu_env *env, struct dt_object *o, struct lu_fid *fid) { struct lustre_mdt_attrs *lma; udmu_objset_t *uos = &osd_obj2dev(osd_dt_obj(o))->od_objset; struct lu_buf buf; sa_handle_t *sa_hdl; nvlist_t *nvbuf = NULL; uchar_t *value; uint64_t dnode; int rc, size; ENTRY; /* first of all, get parent dnode from own attributes */ LASSERT(osd_dt_obj(o)->oo_db); rc = -sa_handle_get(uos->os, osd_dt_obj(o)->oo_db->db_object, NULL, SA_HDL_PRIVATE, &sa_hdl); if (rc) RETURN(rc); dnode = ZFS_NO_OBJECT; rc = -sa_lookup(sa_hdl, SA_ZPL_PARENT(uos), &dnode, 8); sa_handle_destroy(sa_hdl); if (rc) RETURN(rc); /* now get EA buffer */ rc = __osd_xattr_load(uos, dnode, &nvbuf); if (rc) GOTO(regular, rc); /* XXX: if we get that far.. should we cache the result? */ /* try to find LMA attribute */ LASSERT(nvbuf != NULL); rc = -nvlist_lookup_byte_array(nvbuf, XATTR_NAME_LMA, &value, &size); if (rc == 0 && size >= sizeof(*lma)) { lma = (struct lustre_mdt_attrs *)value; lustre_lma_swab(lma); *fid = lma->lma_self_fid; GOTO(out, rc = 0); } regular: /* no LMA attribute in SA, let's try regular EA */ /* first of all, get parent dnode storing regular EA */ rc = -sa_handle_get(uos->os, dnode, NULL, SA_HDL_PRIVATE, &sa_hdl); if (rc) GOTO(out, rc); dnode = ZFS_NO_OBJECT; rc = -sa_lookup(sa_hdl, SA_ZPL_XATTR(uos), &dnode, 8); sa_handle_destroy(sa_hdl); if (rc) GOTO(out, rc); CLASSERT(sizeof(*lma) <= sizeof(osd_oti_get(env)->oti_buf)); buf.lb_buf = osd_oti_get(env)->oti_buf; buf.lb_len = sizeof(osd_oti_get(env)->oti_buf); /* now try to find LMA */ rc = __osd_xattr_get_large(env, uos, dnode, &buf, XATTR_NAME_LMA, &size); if (rc == 0 && size >= sizeof(*lma)) { lma = buf.lb_buf; lustre_lma_swab(lma); *fid = lma->lma_self_fid; GOTO(out, rc = 0); } else if (rc < 0) { GOTO(out, rc); } else { GOTO(out, rc = -EIO); } out: if (nvbuf != NULL) nvlist_free(nvbuf); RETURN(rc); }