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

📄 namei.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 2 页
字号:
                ptlrpc_req_finished(req);        if (rc == 0) {                LASSERT(pb->pb_ino);                I_RELE(pb->pb_ino);                pb->pb_ino = NULL;        } else {                llu_lookup_finish_locks(it, pnode);        }        RETURN(rc);}static int lookup_it_finish(struct ptlrpc_request *request, int offset,                            struct lookup_intent *it, void *data){        struct it_cb_data *icbd = data;        struct pnode *child = icbd->icbd_child;        struct inode *parent = icbd->icbd_parent;        struct llu_sb_info *sbi = llu_i2sbi(parent);        struct inode *inode = NULL;        int rc;        /* libsysio require us generate inode right away if success.         * so if mds created new inode for us we need make sure it         * succeeded. thus for any error we can't delay to the         * llu_file_open() time. */        if (it_disposition(it, DISP_OPEN_CREATE) &&            it_open_error(DISP_OPEN_CREATE, it)) {                CDEBUG(D_INODE, "detect mds create error\n");                return it_open_error(DISP_OPEN_CREATE, it);        }        if (it_disposition(it, DISP_OPEN_OPEN) &&            it_open_error(DISP_OPEN_OPEN, it)) {                CDEBUG(D_INODE, "detect mds open error\n");                /* undo which did by mdc_intent_lock */                if (it_disposition(it, DISP_OPEN_CREATE) &&                    !it_open_error(DISP_OPEN_CREATE, it)) {                        LASSERT(request);                        LASSERT(atomic_read(&request->rq_refcount) > 1);                        CDEBUG(D_INODE, "dec a ref of req %p\n", request);                        ptlrpc_req_finished(request);                }                return it_open_error(DISP_OPEN_OPEN, it);        }        /* NB 1 request reference will be taken away by ll_intent_lock()         * when I return         */        if (!it_disposition(it, DISP_LOOKUP_NEG) || (it->it_op & IT_CREAT)) {                struct lustre_md md;                struct llu_inode_info *lli;                struct intnl_stat *st;                ENTRY;                if (it_disposition(it, DISP_OPEN_CREATE))                        ptlrpc_req_finished(request);                rc = mdc_req2lustre_md(request, offset, sbi->ll_osc_exp, &md);                if (rc)                        RETURN(rc);                inode = llu_iget(parent->i_fs, &md);                if (!inode || IS_ERR(inode)) {                        /* free the lsm if we allocated one above */                        if (md.lsm != NULL)                                obd_free_memmd(sbi->ll_osc_exp, &md.lsm);                        RETURN(inode ? PTR_ERR(inode) : -ENOMEM);                } else if (md.lsm != NULL &&                           llu_i2info(inode)->lli_smd != md.lsm) {                        obd_free_memmd(sbi->ll_osc_exp, &md.lsm);                }                lli = llu_i2info(inode);                st = llu_i2stat(inode);                /* If this is a stat, get the authoritative file size */                if (it->it_op == IT_GETATTR && S_ISREG(st->st_mode) &&                    lli->lli_smd != NULL) {                        struct lov_stripe_md *lsm = lli->lli_smd;                        ldlm_error_t rc;                        LASSERT(lsm->lsm_object_id != 0);                        /* bug 2334: drop MDS lock before acquiring OST lock */                        ll_intent_drop_lock(it);                        rc = llu_glimpse_size(inode);                        if (rc) {                                I_RELE(inode);                                RETURN(rc);                        }                }        } else {                ENTRY;        }        /* intent will be further used in cases of open()/getattr() */        if (inode && (it->it_op & IT_OPEN))                LL_SAVE_INTENT(inode, it);        child->p_base->pb_ino = inode;        RETURN(0);}struct inode *llu_inode_from_lock(struct ldlm_lock *lock){        struct inode *inode;        lock_res_and_lock(lock);        if (lock->l_ast_data) {                inode = (struct inode *)lock->l_ast_data;                I_REF(inode);        } else                inode = NULL;        unlock_res_and_lock(lock);        return inode;}static int llu_lookup_it(struct inode *parent, struct pnode *pnode,                         struct lookup_intent *it, int flags){        struct mdc_op_data op_data;        struct it_cb_data icbd;        struct ptlrpc_request *req = NULL;        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };        int rc;        ENTRY;        if (pnode->p_base->pb_name.len > EXT2_NAME_LEN)                RETURN(-ENAMETOOLONG);        if (!it) {                it = &lookup_it;                it->it_op_release = ll_intent_release;        }        icbd.icbd_child = pnode;        icbd.icbd_parent = parent;        llu_prepare_mdc_op_data(&op_data, parent, NULL,                                pnode->p_base->pb_name.name,                                pnode->p_base->pb_name.len, flags);        rc = mdc_intent_lock(llu_i2mdcexp(parent), &op_data, NULL, 0, it,                             flags, &req, llu_mdc_blocking_ast,                             LDLM_FL_CANCEL_ON_BLOCK);        if (rc < 0)                GOTO(out, rc);        rc = lookup_it_finish(req, DLM_REPLY_REC_OFF, it, &icbd);        if (rc != 0) {                ll_intent_release(it);                GOTO(out, rc);        }        llu_lookup_finish_locks(it, pnode); out:        if (req)                ptlrpc_req_finished(req);        return rc;}static struct lookup_intent*translate_lookup_intent(struct intent *intent, const char *path){        struct lookup_intent *it;        int fmode;        /* libsysio trick */        if (!intent || path) {                CDEBUG(D_VFSTRACE, "not intent needed\n");                return NULL;        }        OBD_ALLOC(it, sizeof(*it));        LASSERT(it);        memset(it, 0, sizeof(*it));        /* libsysio will assign intent like following:         * NOTE: INT_CREAT has include INT_UPDPARENT         *         * open: INT_OPEN [| INT_CREAT]         * mkdir: INT_CREAT         * symlink: INT_CREAT         * unlink: INT_UPDPARENT         * rmdir: INT_UPDPARENT         * mknod: INT_CREAT         * stat: INT_GETATTR         * setattr: NULL         *         * following logic is adjusted for libsysio         */        it->it_flags = intent->int_arg2 ? *((int*)intent->int_arg2) : 0;        if (intent->int_opmask & INT_OPEN) {                it->it_op |= IT_OPEN;                /* convert access mode from O_ to FMODE_ */                if (it->it_flags & O_WRONLY)                        fmode = FMODE_WRITE;                else if (it->it_flags & O_RDWR)                        fmode = FMODE_READ | FMODE_WRITE;                else                        fmode = FMODE_READ;                it->it_flags &= ~O_ACCMODE;                it->it_flags |= fmode;        }        /* XXX libsysio has strange code on intent handling,         * more check later */        if (it->it_flags & O_CREAT) {                it->it_op |= IT_CREAT;                it->it_create_mode = *((int*)intent->int_arg1);                /* bug 7278: libsysio hack. For O_EXCL, libsysio depends on                   this lookup to return negative result, but then there is no                   way to find out original intent in ll_iop_open(). So we just                   clear O_EXCL from libsysio flags here to avoid checking                   for negative result. O_EXCL will be enforced by MDS. */                *((int*)intent->int_arg2) &= ~O_EXCL;        }        if (intent->int_opmask & INT_GETATTR)                it->it_op |= IT_GETATTR;        LASSERT(!(intent->int_opmask & INT_SETATTR));        /* libsysio is different to linux vfs when doing unlink/rmdir,         * INT_UPDPARENT was passed down during name resolution. Here         * we treat it as normal lookup, later unlink()/rmdir() will         * do the actual work */        /* conform to kernel code, if only IT_LOOKUP was set, don't         * pass down it */        if (!it->it_op || it->it_op == IT_LOOKUP) {                OBD_FREE(it, sizeof(*it));                it = NULL;        }        if (it)                it->it_op_release = ll_intent_release;        CDEBUG(D_VFSTRACE, "final intent 0x%x\n", it ? it->it_op : 0);        return it;}int llu_iop_lookup(struct pnode *pnode,                   struct inode **inop,                   struct intent *intnt,                   const char *path){        struct lookup_intent *it;        int rc;        ENTRY;        liblustre_wait_event(0);        *inop = NULL;        /* the mount root inode have no name, so don't call         * remote in this case. but probably we need revalidate         * it here? FIXME */        if (pnode->p_mount->mnt_root == pnode) {                struct inode *i = pnode->p_base->pb_ino;                *inop = i;                RETURN(0);        }        if (!pnode->p_base->pb_name.len)                RETURN(-EINVAL);        it = translate_lookup_intent(intnt, path);        /* param flags is not used, let it be 0 */        if (llu_pb_revalidate(pnode, 0, it)) {                LASSERT(pnode->p_base->pb_ino);                *inop = pnode->p_base->pb_ino;                GOTO(out, rc = 0);        }        rc = llu_lookup_it(pnode->p_parent->p_base->pb_ino, pnode, it, 0);        if (!rc) {                if (!pnode->p_base->pb_ino)                        rc = -ENOENT;                else                        *inop = pnode->p_base->pb_ino;        }out:        liblustre_wait_event(0);        RETURN(rc);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -