/* * Helper function looking up & creating if not found an index file with a * dynamic fid. */ static struct dt_object * lquota_disk_find_create(const struct lu_env *env, struct dt_device *dev, struct dt_object *parent, struct lu_fid *fid, const struct dt_index_features *idx_feat, char *name) { struct lquota_thread_info *qti = lquota_info(env); struct dt_object *obj; struct local_oid_storage *los; int rc; ENTRY; /* Set up local storage */ rc = local_oid_storage_init(env, dev, fid, &los); if (rc) RETURN(ERR_PTR(rc)); /* lookup/create slave index file */ obj = local_index_find_or_create(env, los, parent, name, LQUOTA_MODE, idx_feat); if (IS_ERR(obj)) GOTO(out, obj); /* local_oid_storage_fini() will finalize the local storage device, * we have to open the object in another device stack */ qti->qti_fid = obj->do_lu.lo_header->loh_fid; lu_object_put_nocache(env, &obj->do_lu); obj = dt_locate(env, dev, &qti->qti_fid); if (IS_ERR(obj)) GOTO(out, obj); out: local_oid_storage_fini(env, los); RETURN(obj); }
int mdd_local_file_create(const struct lu_env *env, struct mdd_device *mdd, const struct lu_fid *pfid, const char *name, __u32 mode, struct lu_fid *fid) { struct dt_object *parent, *dto; int rc; ENTRY; LASSERT(!fid_is_zero(pfid)); parent = dt_locate(env, mdd->mdd_bottom, pfid); if (unlikely(IS_ERR(parent))) RETURN(PTR_ERR(parent)); /* create local file/dir, if @fid is passed then try to use it */ if (fid_is_zero(fid)) dto = local_file_find_or_create(env, mdd->mdd_los, parent, name, mode); else dto = local_file_find_or_create_with_fid(env, mdd->mdd_bottom, fid, parent, name, mode); if (IS_ERR(dto)) GOTO(out_put, rc = PTR_ERR(dto)); *fid = *lu_object_fid(&dto->do_lu); /* since stack is not fully set up the local_storage uses own stack * and we should drop its object from cache */ lu_object_put_nocache(env, &dto->do_lu); EXIT; out_put: lu_object_put(env, &parent->do_lu); return 0; }
/* * Set up quota directory (either "quota_master" or "quota_slave") for a QMT or * QSD instance. This function is also used to create per-pool directory on * the quota master. * The directory is created with a local sequence if it does not exist already. * This function is called at ->ldo_prepare time when the full device stack is * configured. * * \param env - is the environment passed by the caller * \param dev - is the dt_device where to create the quota directory * \param parent - is the parent directory. If not specified, the directory * will be created under the root directory * \param name - is the name of quota directory to be created * * \retval - pointer to quota root dt_object on success, appropriate error * on failure */ struct dt_object *lquota_disk_dir_find_create(const struct lu_env *env, struct dt_device *dev, struct dt_object *parent, const char *name) { struct lquota_thread_info *qti = lquota_info(env); struct dt_object *qt_dir = NULL; struct local_oid_storage *los = NULL; int rc; ENTRY; /* Set up local storage to create the quota directory. * We use the sequence reserved for local named objects */ lu_local_name_obj_fid(&qti->qti_fid, 1); rc = local_oid_storage_init(env, dev, &qti->qti_fid, &los); if (rc) RETURN(ERR_PTR(rc)); if (parent == NULL) { /* Fetch dt object associated with root directory */ rc = dt_root_get(env, dev, &qti->qti_fid); if (rc) GOTO(out, rc); parent = dt_locate_at(env, dev, &qti->qti_fid, dev->dd_lu_dev.ld_site->ls_top_dev, NULL); if (IS_ERR(parent)) GOTO(out, rc = PTR_ERR(parent)); } else { lu_object_get(&parent->do_lu); } /* create quota directory to be used for all quota index files */ qt_dir = local_file_find_or_create(env, los, parent, name, S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO); if (IS_ERR(qt_dir)) GOTO(out, rc = PTR_ERR(qt_dir)); /* local_oid_storage_fini() will finalize the local storage device, * we have to open the object in another device stack */ qti->qti_fid = qt_dir->do_lu.lo_header->loh_fid; lu_object_put_nocache(env, &qt_dir->do_lu); qt_dir = dt_locate(env, dev, &qti->qti_fid); if (IS_ERR(qt_dir)) GOTO(out, rc = PTR_ERR(qt_dir)); if (!dt_try_as_dir(env, qt_dir)) GOTO(out, rc = -ENOTDIR); EXIT; out: if (parent != NULL && !IS_ERR(parent)) lu_object_put(env, &parent->do_lu); if (los != NULL) local_oid_storage_fini(env, los); if (rc) { if (qt_dir != NULL && !IS_ERR(qt_dir)) lu_object_put(env, &qt_dir->do_lu); qt_dir = ERR_PTR(rc); } return qt_dir; }