/* * return status : * rc == 0 -> ok, proceed. * rc > 0 -> end of directory. * rc < 0 -> error. ( EOVERFLOW can be masked.) */ static int osd_zap_it_load(const struct lu_env *env, const struct dt_it *di, __u64 hash) { struct osd_zap_it *it = (struct osd_zap_it *)di; struct osd_object *obj = it->ozi_obj; struct osd_device *osd = osd_obj2dev(obj); int rc; ENTRY; udmu_zap_cursor_fini(it->ozi_zc); if (udmu_zap_cursor_init(&it->ozi_zc, &osd->od_objset, obj->oo_db->db_object, hash)) RETURN(-ENOMEM); it->ozi_reset = 0; /* same as osd_zap_it_next()*/ rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, NULL, NAME_MAX + 1); if (rc == 0) RETURN(+1); else if (rc == -ENOENT) /* end of dir*/ RETURN(0); RETURN(rc); }
int osd_xattr_list(const struct lu_env *env, struct dt_object *dt, struct lu_buf *lb, struct lustre_capa *capa) { struct osd_thread_info *oti = osd_oti_get(env); struct osd_object *obj = osd_dt_obj(dt); struct osd_device *osd = osd_obj2dev(obj); udmu_objset_t *uos = &osd->od_objset; zap_cursor_t *zc; int rc, counted = 0, remain = lb->lb_len; ENTRY; LASSERT(obj->oo_db != NULL); LASSERT(osd_invariant(obj)); LASSERT(dt_object_exists(dt)); down(&obj->oo_guard); rc = osd_sa_xattr_list(env, obj, lb); if (rc < 0) GOTO(out, rc); counted = rc; remain -= counted; /* continue with dnode xattr if any */ if (obj->oo_xattr == ZFS_NO_OBJECT) GOTO(out, rc = counted); rc = -udmu_zap_cursor_init(&zc, uos, obj->oo_xattr, 0); if (rc) GOTO(out, rc); while ((rc = -udmu_zap_cursor_retrieve_key(env, zc, oti->oti_key, MAXNAMELEN)) == 0) { rc = strlen(oti->oti_key); if (lb->lb_buf != NULL) { if (rc + 1 > remain) RETURN(-ERANGE); memcpy(lb->lb_buf, oti->oti_key, rc); lb->lb_buf += rc; *((char *)lb->lb_buf) = '\0'; lb->lb_buf++; remain -= rc + 1; } counted += rc + 1; zap_cursor_advance(zc); } if (rc < 0) GOTO(out_fini, rc); rc = counted; out_fini: udmu_zap_cursor_fini(zc); out: up(&obj->oo_guard); RETURN(rc); }
/** * Return pointer to the record under iterator. * * \param di - osd iterator * \param attr - not used */ static int osd_it_acct_rec(const struct lu_env *env, const struct dt_it *di, struct dt_rec *dtrec, __u32 attr) { struct osd_thread_info *info = osd_oti_get(env); char *buf = info->oti_buf; struct osd_it_quota *it = (struct osd_it_quota *)di; struct lquota_acct_rec *rec = (struct lquota_acct_rec *)dtrec; struct osd_object *obj = it->oiq_obj; struct osd_device *osd = osd_obj2dev(obj); int bytes_read; int rc; ENTRY; it->oiq_reset = 0; rec->ispace = rec->bspace = 0; /* retrieve block usage from the DMU accounting object */ rc = -udmu_zap_cursor_retrieve_value(env, it->oiq_zc, (char *)&rec->bspace, sizeof(uint64_t), &bytes_read); if (rc) RETURN(rc); if (osd->od_quota_iused_est) { if (rec->bspace != 0) /* estimate #inodes in use */ rec->ispace = udmu_objset_user_iused(&osd->od_objset, rec->bspace); RETURN(0); } /* retrieve key associated with the current cursor */ rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, buf, 32); if (rc) RETURN(rc); /* inode accounting is not maintained by DMU, so we use our own ZAP to * track inode usage */ rc = -zap_lookup(osd->od_objset.os, it->oiq_obj->oo_db->db_object, buf, sizeof(uint64_t), 1, &rec->ispace); if (rc == -ENOENT) /* user/group has not created any file yet */ CDEBUG(D_QUOTA, "%s: id %s not found in accounting ZAP\n", osd->od_svname, buf); else if (rc) RETURN(rc); RETURN(0); }
/** * Move on to the next valid entry. * * \param di - osd iterator * * \retval +ve - iterator reached the end * \retval 0 - iterator has not reached the end yet * \retval -ve - unexpected failure */ static int osd_it_acct_next(const struct lu_env *env, struct dt_it *di) { struct osd_it_quota *it = (struct osd_it_quota *)di; int rc; ENTRY; if (it->oiq_reset == 0) zap_cursor_advance(it->oiq_zc); it->oiq_reset = 0; rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, NULL, 32); if (rc == -ENOENT) /* reached the end */ RETURN(+1); RETURN(rc); }
static int osd_zap_it_key_size(const struct lu_env *env, const struct dt_it *di) { struct osd_zap_it *it = (struct osd_zap_it *)di; int rc; ENTRY; it->ozi_reset = 0; rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, it->ozi_name, NAME_MAX + 1); if (!rc) RETURN(strlen(it->ozi_name)); else RETURN(rc); }
static struct dt_key *osd_zap_it_key(const struct lu_env *env, const struct dt_it *di) { struct osd_zap_it *it = (struct osd_zap_it *)di; int rc = 0; ENTRY; it->ozi_reset = 0; rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, it->ozi_name, NAME_MAX + 1); if (!rc) RETURN((struct dt_key *)it->ozi_name); else RETURN(ERR_PTR(rc)); }
/** * Return pointer to the key under iterator. * * \param di - osd iterator */ static struct dt_key *osd_it_acct_key(const struct lu_env *env, const struct dt_it *di) { struct osd_it_quota *it = (struct osd_it_quota *)di; struct osd_thread_info *info = osd_oti_get(env); char *buf = info->oti_buf; char *p; int rc; ENTRY; it->oiq_reset = 0; rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, buf, 32); if (rc) RETURN(ERR_PTR(rc)); it->oiq_id = simple_strtoull(buf, &p, 16); RETURN((struct dt_key *) &it->oiq_id); }
/** * to load a directory entry at a time and stored it in * iterator's in-memory data structure. * * \param di, struct osd_it_ea, iterator's in memory structure * * \retval +ve, iterator reached to end * \retval 0, iterator not reached to end * \retval -ve, on error */ static int osd_zap_it_next(const struct lu_env *env, struct dt_it *di) { struct osd_zap_it *it = (struct osd_zap_it *)di; int rc; ENTRY; if (it->ozi_reset == 0) zap_cursor_advance(it->ozi_zc); it->ozi_reset = 0; /* * According to current API we need to return error if its last entry. * zap_cursor_advance() does return any value. So we need to call * retrieve to check if there is any record. We should make * changes to Iterator API to not return status for this API */ rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, NULL, NAME_MAX); if (rc == -ENOENT) /* end of dir*/ RETURN(+1); RETURN((rc)); }
/** * Restore iterator from cookie. if the \a hash isn't found, * restore the first valid record. * * \param di - osd iterator * \param hash - iterator location cookie * * \retval +ve - di points to exact matched key * \retval 0 - di points to the first valid record * \retval -ve - failure */ static int osd_it_acct_load(const struct lu_env *env, const struct dt_it *di, __u64 hash) { struct osd_it_quota *it = (struct osd_it_quota *)di; struct osd_device *osd = osd_obj2dev(it->oiq_obj); zap_cursor_t *zc; int rc; ENTRY; /* create new cursor pointing to the new hash */ rc = -udmu_zap_cursor_init(&zc, &osd->od_objset, it->oiq_oid, hash); if (rc) RETURN(rc); udmu_zap_cursor_fini(it->oiq_zc); it->oiq_zc = zc; it->oiq_reset = 0; rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, NULL, 32); if (rc == 0) RETURN(+1); else if (rc == -ENOENT) RETURN(0); RETURN(rc); }