Example #1
0
File: mds_log.c Project: hpc/lustre
static int llog_changelog_cancel_cb(struct llog_handle *llh,
                                    struct llog_rec_hdr *hdr, void *data)
{
        struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr;
        struct llog_cookie cookie;
        long long endrec = *(long long *)data;
        int rc, err;
        struct obd_device *obd;
        void *trans_h;
        struct inode *inode;
        ENTRY;

        /* This is always a (sub)log, not the catalog */
        LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);

        if (rec->cr.cr_index > endrec)
                /* records are in order, so we're done */
                RETURN(LLOG_PROC_BREAK);

        cookie.lgc_lgl = llh->lgh_id;
        cookie.lgc_index = hdr->lrh_index;
        obd = llh->lgh_ctxt->loc_exp->exp_obd;
        inode = llh->lgh_file->f_dentry->d_inode;

        /* XXX This is a workaround for the deadlock of changelog adding vs.
         * changelog cancelling. Changelog adding always start transaction
         * before acquiring the catlog lock (lgh_lock), whereas, changelog
         * cancelling do start transaction after holding catlog lock.
         *
         * We start the transaction earlier here to keep the locking ordering:
         * 'start transaction -> catlog lock'. LU-81. */
        trans_h = fsfilt_start_log(obd, inode, FSFILT_OP_CANCEL_UNLINK,
                                   NULL, 1);
        if (IS_ERR(trans_h)) {
                CERROR("fsfilt_start_log failed: %ld\n", PTR_ERR(trans_h));
                RETURN(PTR_ERR(trans_h));
        }

        /* cancel them one at a time.  I suppose we could store up the cookies
           and cancel them all at once; probably more efficient, but this is
           done as a user call, so who cares... */
        rc = llog_cat_cancel_records(llh->u.phd.phd_cat_handle, 1, &cookie);

        err = fsfilt_commit(obd, inode, trans_h, 0);
        if (err) {
                CERROR("fsfilt_commit failed: %d\n", err);
                rc = (rc >= 0) ? err : rc;
        }

        RETURN(rc < 0 ? rc : 0);
}
Example #2
0
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);
}
Example #3
0
int llog_origin_handle_cancel(struct ptlrpc_request *req)
{
        struct obd_device *obd = req->rq_export->exp_obd;
        int num_cookies, rc = 0, err, i, failed = 0;
        struct obd_device *disk_obd;
        struct llog_cookie *logcookies;
        struct llog_ctxt *ctxt = NULL;
        struct lvfs_run_ctxt saved;
        struct llog_handle *cathandle;
        struct inode *inode;
        void *handle;
        ENTRY;

        logcookies = req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES);
        num_cookies = req_capsule_get_size(&req->rq_pill, &RMF_LOGCOOKIES,
                                           RCL_CLIENT) / sizeof(*logcookies);
        if (logcookies == NULL || num_cookies == 0) {
                DEBUG_REQ(D_HA, req, "No llog cookies sent");
                RETURN(-EFAULT);
        }

        ctxt = llog_get_context(obd, logcookies->lgc_subsys);
        if (ctxt == NULL)
                RETURN(-ENODEV);

        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        for (i = 0; i < num_cookies; i++, logcookies++) {
                cathandle = ctxt->loc_handle;
                LASSERT(cathandle != NULL);
                inode = cathandle->lgh_file->f_dentry->d_inode;

                handle = fsfilt_start_log(disk_obd, inode,
                                          FSFILT_OP_CANCEL_UNLINK, NULL, 1);
                if (IS_ERR(handle)) {
                        CERROR("fsfilt_start_log() failed: %ld\n",
                               PTR_ERR(handle));
                        GOTO(pop_ctxt, rc = PTR_ERR(handle));
                }

                rc = llog_cat_cancel_records(cathandle, 1, logcookies);

                /*
                 * Do not raise -ENOENT errors for resent rpcs. This rec already
                 * might be killed.
                 */
                if (rc == -ENOENT &&
                    (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT)) {
                        /*
                         * Do not change this message, reply-single.sh test_59b
                         * expects to find this in log.
                         */
                        CDEBUG(D_RPCTRACE, "RESENT cancel req %p - ignored\n",
                               req);
                        rc = 0;
                } else if (rc == 0) {
                        CDEBUG(D_RPCTRACE, "Canceled %d llog-records\n",
                               num_cookies);
                }

                err = fsfilt_commit(disk_obd, inode, handle, 0);
                if (err) {
                        CERROR("Error committing transaction: %d\n", err);
                        if (!rc)
                                rc = err;
                        failed++;
                        GOTO(pop_ctxt, rc);
                } else if (rc)
                        failed++;
        }
        GOTO(pop_ctxt, rc);
pop_ctxt:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        if (rc)
                CERROR("Cancel %d of %d llog-records failed: %d\n",
                       failed, num_cookies, rc);

        llog_ctxt_put(ctxt);
        return rc;
}
Example #4
0
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;
}