📄 mds_open.c
字号:
{ struct inode *inode = dchild->d_inode; struct obd_trans_info oti = { 0 }; struct lov_mds_md *lmm = NULL; int rc, lmm_size; struct mds_body *body; struct obd_info oinfo = { { { 0 } } }; void *lmm_buf; ENTRY; *objid = NULL; if (!S_ISREG(inode->i_mode)) RETURN(0); if (rec->ur_flags & MDS_OPEN_DELAY_CREATE || !(rec->ur_flags & FMODE_WRITE)) RETURN(0); body = lustre_msg_buf(req->rq_repmsg, DLM_REPLY_REC_OFF, sizeof(*body)); if (body->valid & OBD_MD_FLEASIZE) RETURN(0); oti_init(&oti, req); /* replay case */ if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) { if (rec->ur_fid2->id == 0) { DEBUG_REQ(D_ERROR, req, "fid2 not set on open replay"); RETURN(-EFAULT); } body->valid |= OBD_MD_FLBLKSZ | OBD_MD_FLEASIZE; lmm_size = rec->ur_eadatalen; lmm = rec->ur_eadata; LASSERT(lmm); if (*handle == NULL) *handle = fsfilt_start(obd,inode,FSFILT_OP_CREATE,NULL); if (IS_ERR(*handle)) { rc = PTR_ERR(*handle); *handle = NULL; GOTO(out_ids, rc); } rc = fsfilt_set_md(obd, inode, *handle, lmm, lmm_size, "lov"); if (rc) CERROR("open replay failed to set md:%d\n", rc); lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, lmm_size); LASSERT(lmm_buf); memcpy(lmm_buf, lmm, lmm_size); *objid = lmm_buf; RETURN(rc); } if (OBD_FAIL_CHECK_ONCE(OBD_FAIL_MDS_ALLOC_OBDO)) GOTO(out_ids, rc = -ENOMEM); OBDO_ALLOC(oinfo.oi_oa); if (oinfo.oi_oa == NULL) GOTO(out_ids, rc = -ENOMEM); oinfo.oi_oa->o_uid = 0; /* must have 0 uid / gid on OST */ oinfo.oi_oa->o_gid = 0; oinfo.oi_oa->o_mode = S_IFREG | 0600; oinfo.oi_oa->o_id = inode->i_ino; oinfo.oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLFLAGS | OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID; oinfo.oi_oa->o_size = 0; obdo_from_inode(oinfo.oi_oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME); if (!(rec->ur_flags & MDS_OPEN_HAS_OBJS)) { /* check if things like lfs setstripe are sending us the ea */ if (rec->ur_flags & MDS_OPEN_HAS_EA) { rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE, mds->mds_osc_exp, 0, &oinfo.oi_md, rec->ur_eadata); if (rc) GOTO(out_oa, rc); } else { OBD_ALLOC(lmm, mds->mds_max_mdsize); if (lmm == NULL) GOTO(out_oa, rc = -ENOMEM); lmm_size = mds->mds_max_mdsize; rc = mds_get_md(obd, dchild->d_parent->d_inode, lmm, &lmm_size, 1, 0); if (rc > 0) rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE, mds->mds_osc_exp, 0, &oinfo.oi_md, lmm); OBD_FREE(lmm, mds->mds_max_mdsize); if (rc) GOTO(out_oa, rc); } rc = obd_create(mds->mds_osc_exp, oinfo.oi_oa, &oinfo.oi_md, &oti); if (rc) { int level = D_ERROR; if (rc == -ENOSPC) level = D_INODE; CDEBUG(level, "error creating objects for " "inode %lu: rc = %d\n", inode->i_ino, rc); if (rc > 0) { CERROR("obd_create returned invalid " "rc %d\n", rc); rc = -EIO; } GOTO(out_oa, rc); } } else { rc = obd_iocontrol(OBD_IOC_LOV_SETEA, mds->mds_osc_exp, 0, &oinfo.oi_md, rec->ur_eadata); if (rc) { GOTO(out_oa, rc); } oinfo.oi_md->lsm_object_id = oinfo.oi_oa->o_id; } if (i_size_read(inode)) { oinfo.oi_oa->o_size = i_size_read(inode); obdo_from_inode(oinfo.oi_oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLSIZE); /* pack lustre id to OST */ oinfo.oi_oa->o_fid = body->fid1.id; oinfo.oi_oa->o_generation = body->fid1.generation; oinfo.oi_oa->o_valid |= OBD_MD_FLFID | OBD_MD_FLGENER; rc = obd_setattr_rqset(mds->mds_osc_exp, &oinfo, &oti); if (rc) { CERROR("error setting attrs for inode %lu: rc %d\n", inode->i_ino, rc); if (rc > 0) { CERROR("obd_setattr_async returned bad rc %d\n", rc); rc = -EIO; } GOTO(out_oa, rc); } } body->valid |= OBD_MD_FLBLKSZ | OBD_MD_FLEASIZE; obdo_refresh_inode(inode, oinfo.oi_oa, OBD_MD_FLBLKSZ); LASSERT(oinfo.oi_md && oinfo.oi_md->lsm_object_id); lmm = NULL; rc = obd_packmd(mds->mds_osc_exp, &lmm, oinfo.oi_md); if (rc < 0) { CERROR("cannot pack lsm, err = %d\n", rc); GOTO(out_oa, rc); } lmm_size = rc; body->eadatasize = rc; if (*handle == NULL) *handle = fsfilt_start(obd, inode, FSFILT_OP_CREATE, NULL); if (IS_ERR(*handle)) { rc = PTR_ERR(*handle); *handle = NULL; GOTO(free_diskmd, rc); } rc = fsfilt_set_md(obd, inode, *handle, lmm, lmm_size, "lov"); lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, lmm_size); LASSERT(lmm_buf); memcpy(lmm_buf, lmm, lmm_size); *objid = lmm_buf; /* save for mds_lov_update_objid */ free_diskmd: obd_free_diskmd(mds->mds_osc_exp, &lmm); out_oa: oti_free_cookies(&oti); OBDO_FREE(oinfo.oi_oa); out_ids: if (oinfo.oi_md) obd_free_memmd(mds->mds_osc_exp, &oinfo.oi_md); RETURN(rc);}static void reconstruct_open(struct mds_update_record *rec, int offset, struct ptlrpc_request *req, struct lustre_handle *child_lockh){ struct mds_export_data *med = &req->rq_export->exp_mds_data; struct mds_client_data *mcd = med->med_mcd; struct mds_obd *mds = mds_req2mds(req); struct mds_file_data *mfd; struct obd_device *obd = req->rq_export->exp_obd; struct dentry *parent, *dchild; struct ldlm_reply *rep; struct mds_body *body; int rc; struct list_head *t; int put_child = 1; ENTRY; LASSERT(offset == DLM_INTENT_REC_OFF); /* only called via intent */ rep = lustre_msg_buf(req->rq_repmsg, DLM_LOCKREPLY_OFF, sizeof(*rep)); body = lustre_msg_buf(req->rq_repmsg, DLM_REPLY_REC_OFF, sizeof(*body)); /* copy rc, transno and disp; steal locks */ mds_req_from_mcd(req, mcd); intent_set_disposition(rep, le32_to_cpu(mcd->mcd_last_data)); /* Only replay if create or open actually happened. */ if (!intent_disposition(rep, DISP_OPEN_CREATE | DISP_OPEN_OPEN) ) { EXIT; return; /* error looking up parent or child */ } parent = mds_fid2dentry(mds, rec->ur_fid1, NULL); LASSERT(!IS_ERR(parent)); dchild = ll_lookup_one_len(rec->ur_name, parent, rec->ur_namelen - 1); LASSERT(!IS_ERR(dchild)); if (!dchild->d_inode) GOTO(out_dput, 0); /* child not present to open */ /* At this point, we know we have a child. We'll send * it back _unless_ it not created and open failed. */ if (intent_disposition(rep, DISP_OPEN_OPEN) && !intent_disposition(rep, DISP_OPEN_CREATE) && req->rq_status) { GOTO(out_dput, 0); } mds_pack_inode2fid(&body->fid1, dchild->d_inode); mds_pack_inode2body(body, dchild->d_inode); if (S_ISREG(dchild->d_inode->i_mode)) { rc = mds_pack_md(obd, req->rq_repmsg, DLM_REPLY_REC_OFF + 1, body, dchild->d_inode, 1, 0); if (rc) LASSERT(rc == req->rq_status); /* If we have LOV EA data, the OST holds size, mtime */ if (!(body->valid & OBD_MD_FLEASIZE)) body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | OBD_MD_FLATIME | OBD_MD_FLMTIME); } if (!(rec->ur_flags & MDS_OPEN_JOIN_FILE)) lustre_shrink_reply(req, DLM_REPLY_REC_OFF + 1, body->eadatasize, 0); if (req->rq_export->exp_connect_flags & OBD_CONNECT_ACL && !(rec->ur_flags & MDS_OPEN_JOIN_FILE)) { int acl_off = DLM_REPLY_REC_OFF + (body->eadatasize ? 2 : 1); rc = mds_pack_acl(med, dchild->d_inode, req->rq_repmsg, body, acl_off); lustre_shrink_reply(req, acl_off, body->aclsize, 0); if (!req->rq_status && rc) req->rq_status = rc; } /* If we have -EEXIST as the status, and we were asked to create * exclusively, we can tell we failed because the file already existed. */ if (req->rq_status == -EEXIST && ((rec->ur_flags & (MDS_OPEN_CREAT | MDS_OPEN_EXCL)) == (MDS_OPEN_CREAT | MDS_OPEN_EXCL))) { GOTO(out_dput, 0); } /* If we didn't get as far as trying to open, then some locking thing * probably went wrong, and we'll just bail here. */ if (!intent_disposition(rep, DISP_OPEN_OPEN)) GOTO(out_dput, 0); /* If we failed, then we must have failed opening, so don't look for * file descriptor or anything, just give the client the bad news. */ if (req->rq_status) GOTO(out_dput, 0); mfd = NULL; spin_lock(&med->med_open_lock); list_for_each(t, &med->med_open_head) { mfd = list_entry(t, struct mds_file_data, mfd_list); if (mfd->mfd_xid == req->rq_xid) { mds_mfd_addref(mfd); break; } mfd = NULL; } spin_unlock(&med->med_open_lock); /* #warning "XXX fixme" bug 2991 */ /* Here it used to LASSERT(mfd) if exp_outstanding_reply != NULL. * Now that exp_outstanding_reply is a list, it's just using mfd != NULL * to detect a re-open */ if (mfd == NULL) { if (rec->ur_flags & MDS_OPEN_JOIN_FILE) { rc = mds_join_file(rec, req, dchild, NULL); if (rc) GOTO(out_dput, rc); } mntget(mds->mds_vfsmnt); CERROR("Re-opened file \n"); mfd = mds_dentry_open(dchild, mds->mds_vfsmnt, rec->ur_flags & ~MDS_OPEN_TRUNC, req); mntput(mds->mds_vfsmnt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -