コード例 #1
0
ファイル: llog_lvfs.c プロジェクト: AkyZero/wrapfs-latest
/* This is a callback from the llog_* functions.
 * Assumes caller has already pushed us into the kernel context. */
static int llog_lvfs_create(const struct lu_env *env,
			    struct llog_handle *handle,
			    struct thandle *th)
{
	struct llog_ctxt	*ctxt = handle->lgh_ctxt;
	struct obd_device	*obd;
	struct dentry		*dchild = NULL;
	struct file		*file;
	struct obdo		*oa = NULL;
	int			 rc = 0;
	int			 open_flags = O_RDWR | O_CREAT | O_LARGEFILE;

	LASSERT(ctxt);
	LASSERT(ctxt->loc_exp);
	obd = ctxt->loc_exp->exp_obd;
	LASSERT(handle->lgh_file == NULL);

	if (handle->lgh_name) {
		file = llog_filp_open(MOUNT_CONFIGS_DIR, handle->lgh_name,
				      open_flags, 0644);
		if (IS_ERR(file))
			return PTR_ERR(file);

		lustre_build_llog_lvfs_oid(&handle->lgh_id,
				file->f_dentry->d_inode->i_ino,
				file->f_dentry->d_inode->i_generation);
		handle->lgh_file = file;
	} else {
		OBDO_ALLOC(oa);
		if (oa == NULL)
			return -ENOMEM;

		ostid_set_seq_llog(&oa->o_oi);
		oa->o_valid = OBD_MD_FLGENER | OBD_MD_FLGROUP;

		rc = obd_create(NULL, ctxt->loc_exp, oa, NULL, NULL);
		if (rc)
			GOTO(out, rc);

		/* FIXME: rationalize the misuse of o_generation in
		 *	this API along with mds_obd_{create,destroy}.
		 *	Hopefully it is only an internal API issue. */
#define o_generation o_parent_oid
		dchild = obd_lvfs_fid2dentry(ctxt->loc_exp, &oa->o_oi,
					     oa->o_generation);
		if (IS_ERR(dchild))
			GOTO(out, rc = PTR_ERR(dchild));

		file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild, open_flags);
		l_dput(dchild);
		if (IS_ERR(file))
			GOTO(out, rc = PTR_ERR(file));
		handle->lgh_id.lgl_oi = oa->o_oi;
		handle->lgh_id.lgl_ogen = oa->o_generation;
		handle->lgh_file = file;
out:
		OBDO_FREE(oa);
	}
	return rc;
}
コード例 #2
0
ファイル: filter_log.c プロジェクト: LLNL/lustre
/* Callback for processing the setattr log record received from MDS by
 * llog_client_api. */
static int filter_recov_log_setattr_cb(struct llog_ctxt *ctxt,
                                       struct llog_rec_hdr *rec,
                                       struct llog_cookie *cookie)
{
        struct obd_device *obd = ctxt->loc_obd;
        struct obd_export *exp = obd->obd_self_export;
        struct obd_info oinfo = { { { 0 } } };
        obd_id oid;
        int rc = 0;
        ENTRY;

        OBDO_ALLOC(oinfo.oi_oa);
        if (oinfo.oi_oa == NULL)
                RETURN(-ENOMEM);

        if (rec->lrh_type == MDS_SETATTR_REC) {
                struct llog_setattr_rec *lsr = (struct llog_setattr_rec *)rec;

                oinfo.oi_oa->o_id = lsr->lsr_oid;
                oinfo.oi_oa->o_seq = lsr->lsr_oseq;
                oinfo.oi_oa->o_uid = lsr->lsr_uid;
                oinfo.oi_oa->o_gid = lsr->lsr_gid;
        } else {
                struct llog_setattr64_rec *lsr = (struct llog_setattr64_rec *)rec;

                oinfo.oi_oa->o_id = lsr->lsr_oid;
                oinfo.oi_oa->o_seq = lsr->lsr_oseq;
                oinfo.oi_oa->o_uid = lsr->lsr_uid;
                oinfo.oi_oa->o_gid = lsr->lsr_gid;
        }

