ent->lde_attrs = cpu_to_le32(ent->lde_attrs);
}
+int __osd_xattr_load_by_oid(struct osd_device *osd, uint64_t oid, nvlist_t **sa)
+{
+ sa_handle_t *hdl;
+ dmu_buf_t *db;
+ int rc;
+
+ rc = -dmu_bonus_hold(osd->od_os, oid, osd_obj_tag, &db);
+ if (rc < 0) {
+ CERROR("%s: can't get bonus, rc = %d\n", osd->od_svname, rc);
+ return rc;
+ }
+
+ rc = -sa_handle_get_from_db(osd->od_os, db, NULL, SA_HDL_PRIVATE, &hdl);
+ if (rc) {
+ dmu_buf_rele(db, osd_obj_tag);
+ return rc;
+ }
+
+ rc = __osd_xattr_load(osd, hdl, sa);
+
+ sa_handle_destroy(hdl);
+
+ return rc;
+}
/**
* Get the object's FID from its LMA EA.
*
int rc;
ENTRY;
- rc = __osd_xattr_load(osd, oid, &sa_xattr);
+ rc = __osd_xattr_load_by_oid(osd, oid, &sa_xattr);
if (rc == -ENOENT)
goto regular;
struct dt_object *o,
struct lu_fid *fid)
{
- struct osd_device *osd = osd_obj2dev(osd_dt_obj(o));
- sa_handle_t *sa_hdl;
+ struct osd_object *obj = osd_dt_obj(o);
+ struct osd_device *osd = osd_obj2dev(obj);
uint64_t dnode = ZFS_NO_OBJECT;
int rc;
ENTRY;
/* first of all, get parent dnode from own attributes */
- LASSERT(osd_dt_obj(o)->oo_dn);
- rc = -sa_handle_get(osd->od_os, osd_dt_obj(o)->oo_dn->dn_object,
- NULL, SA_HDL_PRIVATE, &sa_hdl);
+ rc = osd_sa_handle_get(obj);
if (rc != 0)
RETURN(rc);
-
- rc = -sa_lookup(sa_hdl, SA_ZPL_PARENT(osd), &dnode, 8);
- sa_handle_destroy(sa_hdl);
+ rc = -sa_lookup(obj->oo_sa_hdl, SA_ZPL_PARENT(osd), &dnode, 8);
if (rc == 0)
rc = osd_get_fid_by_oid(env, osd, dnode, fid);
/* LMA is required for this to be a Lustre object.
* If there is no xattr skip it. */
- rc = __osd_xattr_load(dev, it->mit_pos, &nvbuf);
+ rc = __osd_xattr_load_by_oid(dev, it->mit_pos, &nvbuf);
if (unlikely(rc != 0))
continue;
const struct lu_fid *fid);
/* osd_xattr.c */
-int __osd_xattr_load(struct osd_device *osd, uint64_t dnode,
- nvlist_t **sa_xattr);
+int __osd_xattr_load(struct osd_device *osd, sa_handle_t *hdl, nvlist_t **sa);
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_prefetch((os), (obj), (lvl), (off))
#endif
+static inline int osd_sa_handle_get(struct osd_object *obj)
+{
+ struct osd_device *osd = osd_obj2dev(obj);
+ dnode_t *dn = obj->oo_dn;
+ int rc;
+
+ if (obj->oo_sa_hdl)
+ return 0;
+
+ dbuf_read(dn->dn_bonus, NULL, DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH);
+ rc = -sa_handle_get_from_db(osd->od_os, &dn->dn_bonus->db, obj,
+ SA_HDL_PRIVATE, &obj->oo_sa_hdl);
+ if (rc)
+ return rc;
+ refcount_add(&dn->dn_bonus->db_holds, osd_obj_tag);
+ return 0;
+}
+
static inline void osd_dnode_rele(dnode_t *dn)
{
dmu_buf_impl_t *db;
LASSERT(obj->oo_sa_hdl == NULL);
LASSERT(obj->oo_dn != NULL);
- rc = -sa_handle_get(o->od_os, obj->oo_dn->dn_object, obj,
- SA_HDL_PRIVATE, &obj->oo_sa_hdl);
+ rc = osd_sa_handle_get(obj);
if (rc)
return rc;
{
struct osa_attr *osa = &osd_oti_get(env)->oti_osa;
sa_bulk_attr_t *bulk = osd_oti_get(env)->oti_attr_bulk;
- sa_handle_t *sa_hdl;
int cnt = 0;
int rc;
ENTRY;
LASSERT(obj->oo_dn != NULL);
- rc = -sa_handle_get(o->od_os, obj->oo_dn->dn_object, NULL,
- SA_HDL_PRIVATE, &sa_hdl);
- if (rc)
- RETURN(rc);
-
la->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE | LA_TYPE |
LA_SIZE | LA_UID | LA_GID | LA_FLAGS | LA_NLINK;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_FLAGS(o), NULL, &osa->flags, 8);
LASSERT(cnt <= ARRAY_SIZE(osd_oti_get(env)->oti_attr_bulk));
- rc = -sa_bulk_lookup(sa_hdl, bulk, cnt);
+ rc = -sa_bulk_lookup(obj->oo_sa_hdl, bulk, cnt);
if (rc)
GOTO(out_sa, rc);
}
if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode)) {
- rc = -sa_lookup(sa_hdl, SA_ZPL_RDEV(o), &osa->rdev, 8);
+ rc = -sa_lookup(obj->oo_sa_hdl, SA_ZPL_RDEV(o), &osa->rdev, 8);
if (rc)
GOTO(out_sa, rc);
la->la_rdev = osa->rdev;
la->la_valid |= LA_RDEV;
}
out_sa:
- sa_handle_destroy(sa_hdl);
RETURN(rc);
}
atomic_inc_32(&dn->dn_dbufs_count);
}
*dnp = dn;
+ dbuf_read(db, NULL, DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH);
break;
}
rc = -zap_add(osd->od_os, zapid, buf, 8, 1, zde, oh->ot_tx);
if (rc)
GOTO(out, rc);
-
+ obj->oo_dn = dn;
/* Now add in all of the "SA" attributes */
- rc = -sa_handle_get(osd->od_os, dn->dn_object, NULL,
- SA_HDL_PRIVATE, &obj->oo_sa_hdl);
+ rc = osd_sa_handle_get(obj);
if (rc)
GOTO(out, rc);
/* configure new osd object */
- obj->oo_dn = dn;
parent = parent != 0 ? parent : zapid;
rc = __osd_attr_init(env, osd, obj->oo_sa_hdl, oh->ot_tx,
&obj->oo_attr, parent);
#include <linux/posix_acl_xattr.h>
-int __osd_xattr_load(struct osd_device *osd, uint64_t dnode, nvlist_t **sa)
+int __osd_xattr_load(struct osd_device *osd, sa_handle_t *hdl, nvlist_t **sa)
{
- sa_handle_t *sa_hdl;
char *buf;
int rc, size;
- if (unlikely(dnode == ZFS_NO_OBJECT))
- return -ENOENT;
-
- rc = -sa_handle_get(osd->od_os, dnode, NULL, SA_HDL_PRIVATE, &sa_hdl);
- if (rc)
- return rc;
-
- rc = -sa_size(sa_hdl, SA_ZPL_DXATTR(osd), &size);
+ rc = -sa_size(hdl, SA_ZPL_DXATTR(osd), &size);
if (rc) {
if (rc == -ENOENT)
rc = -nvlist_alloc(sa, NV_UNIQUE_NAME, KM_SLEEP);
rc = -ENOMEM;
goto out_sa;
}
- rc = -sa_lookup(sa_hdl, SA_ZPL_DXATTR(osd), buf, size);
+ rc = -sa_lookup(hdl, SA_ZPL_DXATTR(osd), buf, size);
if (rc == 0)
rc = -nvlist_unpack(buf, size, sa, KM_SLEEP);
osd_zio_buf_free(buf, size);
out_sa:
- sa_handle_destroy(sa_hdl);
return rc;
}
-static inline int __osd_xattr_cache(const struct lu_env *env,
- struct osd_object *obj)
+static inline int __osd_xattr_cache(struct osd_object *obj)
{
- LASSERT(obj->oo_sa_xattr == NULL);
- LASSERT(obj->oo_dn != NULL);
-
- return __osd_xattr_load(osd_obj2dev(obj), obj->oo_dn->dn_object,
- &obj->oo_sa_xattr);
+ LASSERT(obj->oo_sa_hdl);
+ if (obj->oo_sa_xattr != NULL)
+ return 0;
+ return __osd_xattr_load(osd_obj2dev(obj),
+ obj->oo_sa_hdl, &obj->oo_sa_xattr);
}
static int
const struct lu_buf *buf, const char *name, int *sizep)
{
uchar_t *nv_value;
- int rc;
-
- LASSERT(obj->oo_sa_hdl);
+ int rc = 0;
- if (obj->oo_sa_xattr == NULL) {
- rc = __osd_xattr_cache(env, obj);
- if (rc)
- return rc;
- }
+ rc = __osd_xattr_cache(obj);
+ if (rc)
+ return rc;
LASSERT(obj->oo_sa_xattr);
- rc = -nvlist_lookup_byte_array(obj->oo_sa_xattr, name, &nv_value,
- sizep);
+ rc = -nvlist_lookup_byte_array(obj->oo_sa_xattr, name,
+ &nv_value, sizep);
if (rc)
return rc;
int rc;
int too_big = 0;
- LASSERT(obj->oo_sa_hdl);
- if (obj->oo_sa_xattr == NULL) {
- rc = __osd_xattr_cache(env, obj);
- if (rc)
- return rc;
- }
+ rc = __osd_xattr_cache(obj);
+ if (rc)
+ return rc;
LASSERT(obj->oo_sa_xattr);
/* Limited to 32k to keep nvpair memory allocations small */
{
int rc;
- if (obj->oo_sa_xattr == NULL) {
- rc = __osd_xattr_cache(env, obj);
- if (rc)
- return rc;
- }
+ rc = __osd_xattr_cache(obj);
+ if (rc)
+ return rc;
rc = -nvlist_remove(obj->oo_sa_xattr, name, DATA_TYPE_BYTE_ARRAY);
if (rc == 0)
int len, counted = 0;
int rc = 0;
- if (obj->oo_sa_xattr == NULL) {
- rc = __osd_xattr_cache(env, obj);
- if (rc)
- return rc;
- }
-
- LASSERT(obj->oo_sa_xattr);
+ rc = __osd_xattr_cache(obj);
+ if (rc)
+ return rc;
while ((nvp = nvlist_next_nvpair(obj->oo_sa_xattr, nvp)) != NULL) {
const char *name = nvpair_name(nvp);