⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mds_open.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
{        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 + -