        oinfo.oi_oa->o_valid |= (OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID |
                                 OBD_MD_FLCOOKIE);
        oinfo.oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
        oinfo.oi_oa->o_lcookie = *cookie;
        oid = oinfo.oi_oa->o_id;

        rc = filter_setattr(exp, &oinfo, NULL);
        OBDO_FREE(oinfo.oi_oa);

        if (rc == -ENOENT) {
                CDEBUG(D_RPCTRACE, "object already removed, send cookie\n");
                llog_cancel(ctxt, NULL, 1, cookie, 0);
                RETURN(0);
        }

        if (rc == 0)
                CDEBUG(D_RPCTRACE, "object "LPU64" is chown/chgrp\n", oid);

        RETURN(rc);
}
コード例 #3
0
ファイル: llite_close.c プロジェクト: ORNL-TechInt/lustre
/**
 * Cliens updates SOM attributes on MDS (including llog cookies):
 * obd_getattr with no lock and md_setattr.
 */
int ll_som_update(struct inode *inode, struct md_op_data *op_data)
{
        struct ll_inode_info *lli = ll_i2info(inode);
        struct ptlrpc_request *request = NULL;
        __u32 old_flags;
        struct obdo *oa;
        int rc;
        ENTRY;

        LASSERT(op_data != NULL);
        if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
                CERROR("ino %lu/%u(flags %u) som valid it just after "
                       "recovery\n", inode->i_ino, inode->i_generation,
                       lli->lli_flags);

        OBDO_ALLOC(oa);
        if (!oa) {
                CERROR("can't allocate memory for Size-on-MDS update.\n");
                RETURN(-ENOMEM);
        }

        old_flags = op_data->op_flags;
        op_data->op_flags = MF_SOM_CHANGE;

        /* If inode is already in another epoch, skip getattr from OSTs. */
        if (lli->lli_ioepoch == op_data->op_ioepoch) {
                rc = ll_inode_getattr(inode, oa, op_data->op_ioepoch,
                                      old_flags & MF_GETATTR_LOCK);
                if (rc) {
                        oa->o_valid = 0;
			if (rc != -ENOENT)
                                CERROR("inode_getattr failed (%d): unable to "
                                       "send a Size-on-MDS attribute update "
                                       "for inode %lu/%u\n", rc, inode->i_ino,
                                       inode->i_generation);
                } else {
                        CDEBUG(D_INODE, "Size-on-MDS update on "DFID"\n",
                               PFID(&lli->lli_fid));
                }
                /* Install attributes into op_data. */
                md_from_obdo(op_data, oa, oa->o_valid);
        }

        rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data,
                        NULL, 0, NULL, 0, &request, NULL);
        ptlrpc_req_finished(request);

        OBDO_FREE(oa);
        RETURN(rc);
}
コード例 #4
0
ファイル: filter_log.c プロジェクト: LLNL/lustre
/* Callback for processing the unlink log record received from MDS by
 * llog_client_api. */
static int filter_recov_log_unlink_cb(struct llog_ctxt *ctxt,
                                      struct llog_rec_hdr *rec,
                                      struct llog_cookie *cookie)
{
        struct obd_export *exp = ctxt->loc_obd->obd_self_export;
        struct llog_unlink_rec *lur;
        struct obdo *oa;
        obd_id oid;
        obd_count count;
        int rc = 0;
        ENTRY;

        lur = (struct llog_unlink_rec *)rec;
        OBDO_ALLOC(oa);
        if (oa == NULL)
                RETURN(-ENOMEM);
        oa->o_valid |= OBD_MD_FLCOOKIE;
        oa->o_id = lur->lur_oid;
        oa->o_seq = lur->lur_oseq;
        oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
        oa->o_lcookie = *cookie;
        oid = oa->o_id;
        /* objid gap may require to destroy several objects in row */
        count = lur->lur_count + 1;

