int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_handle **lgh, struct llog_logid *logid, char *name, enum llog_open_param open_param) { int raised; int rc; LASSERT(ctxt); LASSERT(ctxt->loc_logops); if (ctxt->loc_logops->lop_open == NULL) { *lgh = NULL; return -EOPNOTSUPP; } *lgh = llog_alloc_handle(); if (*lgh == NULL) return -ENOMEM; (*lgh)->lgh_ctxt = ctxt; (*lgh)->lgh_logops = ctxt->loc_logops; raised = cfs_cap_raised(CFS_CAP_SYS_RESOURCE); if (!raised) cfs_cap_raise(CFS_CAP_SYS_RESOURCE); rc = ctxt->loc_logops->lop_open(env, *lgh, logid, name, open_param); if (!raised) cfs_cap_lower(CFS_CAP_SYS_RESOURCE); if (rc) { llog_free_handle(*lgh); *lgh = NULL; } return rc; }
/* 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); }