Пример #1
0
static struct dt_it *osd_index_it_init(const struct lu_env *env,
				       struct dt_object *dt,
				       __u32 unused,
				       struct lustre_capa *capa)
{
	struct osd_thread_info  *info = osd_oti_get(env);
	struct osd_zap_it       *it;
	struct osd_object       *obj = osd_dt_obj(dt);
	struct osd_device       *osd = osd_obj2dev(obj);
	struct lu_object        *lo  = &dt->do_lu;
	ENTRY;

	/* XXX: check capa ? */

	LASSERT(lu_object_exists(lo));
	LASSERT(obj->oo_db);
	LASSERT(udmu_object_is_zap(obj->oo_db));
	LASSERT(info);

	it = &info->oti_it_zap;

	if (udmu_zap_cursor_init(&it->ozi_zc, &osd->od_objset,
				 obj->oo_db->db_object, 0))
		RETURN(ERR_PTR(-ENOMEM));

	it->ozi_obj   = obj;
	it->ozi_capa  = capa;
	it->ozi_reset = 1;
	lu_object_get(lo);

	RETURN((struct dt_it *)it);
}
Пример #2
0
static int mdd_lpf_setup(const struct lu_env *env, struct mdd_device *m)
{
	struct md_object	*mdo;
	struct mdd_object	*mdd_lpf;
	struct lu_fid		 fid	= LU_LPF_FID;
	int			 rc;
	ENTRY;

	rc = mdd_local_file_create(env, m, mdd_object_fid(m->mdd_dot_lustre),
				   mdd_lpf_dir_name, S_IFDIR | S_IRUSR | S_IXUSR,
				   &fid);
	if (rc != 0)
		RETURN(rc);

	mdo = mdo_locate(env, &m->mdd_md_dev, &fid);
	if (IS_ERR(mdo))
		RETURN(PTR_ERR(mdo));

	LASSERT(lu_object_exists(&mdo->mo_lu));

	mdd_lpf = md2mdd_obj(mdo);
	mdd_lpf->mod_obj.mo_dir_ops = &mdd_lpf_dir_ops;
	m->mdd_dot_lustre_objs.mdd_lpf = mdd_lpf;

	RETURN(0);
}
Пример #3
0
/**
 * open the PENDING directory for device \a mdd
 *
 * The PENDING directory persistently tracks files and directories that were
 * unlinked from the namespace (nlink == 0) but are still held open by clients.
 * Those inodes shouldn't be deleted if the MDS crashes, because the clients
 * would not be able to recover and reopen those files.  Instead, these inodes
 * are linked into the PENDING directory on disk, and only deleted if all
 * clients close them, or the MDS finishes client recovery without any client
 * reopening them (i.e. former clients didn't join recovery).
 *  \param d   mdd device being started.
 *
 *  \retval 0  success
 *  \retval  -ve index operation error.
 *
 */
int orph_index_init(const struct lu_env *env, struct mdd_device *mdd)
{
	struct lu_fid		 fid;
	struct dt_object	*d;
	int			 rc = 0;

	ENTRY;

	/* create PENDING dir */
	fid_zero(&fid);
	rc = mdd_local_file_create(env, mdd, &mdd->mdd_local_root_fid,
				   orph_index_name, S_IFDIR | S_IRUGO |
				   S_IWUSR | S_IXUGO, &fid);
	if (rc < 0)
		RETURN(rc);

	d = dt_locate(env, mdd->mdd_child, &fid);
	if (IS_ERR(d))
		RETURN(PTR_ERR(d));
	LASSERT(lu_object_exists(&d->do_lu));
	if (!dt_try_as_dir(env, d)) {
		CERROR("%s: \"%s\" is not an index: rc = %d\n",
		       mdd2obd_dev(mdd)->obd_name, orph_index_name, rc);
		lu_object_put(env, &d->do_lu);
		RETURN(-ENOTDIR);
	}
	mdd->mdd_orphans = d;
	RETURN(0);
}
Пример #4
0
static int out_destroy(struct tgt_session_info *tsi)
{
	struct tgt_thread_info	*tti = tgt_th_info(tsi->tsi_env);
	struct update		*update = tti->tti_u.update.tti_update;
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	struct lu_fid		*fid;
	int			 rc;
	ENTRY;

	fid = &update->u_fid;
	fid_le_to_cpu(fid, fid);
	if (!fid_is_sane(fid)) {
		CERROR("%s: invalid FID "DFID": rc = %d\n",
		       tgt_name(tsi->tsi_tgt), PFID(fid), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	rc = out_tx_destroy(tsi->tsi_env, obj, &tti->tti_tea,
			    tti->tti_u.update.tti_update_reply,
			    tti->tti_u.update.tti_update_reply_index);

	RETURN(rc);
}
Пример #5
0
static int out_tx_xattr_set_exec(const struct lu_env *env,
				 struct thandle *th,
				 struct tx_arg *arg)
{
	struct dt_object *dt_obj = arg->object;
	int rc;

	CDEBUG(D_INFO, "%s: set xattr buf %p name %s flag %d\n",
	       dt_obd_name(th->th_dev), arg->u.xattr_set.buf.lb_buf,
	       arg->u.xattr_set.name, arg->u.xattr_set.flags);

	if (!lu_object_exists(&dt_obj->do_lu))
		GOTO(out, rc = -ENOENT);

	dt_write_lock(env, dt_obj, MOR_TGT_CHILD);
	rc = dt_xattr_set(env, dt_obj, &arg->u.xattr_set.buf,
			  arg->u.xattr_set.name, arg->u.xattr_set.flags,
			  th, NULL);
	dt_write_unlock(env, dt_obj);
	/**
	 * Ignore errors if this is LINK EA
	 **/
	if (unlikely(rc && !strcmp(arg->u.xattr_set.name, XATTR_NAME_LINK)))
		rc = 0;
out:
	CDEBUG(D_INFO, "%s: insert xattr set reply %p index %d: rc = %d\n",
	       dt_obd_name(th->th_dev), arg->reply, arg->index, rc);

	object_update_result_insert(arg->reply, NULL, 0, arg->index, rc);

	return rc;
}
Пример #6
0
/**
 * Initialize osd Iterator for given osd index object.
 *
 * \param  dt    - osd index object
 * \param  attr  - not used
 * \param  capa  - BYPASS_CAPA
 */
static struct dt_it *osd_it_acct_init(const struct lu_env *env,
				      struct dt_object *dt,
				      __u32 attr,
				      struct lustre_capa *capa)
{
	struct osd_thread_info	*info = osd_oti_get(env);
	struct osd_it_quota	*it;
	struct lu_object	*lo   = &dt->do_lu;
	struct osd_device	*osd  = osd_dev(lo->lo_dev);
	int			 rc;
	ENTRY;

	LASSERT(lu_object_exists(lo));

	if (info == NULL)
		RETURN(ERR_PTR(-ENOMEM));

	it = &info->oti_it_quota;
	memset(it, 0, sizeof(*it));
	it->oiq_oid = osd_quota_fid2dmu(lu_object_fid(lo));

	/* initialize zap cursor */
	rc = -udmu_zap_cursor_init(&it->oiq_zc, &osd->od_objset, it->oiq_oid,0);
	if (rc)
		RETURN(ERR_PTR(rc));

	/* take object reference */
	lu_object_get(lo);
	it->oiq_obj   = osd_dt_obj(dt);
	it->oiq_reset = 1;

	RETURN((struct dt_it *)it);
}
Пример #7
0
static int out_create(struct tgt_session_info *tsi)
{
	struct tgt_thread_info	*tti = tgt_th_info(tsi->tsi_env);
	struct object_update	*update = tti->tti_u.update.tti_update;
	struct dt_object        *obj = tti->tti_u.update.tti_dt_object;
	struct dt_object_format	*dof = &tti->tti_u.update.tti_update_dof;
	struct obdo		*lobdo = &tti->tti_u.update.tti_obdo;
	struct lu_attr		*attr = &tti->tti_attr;
	struct lu_fid		*fid = NULL;
	struct obdo		*wobdo;
	int			size;
	int			rc;

	ENTRY;

	wobdo = object_update_param_get(update, 0, &size);
	if (wobdo == NULL || size != sizeof(*wobdo)) {
		CERROR("%s: obdo is NULL, invalid RPC: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	obdo_le_to_cpu(wobdo, wobdo);
	lustre_get_wire_obdo(NULL, lobdo, wobdo);
	la_from_obdo(attr, lobdo, lobdo->o_valid);

	dof->dof_type = dt_mode_to_dft(attr->la_mode);
	if (update->ou_params_count > 1) {
		int size;

		fid = object_update_param_get(update, 1, &size);
		if (fid == NULL || size != sizeof(*fid)) {
			CERROR("%s: invalid fid: rc = %d\n",
			       tgt_name(tsi->tsi_tgt), -EPROTO);
			RETURN(err_serious(-EPROTO));
		}
		if (ptlrpc_req_need_swab(tsi->tsi_pill->rc_req))
			lustre_swab_lu_fid(fid);
		if (!fid_is_sane(fid)) {
			CERROR("%s: invalid fid "DFID": rc = %d\n",
			       tgt_name(tsi->tsi_tgt), PFID(fid), -EPROTO);
			RETURN(err_serious(-EPROTO));
		}
	}

	if (lu_object_exists(&obj->do_lu))
		RETURN(-EEXIST);

	rc = out_tx_create(tsi->tsi_env, obj, attr, fid, dof,
			   &tti->tti_tea,
			   tti->tti_u.update.tti_update_reply,
			   tti->tti_u.update.tti_update_reply_index);

	RETURN(rc);
}
Пример #8
0
static int out_xattr_get(struct tgt_session_info *tsi)
{
	const struct lu_env	   *env = tsi->tsi_env;
	struct tgt_thread_info	   *tti = tgt_th_info(env);
	struct object_update	   *update = tti->tti_u.update.tti_update;
	struct lu_buf		   *lbuf = &tti->tti_buf;
	struct object_update_reply *reply = tti->tti_u.update.tti_update_reply;
	struct dt_object           *obj = tti->tti_u.update.tti_dt_object;
	char			   *name;
	struct object_update_result *update_result;
	int			idx = tti->tti_u.update.tti_update_reply_index;
	int			   rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu)) {
		set_bit(LU_OBJECT_HEARD_BANSHEE,
			&obj->do_lu.lo_header->loh_flags);
		RETURN(-ENOENT);
	}

	name = object_update_param_get(update, 0, NULL);
	if (IS_ERR(name)) {
		CERROR("%s: empty name for xattr get: rc = %ld\n",
		       tgt_name(tsi->tsi_tgt), PTR_ERR(name));
		RETURN(PTR_ERR(name));
	}

	update_result = object_update_result_get(reply, 0, NULL);
	if (update_result == NULL) {
		CERROR("%s: empty name for xattr get: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), -EPROTO);
		RETURN(-EPROTO);
	}

	lbuf->lb_len = (int)tti->tti_u.update.tti_update->ou_result_size;
	lbuf->lb_buf = update_result->our_data;
	if (lbuf->lb_len == 0)
		lbuf->lb_buf = 0;
	dt_read_lock(env, obj, MOR_TGT_CHILD);
	rc = dt_xattr_get(env, obj, lbuf, name);
	dt_read_unlock(env, obj);
	if (rc < 0)
		lbuf->lb_len = 0;
	CDEBUG(D_INFO, "%s: "DFID" get xattr %s len %d\n",
	       tgt_name(tsi->tsi_tgt), PFID(lu_object_fid(&obj->do_lu)),
	       name, (int)lbuf->lb_len);

	GOTO(out, rc);

out:
	object_update_result_insert(reply, lbuf->lb_buf, lbuf->lb_len, idx, rc);
	RETURN(0);
}
Пример #9
0
static int out_index_lookup(struct tgt_session_info *tsi)
{
	const struct lu_env	*env = tsi->tsi_env;
	struct tgt_thread_info	*tti = tgt_th_info(env);
	struct object_update	*update = tti->tti_u.update.tti_update;
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	char			*name;
	int			 rc;

	ENTRY;

	if (unlikely(update->ou_result_size < sizeof(tti->tti_fid1)))
		return -EPROTO;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	name = object_update_param_get(update, 0, NULL);
	if (IS_ERR(name)) {
		CERROR("%s: empty name for lookup: rc = %ld\n",
		       tgt_name(tsi->tsi_tgt), PTR_ERR(name));
		RETURN(PTR_ERR(name));
	}

	dt_read_lock(env, obj, MOR_TGT_CHILD);
	if (!dt_try_as_dir(env, obj))
		GOTO(out_unlock, rc = -ENOTDIR);

	rc = dt_lookup(env, obj, (struct dt_rec *)&tti->tti_fid1,
		       (struct dt_key *)name);

	if (rc < 0)
		GOTO(out_unlock, rc);

	if (rc == 0)
		rc += 1;

out_unlock:
	dt_read_unlock(env, obj);

	CDEBUG(D_INFO, "lookup "DFID" %s get "DFID" rc %d\n",
	       PFID(lu_object_fid(&obj->do_lu)), name,
	       PFID(&tti->tti_fid1), rc);

	CDEBUG(D_INFO, "%s: insert lookup reply %p index %d: rc = %d\n",
	       tgt_name(tsi->tsi_tgt), tti->tti_u.update.tti_update_reply,
	       0, rc);

	object_update_result_insert(tti->tti_u.update.tti_update_reply,
			    &tti->tti_fid1, sizeof(tti->tti_fid1),
			    tti->tti_u.update.tti_update_reply_index, rc);
	RETURN(rc);
}
Пример #10
0
static int out_index_lookup(struct tgt_session_info *tsi)
{
	const struct lu_env	*env = tsi->tsi_env;
	struct tgt_thread_info	*tti = tgt_th_info(env);
	struct update		*update = tti->tti_u.update.tti_update;
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	char			*name;
	int			 rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	name = (char *)update_param_buf(update, 0, NULL);
	if (name == NULL) {
		CERROR("%s: empty name for lookup: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	dt_read_lock(env, obj, MOR_TGT_CHILD);
	if (!dt_try_as_dir(env, obj))
		GOTO(out_unlock, rc = -ENOTDIR);

	rc = dt_lookup(env, obj, (struct dt_rec *)&tti->tti_fid1,
		(struct dt_key *)name, NULL);

	if (rc < 0)
		GOTO(out_unlock, rc);

	if (rc == 0)
		rc += 1;

	CDEBUG(D_INFO, "lookup "DFID" %s get "DFID" rc %d\n",
	       PFID(lu_object_fid(&obj->do_lu)), name,
	       PFID(&tti->tti_fid1), rc);
	fid_cpu_to_le(&tti->tti_fid1, &tti->tti_fid1);

out_unlock:
	dt_read_unlock(env, obj);

	CDEBUG(D_INFO, "%s: insert lookup reply %p index %d: rc = %d\n",
	       tgt_name(tsi->tsi_tgt), tti->tti_u.update.tti_update_reply,
	       0, rc);

	update_insert_reply(tti->tti_u.update.tti_update_reply,
			    &tti->tti_fid1, sizeof(tti->tti_fid1), 0, rc);
	RETURN(rc);
}
Пример #11
0
static int out_ref_del(struct mdt_thread_info *info)
{
	struct dt_object  *obj = info->mti_u.update.mti_dt_object;
	int		  rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	rc = out_tx_ref_del(info, obj, &info->mti_handle,
			    info->mti_u.update.mti_update_reply,
			    info->mti_u.update.mti_update_reply_index);
	RETURN(rc);
}
Пример #12
0
/**
 * Find the osd object for given fid.
 *
 * \param fid need to find the osd object having this fid
 *
 * \retval osd_object on success
 * \retval        -ve on error
 */
struct osd_object *osd_object_find(const struct lu_env *env,
				   struct dt_object *dt,
				   const struct lu_fid *fid)
{
	struct lu_device         *ludev = dt->do_lu.lo_dev;
	struct osd_object        *child = NULL;
	struct lu_object         *luch;
	struct lu_object         *lo;

	/*
	 * at this point topdev might not exist yet
	 * (i.e. MGS is preparing profiles). so we can
	 * not rely on topdev and instead lookup with
	 * our device passed as topdev. this can't work
	 * if the object isn't cached yet (as osd doesn't
	 * allocate lu_header). IOW, the object must be
	 * in the cache, otherwise lu_object_alloc() crashes
	 * -bzzz
	 */
	luch = lu_object_find_at(env, ludev, fid, NULL);
	if (IS_ERR(luch))
		return (void *)luch;

	if (lu_object_exists(luch)) {
		lo = lu_object_locate(luch->lo_header, ludev->ld_type);
		if (lo != NULL)
			child = osd_obj(lo);
		else
			LU_OBJECT_DEBUG(D_ERROR, env, luch,
					"%s: object can't be located "DFID"\n",
					osd_dev(ludev)->od_svname, PFID(fid));

		if (child == NULL) {
			lu_object_put(env, luch);
			CERROR("%s: Unable to get osd_object "DFID"\n",
			       osd_dev(ludev)->od_svname, PFID(fid));
			child = ERR_PTR(-ENOENT);
		}
	} else {
		LU_OBJECT_DEBUG(D_ERROR, env, luch,
				"%s: lu_object does not exists "DFID"\n",
				osd_dev(ludev)->od_svname, PFID(fid));
		lu_object_put(env, luch);
		child = ERR_PTR(-ENOENT);
	}

	return child;
}
Пример #13
0
static int out_ref_del(struct tgt_session_info *tsi)
{
	struct tgt_thread_info	*tti = tgt_th_info(tsi->tsi_env);
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	int			 rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	rc = out_tx_ref_del(tsi->tsi_env, obj, &tti->tti_tea,
			    tti->tti_u.update.tti_update_reply,
			    tti->tti_u.update.tti_update_reply_index);
	RETURN(rc);
}
Пример #14
0
static int out_attr_get(struct tgt_session_info *tsi)
{
	const struct lu_env	*env = tsi->tsi_env;
	struct tgt_thread_info	*tti = tgt_th_info(env);
	struct object_update	*update = tti->tti_u.update.tti_update;
	struct obdo		*obdo = &tti->tti_u.update.tti_obdo;
	struct lu_attr		*la = &tti->tti_attr;
	struct dt_object        *obj = tti->tti_u.update.tti_dt_object;
	int			idx = tti->tti_u.update.tti_update_reply_index;
	int			rc;

	ENTRY;

	if (unlikely(update->ou_result_size < sizeof(*obdo)))
		return -EPROTO;

	if (!lu_object_exists(&obj->do_lu)) {
		/* Usually, this will be called when the master MDT try
		 * to init a remote object(see osp_object_init), so if
		 * the object does not exist on slave, we need set BANSHEE flag,
		 * so the object can be removed from the cache immediately */
		set_bit(LU_OBJECT_HEARD_BANSHEE,
			&obj->do_lu.lo_header->loh_flags);
		RETURN(-ENOENT);
	}

	dt_read_lock(env, obj, MOR_TGT_CHILD);
	rc = dt_attr_get(env, obj, la);
	if (rc)
		GOTO(out_unlock, rc);

	obdo->o_valid = 0;
	obdo_from_la(obdo, la, la->la_valid);
	lustre_set_wire_obdo(NULL, obdo, obdo);

out_unlock:
	dt_read_unlock(env, obj);

	CDEBUG(D_INFO, "%s: insert attr get reply %p index %d: rc = %d\n",
	       tgt_name(tsi->tsi_tgt), tti->tti_u.update.tti_update_reply,
	       0, rc);

	object_update_result_insert(tti->tti_u.update.tti_update_reply, obdo,
				    sizeof(*obdo), idx, rc);

	RETURN(rc);
}
Пример #15
0
static int out_index_lookup(struct mdt_thread_info *info)
{
	struct update		*update = info->mti_u.update.mti_update;
	const struct lu_env	*env = info->mti_env;
	struct dt_object	*obj = info->mti_u.update.mti_dt_object;
	char			*name;
	int			rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	name = (char *)update_param_buf(update, 0, NULL);
	if (name == NULL) {
		CERROR("%s: empty name for lookup: rc = %d\n",
		       mdt_obd_name(info->mti_mdt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	dt_read_lock(env, obj, MOR_TGT_CHILD);
	if (!dt_try_as_dir(env, obj))
		GOTO(out_unlock, rc = -ENOTDIR);

	rc = dt_lookup(env, obj, (struct dt_rec *)&info->mti_tmp_fid1,
		(struct dt_key *)name, NULL);

	if (rc < 0)
		GOTO(out_unlock, rc);

	if (rc == 0)
		rc += 1;

	CDEBUG(D_INFO, "lookup "DFID" %s get "DFID" rc %d\n",
	       PFID(lu_object_fid(&obj->do_lu)), name,
	       PFID(&info->mti_tmp_fid1), rc);
	fid_cpu_to_le(&info->mti_tmp_fid1, &info->mti_tmp_fid1);

out_unlock:
	dt_read_unlock(env, obj);
	update_insert_reply(info->mti_u.update.mti_update_reply,
			    &info->mti_tmp_fid1, sizeof(info->mti_tmp_fid1),
			    0, rc);
	RETURN(rc);
}
Пример #16
0
/** Setup ".lustre" directory object */
static int mdd_dot_lustre_setup(const struct lu_env *env, struct mdd_device *m)
{
	struct md_object	*mdo;
	struct lu_fid		 fid;
	int			 rc;

	ENTRY;
	/* Create ".lustre" directory in ROOT. */
	fid = LU_DOT_LUSTRE_FID;
	rc = mdd_local_file_create(env, m, &m->mdd_root_fid,
				   dot_lustre_name,
				   S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO,
				   &fid);
	if (rc < 0)
		RETURN(rc);
	mdo = mdo_locate(env, &m->mdd_md_dev, &fid);
	if (IS_ERR(mdo))
		RETURN(PTR_ERR(mdo));
	LASSERT(lu_object_exists(&mdo->mo_lu));

	m->mdd_dot_lustre = md2mdd_obj(mdo);

	rc = mdd_obf_setup(env, m);
	if (rc) {
		CERROR("%s: error initializing \"fid\" object: rc = %d.\n",
		       mdd2obd_dev(m)->obd_name, rc);
		GOTO(out, rc);
	}

	rc = mdd_lpf_setup(env, m);
	if (rc != 0) {
		CERROR("%s: error initializing \"lost+found\": rc = %d.\n",
		       mdd2obd_dev(m)->obd_name, rc);
		GOTO(out, rc);
	}

	RETURN(0);

out:
	mdd_dot_lustre_cleanup(env, m);

	return rc;
}
Пример #17
0
static int out_index_delete(struct mdt_thread_info *info)
{
	struct update		*update = info->mti_u.update.mti_update;
	struct dt_object	*obj = info->mti_u.update.mti_dt_object;
	char			*name;
	int			rc = 0;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);
	name = (char *)update_param_buf(update, 0, NULL);
	if (name == NULL) {
		CERROR("%s: empty name for index delete: rc = %d\n",
		       mdt_obd_name(info->mti_mdt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	rc = out_tx_index_delete(info, obj, name, &info->mti_handle,
				 info->mti_u.update.mti_update_reply,
				 info->mti_u.update.mti_update_reply_index);
	RETURN(rc);
}
Пример #18
0
static int __out_tx_index_insert(const struct lu_env *env,
				 struct dt_object *dt_obj,
				 char *name, struct lu_fid *fid,
				 struct thandle_exec_args *ta,
				 struct update_reply *reply,
				 int index, char *file, int line)
{
	struct tx_arg *arg;

	LASSERT(ta->ta_handle != NULL);

	if (lu_object_exists(&dt_obj->do_lu)) {
		if (dt_try_as_dir(env, dt_obj) == 0) {
			ta->ta_err = -ENOTDIR;
			return ta->ta_err;
		}
		ta->ta_err = dt_declare_insert(env, dt_obj,
					       (struct dt_rec *)fid,
					       (struct dt_key *)name,
					       ta->ta_handle);
	}

	if (ta->ta_err != 0)
		return ta->ta_err;

	arg = tx_add_exec(ta, out_tx_index_insert_exec,
			  out_tx_index_insert_undo, file,
			  line);
	LASSERT(arg);
	lu_object_get(&dt_obj->do_lu);
	arg->object = dt_obj;
	arg->reply = reply;
	arg->index = index;
	arg->u.insert.rec = (struct dt_rec *)fid;
	arg->u.insert.key = (struct dt_key *)name;

	return 0;
}
Пример #19
0
static int out_index_delete(struct tgt_session_info *tsi)
{
	struct tgt_thread_info	*tti = tgt_th_info(tsi->tsi_env);
	struct update		*update = tti->tti_u.update.tti_update;
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	char			*name;
	int			 rc = 0;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	name = (char *)update_param_buf(update, 0, NULL);
	if (name == NULL) {
		CERROR("%s: empty name for index delete: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	rc = out_tx_index_delete(tsi->tsi_env, obj, name, &tti->tti_tea,
				 tti->tti_u.update.tti_update_reply,
				 tti->tti_u.update.tti_update_reply_index);
	RETURN(rc);
}
Пример #20
0
static int out_index_delete(struct tgt_session_info *tsi)
{
	struct tgt_thread_info	*tti = tgt_th_info(tsi->tsi_env);
	struct object_update	*update = tti->tti_u.update.tti_update;
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	char			*name;
	int			 rc = 0;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	name = object_update_param_get(update, 0, NULL);
	if (IS_ERR(name)) {
		CERROR("%s: empty name for index delete: rc = %ld\n",
		       tgt_name(tsi->tsi_tgt), PTR_ERR(name));
		RETURN(PTR_ERR(name));
	}

	rc = out_tx_index_delete(tsi->tsi_env, obj, (const struct dt_key *)name,
				 &tti->tti_tea, tti->tti_tea.ta_handle,
				 tti->tti_u.update.tti_update_reply,
				 tti->tti_u.update.tti_update_reply_index);
	RETURN(rc);
}
Пример #21
0
static int out_attr_get(struct tgt_session_info *tsi)
{
	const struct lu_env	*env = tsi->tsi_env;
	struct tgt_thread_info	*tti = tgt_th_info(env);
	struct obdo		*obdo = &tti->tti_u.update.tti_obdo;
	struct lu_attr		*la = &tti->tti_attr;
	struct dt_object        *obj = tti->tti_u.update.tti_dt_object;
	int			rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu))
		RETURN(-ENOENT);

	dt_read_lock(env, obj, MOR_TGT_CHILD);
	rc = dt_attr_get(env, obj, la, NULL);
	if (rc)
		GOTO(out_unlock, rc);
	/*
	 * If it is a directory, we will also check whether the
	 * directory is empty.
	 * la_flags = 0 : Empty.
	 *          = 1 : Not empty.
	 */
	la->la_flags = 0;
	if (S_ISDIR(la->la_mode)) {
		struct dt_it		*it;
		const struct dt_it_ops	*iops;

		if (!dt_try_as_dir(env, obj))
			GOTO(out_unlock, rc = -ENOTDIR);

		iops = &obj->do_index_ops->dio_it;
		it = iops->init(env, obj, LUDA_64BITHASH, BYPASS_CAPA);
		if (!IS_ERR(it)) {
			int  result;
			result = iops->get(env, it, (const void *)"");
			if (result > 0) {
				int i;
				for (result = 0, i = 0; result == 0 && i < 3;
				     ++i)
					result = iops->next(env, it);
				if (result == 0)
					la->la_flags = 1;
			} else if (result == 0)
				/*
				 * Huh? Index contains no zero key?
				 */
				rc = -EIO;

			iops->put(env, it);
			iops->fini(env, it);
		}
	}

	obdo->o_valid = 0;
	obdo_from_la(obdo, la, la->la_valid);
	obdo_cpu_to_le(obdo, obdo);
	lustre_set_wire_obdo(NULL, obdo, obdo);

out_unlock:
	dt_read_unlock(env, obj);

	CDEBUG(D_INFO, "%s: insert attr get reply %p index %d: rc = %d\n",
	       tgt_name(tsi->tsi_tgt), tti->tti_u.update.tti_update_reply,
	       0, rc);

	update_insert_reply(tti->tti_u.update.tti_update_reply, obdo,
			    sizeof(*obdo), 0, rc);
	RETURN(rc);
}
Пример #22
0
static int out_attr_get(struct tgt_session_info *tsi)
{
	const struct lu_env	*env = tsi->tsi_env;
	struct tgt_thread_info	*tti = tgt_th_info(env);
	struct obdo		*obdo = &tti->tti_u.update.tti_obdo;
	struct lu_attr		*la = &tti->tti_attr;
	struct dt_object        *obj = tti->tti_u.update.tti_dt_object;
	int			idx = tti->tti_u.update.tti_update_reply_index;
	int			rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu)) {
		/* Usually, this will be called when the master MDT try
		 * to init a remote object(see osp_object_init), so if
		 * the object does not exist on slave, we need set BANSHEE flag,
		 * so the object can be removed from the cache immediately */
		set_bit(LU_OBJECT_HEARD_BANSHEE,
			&obj->do_lu.lo_header->loh_flags);
		RETURN(-ENOENT);
	}

	dt_read_lock(env, obj, MOR_TGT_CHILD);
	rc = dt_attr_get(env, obj, la, NULL);
	if (rc)
		GOTO(out_unlock, rc);
	/*
	 * If it is a directory, we will also check whether the
	 * directory is empty.
	 * la_flags = 0 : Empty.
	 *          = 1 : Not empty.
	 */
	la->la_flags = 0;
	if (S_ISDIR(la->la_mode)) {
		struct dt_it		*it;
		const struct dt_it_ops	*iops;

		if (!dt_try_as_dir(env, obj))
			GOTO(out_unlock, rc = -ENOTDIR);

		iops = &obj->do_index_ops->dio_it;
		it = iops->init(env, obj, LUDA_64BITHASH, BYPASS_CAPA);
		if (!IS_ERR(it)) {
			int  result;
			result = iops->get(env, it, (const void *)"");
			if (result > 0) {
				int i;
				for (result = 0, i = 0; result == 0 && i < 3;
				     ++i)
					result = iops->next(env, it);
				if (result == 0)
					la->la_flags = 1;
			} else if (result == 0)
				/*
				 * Huh? Index contains no zero key?
				 */
				rc = -EIO;

			iops->put(env, it);
			iops->fini(env, it);
		}
	}

	obdo->o_valid = 0;
	obdo_from_la(obdo, la, la->la_valid);
	obdo_cpu_to_le(obdo, obdo);
	lustre_set_wire_obdo(NULL, obdo, obdo);

out_unlock:
	dt_read_unlock(env, obj);

	CDEBUG(D_INFO, "%s: insert attr get reply %p index %d: rc = %d\n",
	       tgt_name(tsi->tsi_tgt), tti->tti_u.update.tti_update_reply,
	       0, rc);

	object_update_result_insert(tti->tti_u.update.tti_update_reply, obdo,
				    sizeof(*obdo), idx, rc);

	RETURN(rc);
}
Пример #23
0
static int out_read(struct tgt_session_info *tsi)
{
	const struct lu_env	*env = tsi->tsi_env;
	struct tgt_thread_info	*tti = tgt_th_info(env);
	struct object_update	*update = tti->tti_u.update.tti_update;
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	struct object_update_reply *reply = tti->tti_u.update.tti_update_reply;
	int index = tti->tti_u.update.tti_update_reply_index;
	struct lu_rdbuf	*rdbuf;
	struct object_update_result *update_result;
	struct out_read_reply	*orr;
	void *tmp;
	size_t size;
	size_t total_size = 0;
	__u64 pos;
	unsigned int i;
	unsigned int nbufs;
	int rc = 0;
	ENTRY;

	update_result = object_update_result_get(reply, index, NULL);
	LASSERT(update_result != NULL);
	update_result->our_datalen = sizeof(*orr);

	if (!lu_object_exists(&obj->do_lu))
		GOTO(out, rc = -ENOENT);

	tmp = object_update_param_get(update, 0, NULL);
	if (IS_ERR(tmp)) {
		CERROR("%s: empty size for read: rc = %ld\n",
		       tgt_name(tsi->tsi_tgt), PTR_ERR(tmp));
		GOTO(out, rc = PTR_ERR(tmp));
	}
	size = le64_to_cpu(*(size_t *)(tmp));

	tmp = object_update_param_get(update, 1, NULL);
	if (IS_ERR(tmp)) {
		CERROR("%s: empty pos for read: rc = %ld\n",
		       tgt_name(tsi->tsi_tgt), PTR_ERR(tmp));
		GOTO(out, rc = PTR_ERR(tmp));
	}
	pos = le64_to_cpu(*(__u64 *)(tmp));

	/* Put the offset into the begining of the buffer in reply */
	orr = (struct out_read_reply *)update_result->our_data;

	nbufs = (size + OUT_BULK_BUFFER_SIZE - 1) / OUT_BULK_BUFFER_SIZE;
	OBD_ALLOC(rdbuf, sizeof(struct lu_rdbuf) +
			 nbufs * sizeof(rdbuf->rb_bufs[0]));
	if (rdbuf == NULL)
		GOTO(out, rc = -ENOMEM);

	rdbuf->rb_nbufs = 0;
	total_size = 0;
	for (i = 0; i < nbufs; i++) {
		__u32 read_size;

		read_size = size > OUT_BULK_BUFFER_SIZE ?
			    OUT_BULK_BUFFER_SIZE : size;
		OBD_ALLOC(rdbuf->rb_bufs[i].lb_buf, read_size);
		if (rdbuf->rb_bufs[i].lb_buf == NULL)
			GOTO(out_free, rc = -ENOMEM);

		rdbuf->rb_bufs[i].lb_len = read_size;
		dt_read_lock(env, obj, MOR_TGT_CHILD);
		rc = dt_read(env, obj, &rdbuf->rb_bufs[i], &pos);
		dt_read_unlock(env, obj);

		total_size += rc < 0 ? 0 : rc;
		if (rc <= 0)
			break;

		rdbuf->rb_nbufs++;
		size -= read_size;
	}

	/* send pages to client */
	rc = tgt_send_buffer(tsi, rdbuf);
	if (rc < 0)
		GOTO(out_free, rc);

	orr->orr_size = total_size;
	orr->orr_offset = pos;

	orr_cpu_to_le(orr, orr);
	update_result->our_datalen += orr->orr_size;
out_free:
	for (i = 0; i < nbufs; i++) {
		if (rdbuf->rb_bufs[i].lb_buf != NULL) {
			OBD_FREE(rdbuf->rb_bufs[i].lb_buf,
				 rdbuf->rb_bufs[i].lb_len);
		}
	}
	OBD_FREE(rdbuf, sizeof(struct lu_rdbuf) +
			nbufs * sizeof(rdbuf->rb_bufs[0]));
out:
	/* Insert read buffer */
	update_result->our_rc = ptlrpc_status_hton(rc);
	reply->ourp_lens[index] = cfs_size_round(update_result->our_datalen +
						 sizeof(*update_result));
	RETURN(rc);
}