📄 mds_reint.c
字号:
} else if (ia_valid & ATTR_MODE) { int mode = attr->ia_mode; /* chmod */ if (attr->ia_mode == (umode_t)-1) mode = inode->i_mode; attr->ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); } RETURN(0);}void mds_steal_ack_locks(struct ptlrpc_request *req){ struct obd_export *exp = req->rq_export; struct list_head *tmp; struct ptlrpc_reply_state *oldrep; struct ptlrpc_service *svc; int i; /* CAVEAT EMPTOR: spinlock order */ spin_lock(&exp->exp_lock); list_for_each (tmp, &exp->exp_outstanding_replies) { oldrep = list_entry(tmp, struct ptlrpc_reply_state,rs_exp_list); if (oldrep->rs_xid != req->rq_xid) continue; if (lustre_msg_get_opc(oldrep->rs_msg) != lustre_msg_get_opc(req->rq_reqmsg)) CERROR ("Resent req xid "LPX64" has mismatched opc: " "new %d old %d\n", req->rq_xid, lustre_msg_get_opc(req->rq_reqmsg), lustre_msg_get_opc(oldrep->rs_msg)); svc = oldrep->rs_service; spin_lock (&svc->srv_lock); list_del_init (&oldrep->rs_exp_list); CWARN("Stealing %d locks from rs %p x"LPD64".t"LPD64 " o%d NID %s\n", oldrep->rs_nlocks, oldrep, oldrep->rs_xid, oldrep->rs_transno, lustre_msg_get_opc(oldrep->rs_msg), libcfs_nid2str(exp->exp_connection->c_peer.nid)); for (i = 0; i < oldrep->rs_nlocks; i++) ptlrpc_save_lock(req, &oldrep->rs_locks[i], oldrep->rs_modes[i]); oldrep->rs_nlocks = 0; DEBUG_REQ(D_DLMTRACE, req, "stole locks for"); ptlrpc_schedule_difficult_reply (oldrep); spin_unlock (&svc->srv_lock); break; } spin_unlock(&exp->exp_lock);}void mds_req_from_mcd(struct ptlrpc_request *req, struct mds_client_data *mcd){ if (lustre_msg_get_opc(req->rq_reqmsg) == MDS_CLOSE) { req->rq_transno = le64_to_cpu(mcd->mcd_last_close_transno); lustre_msg_set_transno(req->rq_repmsg, req->rq_transno); req->rq_status = le32_to_cpu(mcd->mcd_last_close_result); lustre_msg_set_status(req->rq_repmsg, req->rq_status); } else { req->rq_transno = le64_to_cpu(mcd->mcd_last_transno); lustre_msg_set_transno(req->rq_repmsg, req->rq_transno); req->rq_status = le32_to_cpu(mcd->mcd_last_result); lustre_msg_set_status(req->rq_repmsg, req->rq_status); } DEBUG_REQ(D_RPCTRACE, req, "restoring transno "LPD64"/status %d", req->rq_transno, req->rq_status); mds_steal_ack_locks(req);}static void reconstruct_reint_setattr(struct mds_update_record *rec, int offset, struct ptlrpc_request *req){ struct mds_export_data *med = &req->rq_export->exp_mds_data; struct mds_obd *obd = &req->rq_export->exp_obd->u.mds; struct dentry *de; struct mds_body *body; mds_req_from_mcd(req, med->med_mcd); de = mds_fid2dentry(obd, rec->ur_fid1, NULL); if (IS_ERR(de)) { LASSERT(PTR_ERR(de) == req->rq_status); return; } body = lustre_msg_buf(req->rq_repmsg, offset, sizeof(*body)); mds_pack_inode2fid(&body->fid1, de->d_inode); mds_pack_inode2body(body, de->d_inode); /* Don't return OST-specific attributes if we didn't just set them */ if (rec->ur_iattr.ia_valid & ATTR_SIZE) body->valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS; if (rec->ur_iattr.ia_valid & (ATTR_MTIME | ATTR_MTIME_SET)) body->valid |= OBD_MD_FLMTIME; if (rec->ur_iattr.ia_valid & (ATTR_ATIME | ATTR_ATIME_SET)) body->valid |= OBD_MD_FLATIME; l_dput(de);}int mds_osc_setattr_async(struct obd_device *obd, struct inode *inode, struct lov_mds_md *lmm, int lmm_size, struct llog_cookie *logcookies, struct ll_fid *fid){ struct mds_obd *mds = &obd->u.mds; struct obd_trans_info oti = { 0 }; struct obd_info oinfo = { { { 0 } } }; int rc; ENTRY; if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OST_SETATTR)) RETURN(0); /* first get memory EA */ OBDO_ALLOC(oinfo.oi_oa); if (!oinfo.oi_oa) RETURN(-ENOMEM); LASSERT(lmm); rc = obd_unpackmd(mds->mds_osc_exp, &oinfo.oi_md, lmm, lmm_size); if (rc < 0) { CERROR("Error unpack md %p for inode %lu\n", lmm, inode->i_ino); GOTO(out, rc); } rc = obd_checkmd(mds->mds_osc_exp, obd->obd_self_export, oinfo.oi_md); if (rc) { CERROR("Error revalidate lsm %p \n", oinfo.oi_md); GOTO(out, rc); } /* then fill oa */ obdo_from_inode(oinfo.oi_oa, inode, OBD_MD_FLUID | OBD_MD_FLGID); oinfo.oi_oa->o_valid |= OBD_MD_FLID; oinfo.oi_oa->o_id = oinfo.oi_md->lsm_object_id; if (logcookies) { oinfo.oi_oa->o_valid |= OBD_MD_FLCOOKIE; oti.oti_logcookies = logcookies; } LASSERT(fid != NULL); oinfo.oi_oa->o_fid = fid->id; oinfo.oi_oa->o_generation = fid->generation; oinfo.oi_oa->o_valid |= OBD_MD_FLFID | OBD_MD_FLGENER; /* do async setattr from mds to ost not waiting for responses. */ rc = obd_setattr_async(mds->mds_osc_exp, &oinfo, &oti, NULL); if (rc) CDEBUG(D_INODE, "mds to ost setattr objid 0x"LPX64 " on ost error %d\n", oinfo.oi_md->lsm_object_id, rc);out: if (oinfo.oi_md) obd_free_memmd(mds->mds_osc_exp, &oinfo.oi_md); OBDO_FREE(oinfo.oi_oa); RETURN(rc);}/* In the raw-setattr case, we lock the child inode. * In the write-back case or if being called from open, the client holds a lock * already. * * We use the ATTR_FROM_OPEN flag to tell these cases apart. */static int mds_reint_setattr(struct mds_update_record *rec, int offset, struct ptlrpc_request *req, struct lustre_handle *lh){ unsigned int ia_valid = rec->ur_iattr.ia_valid; struct mds_obd *mds = mds_req2mds(req); struct obd_device *obd = req->rq_export->exp_obd; struct mds_body *body; struct dentry *de; struct inode *inode = NULL; struct lustre_handle lockh; void *handle = NULL; struct mds_logcancel_data *mlcd = NULL; struct lov_mds_md *lmm = NULL; struct llog_cookie *logcookies = NULL; int lmm_size = 0, need_lock = 1, cookie_size = 0; int rc = 0, cleanup_phase = 0, err, locked = 0, sync = 0; unsigned int qcids[MAXQUOTAS] = { 0, 0 }; unsigned int qpids[MAXQUOTAS] = { rec->ur_iattr.ia_uid, rec->ur_iattr.ia_gid }; ENTRY; LASSERT(offset == REQ_REC_OFF); offset = REPLY_REC_OFF; DEBUG_REQ(D_INODE, req, "setattr "LPU64"/%u %x", rec->ur_fid1->id, rec->ur_fid1->generation, rec->ur_iattr.ia_valid); OBD_COUNTER_INCREMENT(obd, setattr); MDS_CHECK_RESENT(req, reconstruct_reint_setattr(rec, offset, req)); if (rec->ur_dlm) ldlm_request_cancel(req, rec->ur_dlm, 0); if (rec->ur_iattr.ia_valid & ATTR_FROM_OPEN || (req->rq_export->exp_connect_flags & OBD_CONNECT_RDONLY)) { de = mds_fid2dentry(mds, rec->ur_fid1, NULL); if (IS_ERR(de)) GOTO(cleanup, rc = PTR_ERR(de)); if (req->rq_export->exp_connect_flags & OBD_CONNECT_RDONLY) GOTO(cleanup, rc = -EROFS); } else { __u64 lockpart = MDS_INODELOCK_UPDATE; if (rec->ur_iattr.ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) lockpart |= MDS_INODELOCK_LOOKUP; de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_EX, &lockh, NULL, 0, lockpart); if (IS_ERR(de)) GOTO(cleanup, rc = PTR_ERR(de)); locked = 1; } cleanup_phase = 1; inode = de->d_inode; LASSERT(inode); if ((rec->ur_iattr.ia_valid & ATTR_FROM_OPEN) || (rec->ur_iattr.ia_valid & ATTR_SIZE)) { /* Check write access for the O_TRUNC case */ if (mds_query_write_access(inode) < 0) GOTO(cleanup, rc = -ETXTBSY); } /* save uid/gid for quota acq/rel */ qcids[USRQUOTA] = inode->i_uid; qcids[GRPQUOTA] = inode->i_gid; if ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) && rec->ur_eadata != NULL) { LOCK_INODE_MUTEX(inode); need_lock = 0; } OBD_FAIL_WRITE(obd, OBD_FAIL_MDS_REINT_SETATTR_WRITE, inode->i_sb); /* start a log jounal handle if needed */ if (S_ISREG(inode->i_mode) && rec->ur_iattr.ia_valid & (ATTR_UID | ATTR_GID)) { lmm_size = mds->mds_max_mdsize; OBD_ALLOC(lmm, lmm_size); if (lmm == NULL) GOTO(cleanup, rc = -ENOMEM); cleanup_phase = 2; rc = mds_get_md(obd, inode, lmm, &lmm_size, need_lock, 0); if (rc < 0) GOTO(cleanup, rc); rc = 0; handle = fsfilt_start_log(obd, inode, FSFILT_OP_SETATTR, NULL, le32_to_cpu(lmm->lmm_stripe_count)); } else { handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL); } if (IS_ERR(handle)) GOTO(cleanup, rc = PTR_ERR(handle)); if (rec->ur_iattr.ia_valid & (ATTR_MTIME | ATTR_CTIME)) CDEBUG(D_INODE, "setting mtime %lu, ctime %lu\n", LTIME_S(rec->ur_iattr.ia_mtime), LTIME_S(rec->ur_iattr.ia_ctime)); rc = mds_fix_attr(inode, rec); if (rc) GOTO(cleanup, rc); if (rec->ur_iattr.ia_valid & ATTR_ATTR_FLAG) { /* ioctl */ rc = fsfilt_iocontrol(obd, inode, NULL, EXT3_IOC_SETFLAGS, (long)&rec->ur_flags); } else if (rec->ur_iattr.ia_valid) { /* setattr */ rc = fsfilt_setattr(obd, de, handle, &rec->ur_iattr, 0); /* journal chown/chgrp in llog, just like unlink */ if (rc == 0 && lmm_size){ cookie_size = mds_get_cookie_size(obd, lmm); OBD_ALLOC(logcookies, cookie_size); if (logcookies == NULL) GOTO(cleanup, rc = -ENOMEM); if (mds_log_op_setattr(obd, inode, lmm, lmm_size, logcookies, cookie_size) <= 0) { OBD_FREE(logcookies, cookie_size); logcookies = NULL; } } } if (rc == 0 && (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) && rec->ur_eadata != NULL) { struct lov_stripe_md *lsm = NULL; struct lov_user_md *lum = NULL; rc = ll_permission(inode, MAY_WRITE, NULL); if (rc < 0) GOTO(cleanup, rc); lum = rec->ur_eadata; /* if { size, offset, count } = { 0, -1, 0 } (i.e. all default * values specified) then delete default striping from dir. */ if (S_ISDIR(inode->i_mode) && ((lum->lmm_stripe_size == 0 && lum->lmm_stripe_offset == (typeof(lum->lmm_stripe_offset))(-1) && lum->lmm_stripe_count == 0) || /* lmm_stripe_size == -1 is deprecated in 1.4.6 */ lum->lmm_stripe_size == (typeof(lum->lmm_stripe_size))(-1))){ rc = fsfilt_set_md(obd, inode, handle, NULL, 0, "lov");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -