/* 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; }
/* 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); }
/** * 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); }
/* 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); }
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; }
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); }
/* 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); }
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; }