        /* This check is only valid before FID-on-OST and it should
         * be removed after FID-on-OST is implemented */
        if (oa->o_seq > FID_SEQ_OST_MAX) {
                CERROR("%s: invalid group number "LPU64" > MAX_CMD_GROUP %u\n",
                        exp->exp_obd->obd_name, oa->o_seq, FID_SEQ_OST_MAX);
                RETURN(-EINVAL);
        }

        while (count > 0) {
                rc = filter_destroy(exp, oa, NULL, NULL, NULL, NULL);
                if (rc == 0)
                        CDEBUG(D_RPCTRACE, "object "LPU64" is destroyed\n",
                               oid);
                else if (rc != -ENOENT)
                        CEMERG("error destroying object "LPU64": %d\n",
                               oid, rc);
                else
                        rc = 0;
                count--;
                oid++;
        }
        OBDO_FREE(oa);

        RETURN(rc);
}
コード例 #5
0
ファイル: file.c プロジェクト: DCteam/lustre
int llu_objects_destroy(struct ptlrpc_request *req, struct inode *dir)
{
        struct mdt_body *body;
        struct lov_mds_md *eadata;
        struct lov_stripe_md *lsm = NULL;
        struct obd_trans_info oti = { 0 };
        struct obdo *oa;
        int rc;
        ENTRY;

        body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);

        if (!(body->valid & OBD_MD_FLEASIZE))
                RETURN(0);

        if (body->eadatasize == 0) {
                CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
                GOTO(out, rc = -EPROTO);
        }

        /* The MDS sent back the EA because we unlinked the last reference
         * to this file. Use this EA to unlink the objects on the OST.
         * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
         * check it is complete and sensible. */
        eadata = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD,
                                              body->eadatasize);

        LASSERT(eadata != NULL);

        rc = obd_unpackmd(llu_i2obdexp(dir), &lsm, eadata,body->eadatasize);
        if (rc < 0) {
                CERROR("obd_unpackmd: %d\n", rc);
                GOTO(out, rc);
        }
        LASSERT(rc >= sizeof(*lsm));

        OBDO_ALLOC(oa);
        if (oa == NULL)
                GOTO(out_free_memmd, rc = -ENOMEM);

        oa->o_id = lsm->lsm_object_id;
        oa->o_seq = lsm->lsm_object_seq;
        oa->o_mode = body->mode & S_IFMT;
        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP;
        obdo_from_inode(oa, NULL, &llu_i2info(dir)->lli_fid, 0);

        if (body->valid & OBD_MD_FLCOOKIE) {
                oa->o_valid |= OBD_MD_FLCOOKIE;
                oti.oti_logcookies =
                        req_capsule_server_sized_get(&req->rq_pill,
                                                   &RMF_LOGCOOKIES,
                                                   sizeof(struct llog_cookie) *
                                                   lsm->lsm_stripe_count);
                if (oti.oti_logcookies == NULL) {
                        oa->o_valid &= ~OBD_MD_FLCOOKIE;
                        body->valid &= ~OBD_MD_FLCOOKIE;
                }
        }

        rc = obd_destroy(llu_i2obdexp(dir), oa, lsm, &oti, NULL, NULL);
        OBDO_FREE(oa);
        if (rc)
                CERROR("obd destroy objid 0x"LPX64" error %d\n",
                       lsm->lsm_object_id, rc);
 out_free_memmd:
        obd_free_memmd(llu_i2obdexp(dir), &lsm);
 out:
        return rc;
}
コード例 #6
0
ファイル: llog_lvfs.c プロジェクト: DCteam/lustre
static int llog_lvfs_destroy(struct llog_handle *handle)
{
        struct dentry *fdentry;
        struct obdo *oa;
        struct obd_device *obd = handle->lgh_ctxt->loc_exp->exp_obd;
        char *dir;
        void *th;
        struct inode *inode;
        int rc, rc1;
        ENTRY;

        dir = MOUNT_CONFIGS_DIR;

        fdentry = handle->lgh_file->f_dentry;
        inode = fdentry->d_parent->d_inode;
        if (strcmp(fdentry->d_parent->d_name.name, dir) == 0) {
                struct lvfs_run_ctxt saved;
                struct vfsmount *mnt = mntget(handle->lgh_file->f_vfsmnt);

                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
                dget(fdentry);
                rc = llog_lvfs_close(handle);

                if (rc == 0) {
                        LOCK_INODE_MUTEX_PARENT(inode);
                        rc = ll_vfs_unlink(inode, fdentry, mnt);
                        UNLOCK_INODE_MUTEX(inode);
                }
                mntput(mnt);

                dput(fdentry);
                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
                RETURN(rc);
        }

        OBDO_ALLOC(oa);
        if (oa == NULL)
                RETURN(-ENOMEM);

        oa->o_id = handle->lgh_id.lgl_oid;
        oa->o_seq = handle->lgh_id.lgl_oseq;
        oa->o_generation = handle->lgh_id.lgl_ogen;
#undef o_generation
        oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLGENER;

        rc = llog_lvfs_close(handle);
        if (rc)
                GOTO(out, rc);

        th = fsfilt_start_log(obd, inode, FSFILT_OP_UNLINK, NULL, 1);
        if (IS_ERR(th)) {
                CERROR("fsfilt_start failed: %ld\n", PTR_ERR(th));
                GOTO(out, rc = PTR_ERR(th));
        }

        rc = obd_destroy(handle->lgh_ctxt->loc_exp, oa, NULL, NULL, NULL, NULL);

        rc1 = fsfilt_commit(obd, inode, th, 0);
        if (rc == 0 && rc1 != 0)
                rc = rc1;
 out:
        OBDO_FREE(oa);
        RETURN(rc);
}
コード例 #7
0
ファイル: llog_lvfs.c プロジェクト: DCteam/lustre
/* This is a callback from the llog_* functions.
 * Assumes caller has already pushed us into the kernel context. */
static int llog_lvfs_create(struct llog_ctxt *ctxt, struct llog_handle **res,
                            struct llog_logid *logid, char *name)
{
        struct llog_handle *handle;
        struct obd_device *obd;
        struct l_dentry *dchild = NULL;
        struct obdo *oa = NULL;
        int rc = 0;
        int open_flags = O_RDWR | O_CREAT | O_LARGEFILE;
        ENTRY;

        handle = llog_alloc_handle();
        if (handle == NULL)
                RETURN(-ENOMEM);
        *res = handle;

        LASSERT(ctxt);
        LASSERT(ctxt->loc_exp);
        obd = ctxt->loc_exp->exp_obd;

        if (logid != NULL) {
                dchild = obd_lvfs_fid2dentry(ctxt->loc_exp, logid->lgl_oid,
                                             logid->lgl_ogen, logid->lgl_oseq);

                if (IS_ERR(dchild)) {
                        rc = PTR_ERR(dchild);
                        CERROR("error looking up logfile "LPX64":0x%x: rc %d\n",
                               logid->lgl_oid, logid->lgl_ogen, rc);
                        GOTO(out, rc);
                }

                if (dchild->d_inode == NULL) {
                        l_dput(dchild);
                        rc = -ENOENT;
                        CERROR("nonexistent log file "LPX64":"LPX64": rc %d\n",
                               logid->lgl_oid, logid->lgl_oseq, rc);
                        GOTO(out, rc);
                }

                /* l_dentry_open will call dput(dchild) if there is an error */
                handle->lgh_file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild,
                                                    O_RDWR | O_LARGEFILE);
                if (IS_ERR(handle->lgh_file)) {
                        rc = PTR_ERR(handle->lgh_file);
                        CERROR("error opening logfile "LPX64"0x%x: rc %d\n",
                               logid->lgl_oid, logid->lgl_ogen, rc);
                        GOTO(out, rc);
                }

