Esempio n. 1
0
static void
llu_lookup_finish_locks(struct lookup_intent *it, struct pnode *pnode)
{
        struct inode *inode;
        LASSERT(it);
        LASSERT(pnode);

        inode = pnode->p_base->pb_ino;
        if (it->d.lustre.it_lock_mode && inode != NULL) {
                struct llu_sb_info *sbi;

                CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%llu/%lu)\n",
                       inode, (long long)llu_i2stat(inode)->st_ino,
                       llu_i2info(inode)->lli_st_generation);

                sbi = llu_i2sbi(inode);
                md_set_lock_data(sbi->ll_md_exp,
                                 &it->d.lustre.it_lock_handle, inode, NULL);
        }

        /* drop lookup/getattr locks */
        if (it->it_op & (IT_LOOKUP | IT_GETATTR))
                ll_intent_release(it);

}
Esempio n. 2
0
void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry)
{
        LASSERT(it != NULL);
        LASSERT(dentry != NULL);

        if (it->d.lustre.it_lock_mode && dentry->d_inode != NULL) {
                struct inode *inode = dentry->d_inode;
                struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);

                CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
                       inode, inode->i_ino, inode->i_generation);
                md_set_lock_data(sbi->ll_md_exp, &it->d.lustre.it_lock_handle,
                                 inode, NULL);
        }

        /* drop lookup or getattr locks immediately */
        if (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR) {
                /* on 2.6 there are situation when several lookups and
                 * revalidations may be requested during single operation.
                 * therefore, we don't release intent here -bzzz */
                ll_intent_drop_lock(it);
        }
}
Esempio n. 3
0
int lmv_revalidate_slaves(struct obd_export *exp,
			  const struct lmv_stripe_md *lsm,
			  ldlm_blocking_callback cb_blocking,
			  int extra_lock_flags)
{
	struct obd_device      *obd = exp->exp_obd;
	struct lmv_obd         *lmv = &obd->u.lmv;
	struct ptlrpc_request	*req = NULL;
	struct mdt_body		*body;
	struct md_op_data      *op_data;
	int                     i;
	int                     rc = 0;

	ENTRY;

	/**
	 * revalidate slaves has some problems, temporarily return,
	 * we may not need that
	 */
	OBD_ALLOC_PTR(op_data);
	if (op_data == NULL)
		RETURN(-ENOMEM);

	/**
	 * Loop over the stripe information, check validity and update them
	 * from MDS if needed.
	 */
	for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
		struct lu_fid		fid;
		struct lookup_intent	it = { .it_op = IT_GETATTR };
		struct lustre_handle	*lockh = NULL;
		struct lmv_tgt_desc	*tgt = NULL;
		struct inode		*inode;

		fid = lsm->lsm_md_oinfo[i].lmo_fid;
		inode = lsm->lsm_md_oinfo[i].lmo_root;

		/*
		 * Prepare op_data for revalidating. Note that @fid2 shluld be
		 * defined otherwise it will go to server and take new lock
		 * which is not needed here.
		 */
		memset(op_data, 0, sizeof(*op_data));
		op_data->op_fid1 = fid;
		op_data->op_fid2 = fid;

		tgt = lmv_locate_mds(lmv, op_data, &fid);
		if (IS_ERR(tgt))
			GOTO(cleanup, rc = PTR_ERR(tgt));

		CDEBUG(D_INODE, "Revalidate slave "DFID" -> mds #%u\n",
		       PFID(&fid), tgt->ltd_idx);

		if (req != NULL) {
			ptlrpc_req_finished(req);
			req = NULL;
		}

		rc = md_intent_lock(tgt->ltd_exp, op_data, &it, &req,
				    cb_blocking, extra_lock_flags);
		if (rc < 0)
			GOTO(cleanup, rc);

		lockh = (struct lustre_handle *)&it.d.lustre.it_lock_handle;
		if (rc > 0 && req == NULL) {
			/* slave inode is still valid */
			CDEBUG(D_INODE, "slave "DFID" is still valid.\n",
			       PFID(&fid));
			rc = 0;
		} else {
			/* refresh slave from server */
			body = req_capsule_server_get(&req->rq_pill,
						      &RMF_MDT_BODY);
			if (body == NULL) {
				if (it.d.lustre.it_lock_mode && lockh) {
					ldlm_lock_decref(lockh,
						 it.d.lustre.it_lock_mode);
					it.d.lustre.it_lock_mode = 0;
				}
				GOTO(cleanup, rc = -ENOENT);
			}

			i_size_write(inode, body->mbo_size);
			inode->i_blocks = body->mbo_blocks;
			set_nlink(inode, body->mbo_nlink);
			LTIME_S(inode->i_atime) = body->mbo_atime;
			LTIME_S(inode->i_ctime) = body->mbo_ctime;
			LTIME_S(inode->i_mtime) = body->mbo_mtime;
		}

		md_set_lock_data(tgt->ltd_exp, &lockh->cookie, inode, NULL);
		if (it.d.lustre.it_lock_mode != 0 && lockh != NULL) {
			ldlm_lock_decref(lockh, it.d.lustre.it_lock_mode);
			it.d.lustre.it_lock_mode = 0;
		}
	}

cleanup:
	if (req != NULL)
		ptlrpc_req_finished(req);

	OBD_FREE_PTR(op_data);
	RETURN(rc);
}
Esempio n. 4
0
int lmv_revalidate_slaves(struct obd_export *exp, struct mdt_body *mbody,
			  struct lmv_stripe_md *lsm,
			  ldlm_blocking_callback cb_blocking,
			  int extra_lock_flags)
{
	struct obd_device      *obd = exp->exp_obd;
	struct lmv_obd         *lmv = &obd->u.lmv;
	struct mdt_body		*body;
	struct md_op_data      *op_data;
	unsigned long           size = 0;
	unsigned long           nlink = 0;
	obd_time		atime = 0;
	obd_time		ctime = 0;
	obd_time		mtime = 0;
	int                     i;
	int                     rc = 0;

	ENTRY;

	/**
	 * revalidate slaves has some problems, temporarily return,
	 * we may not need that
	 */
	if (lsm->lsm_md_stripe_count <= 1)
		RETURN(0);

	OBD_ALLOC_PTR(op_data);
	if (op_data == NULL)
		RETURN(-ENOMEM);

	/**
	 * Loop over the stripe information, check validity and update them
	 * from MDS if needed.
	 */
	for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
		struct lu_fid		fid;
		struct lookup_intent	it = { .it_op = IT_GETATTR };
		struct ptlrpc_request	*req = NULL;
		struct lustre_handle	*lockh = NULL;
		struct lmv_tgt_desc	*tgt = NULL;
		struct inode		*inode;

		fid = lsm->lsm_md_oinfo[i].lmo_fid;
		inode = lsm->lsm_md_oinfo[i].lmo_root;
		if (i == 0) {
			if (mbody != NULL) {
				body = mbody;
				goto update;
			} else {
				goto release_lock;
			}
		}

		/*
		 * Prepare op_data for revalidating. Note that @fid2 shluld be
		 * defined otherwise it will go to server and take new lock
		 * which is not needed here.
		 */
		memset(op_data, 0, sizeof(*op_data));
		op_data->op_fid1 = fid;
		op_data->op_fid2 = fid;

		tgt = lmv_locate_mds(lmv, op_data, &fid);
		if (IS_ERR(tgt))
			GOTO(cleanup, rc = PTR_ERR(tgt));

		CDEBUG(D_INODE, "Revalidate slave "DFID" -> mds #%d\n",
		       PFID(&fid), tgt->ltd_idx);

		rc = md_intent_lock(tgt->ltd_exp, op_data, NULL, 0, &it, 0,
				    &req, cb_blocking, extra_lock_flags);
		if (rc < 0)
			GOTO(cleanup, rc);

		lockh = (struct lustre_handle *)&it.d.lustre.it_lock_handle;
		if (rc > 0 && req == NULL) {
			/* slave inode is still valid */
			CDEBUG(D_INODE, "slave "DFID" is still valid.\n",
			       PFID(&fid));
			rc = 0;
		} else {
			/* refresh slave from server */
			body = req_capsule_server_get(&req->rq_pill,
						      &RMF_MDT_BODY);
			LASSERT(body != NULL);
update:
			if (unlikely(body->nlink < 2)) {
				CERROR("%s: nlink %d < 2 corrupt stripe %d "DFID
				       ":" DFID"\n", obd->obd_name, body->nlink,
				       i, PFID(&lsm->lsm_md_oinfo[i].lmo_fid),
				       PFID(&lsm->lsm_md_oinfo[0].lmo_fid));

				if (req != NULL)
					ptlrpc_req_finished(req);

				if (it.d.lustre.it_lock_mode && lockh) {
					ldlm_lock_decref(lockh,
						 it.d.lustre.it_lock_mode);
					it.d.lustre.it_lock_mode = 0;
				}

				GOTO(cleanup, rc = -EIO);
			}

			if (i != 0)
				md_set_lock_data(tgt->ltd_exp, &lockh->cookie,
						 inode, NULL);

			i_size_write(inode, body->size);
			set_nlink(inode, body->nlink);
			LTIME_S(inode->i_atime) = body->atime;
			LTIME_S(inode->i_ctime) = body->ctime;
			LTIME_S(inode->i_mtime) = body->mtime;

			if (req != NULL)
				ptlrpc_req_finished(req);
		}
release_lock:
		size += i_size_read(inode);

		if (i != 0)
			nlink += inode->i_nlink - 2;
		else
			nlink += inode->i_nlink;

		atime = LTIME_S(inode->i_atime) > atime ?
				LTIME_S(inode->i_atime) : atime;
		ctime = LTIME_S(inode->i_ctime) > ctime ?
				LTIME_S(inode->i_ctime) : ctime;
		mtime = LTIME_S(inode->i_mtime) > mtime ?
				LTIME_S(inode->i_mtime) : mtime;

		if (it.d.lustre.it_lock_mode != 0 && lockh != NULL) {
			ldlm_lock_decref(lockh, it.d.lustre.it_lock_mode);
			it.d.lustre.it_lock_mode = 0;
		}

		CDEBUG(D_INODE, "i %d "DFID" size %llu, nlink %u, atime "
		       "%lu, mtime %lu, ctime %lu.\n", i, PFID(&fid),
		       i_size_read(inode), inode->i_nlink,
		       LTIME_S(inode->i_atime), LTIME_S(inode->i_mtime),
		       LTIME_S(inode->i_ctime));
	}

	/*
	 * update attr of master request.
	 */
	CDEBUG(D_INODE, "Return refreshed attrs: size = %lu nlink %lu atime "
	       LPU64 "ctime "LPU64" mtime "LPU64" for " DFID"\n", size, nlink,
	       atime, ctime, mtime, PFID(&lsm->lsm_md_oinfo[0].lmo_fid));

	if (mbody != NULL) {
		mbody->atime = atime;
		mbody->ctime = ctime;
		mbody->mtime = mtime;
	}
cleanup:
	OBD_FREE_PTR(op_data);
	RETURN(rc);
}