                /* assign the value of lgh_id for handle directly */
                handle->lgh_id = *logid;

        } else if (name) {
                handle->lgh_file = llog_filp_open(MOUNT_CONFIGS_DIR,
                                                  name, open_flags, 0644);
                if (IS_ERR(handle->lgh_file))
                        GOTO(out, rc = PTR_ERR(handle->lgh_file));

                handle->lgh_id.lgl_oseq = 1;
                handle->lgh_id.lgl_oid =
                        handle->lgh_file->f_dentry->d_inode->i_ino;
                handle->lgh_id.lgl_ogen =
                        handle->lgh_file->f_dentry->d_inode->i_generation;
        } else {
                OBDO_ALLOC(oa);
                if (oa == NULL)
                        GOTO(out, rc = -ENOMEM);

                oa->o_seq = FID_SEQ_LLOG;
                oa->o_valid = OBD_MD_FLGENER | OBD_MD_FLGROUP;

                rc = obd_create(ctxt->loc_exp, oa, NULL, NULL);
                if (rc)
                        GOTO(out, rc);

                /* FIXME: rationalize the misuse of o_generation in
                 *        this API along with mds_obd_{create,destroy}.
                 *        Hopefully it is only an internal API issue. */
#define o_generation o_parent_oid
                dchild = obd_lvfs_fid2dentry(ctxt->loc_exp, oa->o_id,
                                             oa->o_generation, oa->o_seq);

                if (IS_ERR(dchild))
                        GOTO(out, rc = PTR_ERR(dchild));

                handle->lgh_file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild,
                                                 open_flags);
                if (IS_ERR(handle->lgh_file))
                        GOTO(out, rc = PTR_ERR(handle->lgh_file));

                handle->lgh_id.lgl_oseq = oa->o_seq;
                handle->lgh_id.lgl_oid = oa->o_id;
                handle->lgh_id.lgl_ogen = oa->o_generation;
        }

        handle->lgh_ctxt = ctxt;
out:
        if (rc)
                llog_free_handle(handle);

        if (oa)
                OBDO_FREE(oa);
        RETURN(rc);
}
コード例 #8
0
ファイル: llog_lvfs.c プロジェクト: AkyZero/wrapfs-latest
static int llog_lvfs_destroy(const struct lu_env *env,
			     struct llog_handle *handle)
{
	struct dentry *fdentry;
	struct obdo *oa;
	struct obd_device *obd = handle->lgh_ctxt->loc_exp->exp_obd;
	char *dir;
	void *th;
	struct inode *inode;
	int rc, rc1;

	dir = MOUNT_CONFIGS_DIR;

	LASSERT(handle->lgh_file);
	fdentry = handle->lgh_file->f_dentry;
	inode = fdentry->d_parent->d_inode;
	if (strcmp(fdentry->d_parent->d_name.name, dir) == 0) {
		struct lvfs_run_ctxt saved;
		struct vfsmount *mnt = mntget(handle->lgh_file->f_vfsmnt);

		push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
		dget(fdentry);
		rc = llog_lvfs_close(env, handle);
		if (rc == 0) {
			mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
			rc = ll_vfs_unlink(inode, fdentry, mnt);
			mutex_unlock(&inode->i_mutex);
		}
		mntput(mnt);

		dput(fdentry);
		pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
		return rc;
	}

	OBDO_ALLOC(oa);
	if (oa == NULL)
		return -ENOMEM;

	oa->o_oi = handle->lgh_id.lgl_oi;
	oa->o_generation = handle->lgh_id.lgl_ogen;
#undef o_generation
	oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLGENER;

	rc = llog_lvfs_close(env, handle);
	if (rc)
		GOTO(out, rc);

	th = fsfilt_start_log(obd, inode, FSFILT_OP_UNLINK, NULL, 1);
	if (IS_ERR(th)) {
		CERROR("fsfilt_start failed: %ld\n", PTR_ERR(th));
		GOTO(out, rc = PTR_ERR(th));
	}

	rc = obd_destroy(NULL, handle->lgh_ctxt->loc_exp, oa,
			 NULL, NULL, NULL, NULL);

	rc1 = fsfilt_commit(obd, inode, th, 0);
	if (rc == 0 && rc1 != 0)
		rc = rc1;
 out:
	OBDO_FREE(oa);
	return rc;
}