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

📄 statahead.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 3 页
字号:
                               minfo->mi_generation,                               (unsigned int)(long)minfo->mi_cbdata);                ll_sai_put(sai);        }out_free:        ll_intent_release(it);        OBD_FREE_PTR(minfo);        dput(dentry);        return rc;}static void sa_args_fini(struct md_enqueue_info *minfo,                         struct ldlm_enqueue_info *einfo){        LASSERT(minfo && einfo);        OBD_FREE_PTR(minfo);        OBD_FREE_PTR(einfo);}static int sa_args_prep(struct inode *dir, struct dentry *dentry,                        struct md_enqueue_info **pmi,                        struct ldlm_enqueue_info **pei){        struct ll_inode_info     *lli = ll_i2info(dir);        struct md_enqueue_info   *minfo;        struct ldlm_enqueue_info *einfo;        OBD_ALLOC_PTR(einfo);        if (einfo == NULL)                return -ENOMEM;        OBD_ALLOC_PTR(minfo);        if (minfo == NULL) {                OBD_FREE_PTR(einfo);                return -ENOMEM;        }        minfo->mi_exp = ll_i2mdcexp(dir);        minfo->mi_it.it_op = IT_GETATTR;        minfo->mi_dentry = dentry;        minfo->mi_cb = ll_statahead_interpret;        minfo->mi_generation = lli->lli_sai->sai_generation;        minfo->mi_cbdata = (void *)(long)lli->lli_sai->sai_index;        einfo->ei_type   = LDLM_IBITS;        einfo->ei_mode   = it_to_lock_mode(&minfo->mi_it);        einfo->ei_cb_bl  = ll_mdc_blocking_ast;        einfo->ei_cb_cp  = ldlm_completion_ast;        einfo->ei_cb_gl  = NULL;        einfo->ei_cbdata = NULL;        *pmi = minfo;        *pei = einfo;        return 0;}/* similar to ll_lookup_it(). */static int do_sa_lookup(struct inode *dir, struct dentry *dentry){        struct md_enqueue_info   *minfo;        struct ldlm_enqueue_info *einfo;        int                       rc;                        ENTRY;        rc = sa_args_prep(dir, dentry, &minfo, &einfo);        if (rc)                RETURN(rc);        rc = ll_prepare_mdc_op_data(&minfo->mi_data, dir, NULL,                                    dentry->d_name.name, dentry->d_name.len, 0,                                    NULL);        if (rc == 0)                rc = mdc_intent_getattr_async(minfo->mi_exp, minfo, einfo);        if (rc)                sa_args_fini(minfo, einfo);        RETURN(rc);}/*  * similar to ll_revalidate_it(). * return value: *  1      -- dentry valid *  0      -- will send stat-ahead request *  others -- prepare stat-ahead request failed */static int do_sa_revalidate(struct dentry *dentry){        struct inode             *inode = dentry->d_inode;        struct ll_fid             fid;        struct lookup_intent      it = { .it_op = IT_GETATTR };        struct md_enqueue_info   *minfo;        struct ldlm_enqueue_info *einfo;        int rc;        ENTRY;        if (inode == NULL)                RETURN(1);        if (d_mountpoint(dentry))                RETURN(1);        if (dentry == dentry->d_sb->s_root)                RETURN(1);        ll_inode2fid(&fid, inode);        rc = mdc_revalidate_lock(ll_i2mdcexp(inode), &it, &fid);        if (rc == 1) {                ll_intent_release(&it);                RETURN(1);        }        rc = sa_args_prep(dentry->d_parent->d_inode, dentry, &minfo, &einfo);        if (rc)                RETURN(rc);        rc = ll_prepare_mdc_op_data(&minfo->mi_data, dentry->d_parent->d_inode,                                    inode, dentry->d_name.name,                                    dentry->d_name.len, 0, NULL);        if (rc == 0)                rc = mdc_intent_getattr_async(minfo->mi_exp, minfo, einfo);        if (rc)                sa_args_fini(minfo, einfo);        RETURN(rc);}static inline void ll_name2qstr(struct qstr *this, const char *name, int namelen){        unsigned long hash = init_name_hash();        unsigned int  c;        this->name = name;        this->len  = namelen;        for (; namelen > 0; namelen--, name++) {                c = *(const unsigned char *)name;                hash = partial_name_hash(c, hash);        }        this->hash = end_name_hash(hash);}static int ll_statahead_one(struct dentry *parent, ext2_dirent *de){        struct inode           *dir = parent->d_inode;        struct ll_inode_info   *lli = ll_i2info(dir);        struct qstr             name;        struct dentry          *dentry;        struct ll_sai_entry    *se;        int                     rc;        ENTRY;#ifdef DCACHE_LUSTRE_INVALID        if (parent->d_flags & DCACHE_LUSTRE_INVALID) {#else        if (d_unhashed(parent)) {#endif                CDEBUG(D_READA, "parent dentry@%p %.*s is "                       "invalid, skip statahead\n",                       parent, parent->d_name.len, parent->d_name.name);                RETURN(-EINVAL);        }        se = ll_sai_entry_get(lli->lli_sai, lli->lli_sai->sai_index,                              SA_ENTRY_UNSTATED);        if (IS_ERR(se))                RETURN(PTR_ERR(se));        ll_name2qstr(&name, de->name, de->name_len);        dentry = d_lookup(parent, &name);        if (!dentry) {                dentry = d_alloc(parent, &name);                if (dentry) {                        rc = do_sa_lookup(dir, dentry);                        if (rc)                                dput(dentry);                } else {                        GOTO(out, rc = -ENOMEM);                }        } else {                rc = do_sa_revalidate(dentry);                if (rc)                        dput(dentry);        }        EXIT;out:        if (rc) {                CDEBUG(D_READA, "set sai entry %p index %u stat %d rc %d\n",                       se, se->se_index, se->se_stat, rc);                se->se_stat = rc;                cfs_waitq_signal(&lli->lli_sai->sai_waitq);        } else {                lli->lli_sai->sai_sent++;        }        lli->lli_sai->sai_index++;        return rc;}                static inline int sa_check_stop(struct ll_statahead_info *sai){        return !!(sai->sai_thread.t_flags & SVC_STOPPING);}static inline int sa_not_full(struct ll_statahead_info *sai){        return sai->sai_index < sai->sai_hit + sai->sai_miss + sai->sai_max;}/* (1) hit ratio less than 80% * or * (2) consecutive miss more than 8 */static inline int sa_low_hit(struct ll_statahead_info *sai){        return ((sai->sai_hit < 4 * sai->sai_miss && sai->sai_hit > 7) ||                (sai->sai_consecutive_miss > 8));}struct ll_sa_thread_args {        struct dentry   *sta_parent;        pid_t            sta_pid;};static int ll_statahead_thread(void *arg){        struct ll_sa_thread_args *sta = arg;        struct dentry            *parent = dget(sta->sta_parent);        struct inode             *dir = parent->d_inode;        struct ll_inode_info     *lli = ll_i2info(dir);        struct ll_sb_info        *sbi = ll_i2sbi(dir);        struct ll_statahead_info *sai = ll_sai_get(lli->lli_sai);        struct ptlrpc_thread     *thread = &sai->sai_thread;        unsigned long             index = 0;        int                       first = 0;        int                       rc = 0;        char                      name[16] = "";        ENTRY;        sbi->ll_sa_total++;        snprintf(name, 15, "ll_sa_%u", sta->sta_pid);        cfs_daemonize(name);        spin_lock(&lli->lli_lock);        thread->t_flags = SVC_RUNNING;        spin_unlock(&lli->lli_lock);        cfs_waitq_signal(&thread->t_ctl_waitq);        CDEBUG(D_READA, "start doing statahead for %s\n", parent->d_name.name);        while (1) {                struct l_wait_info lwi = { 0 };                unsigned long npages;                char *kaddr, *limit;                ext2_dirent *de;                struct page *page;                npages = dir_pages(dir);                /* reach the end of dir */                if (index >= npages) {                        CDEBUG(D_READA, "reach end, index/npages %lu/%lu\n",                               index, npages);                        break;                }                page = ll_get_dir_page(dir, index);                if (IS_ERR(page)) {                        rc = PTR_ERR(page);                        CERROR("error reading dir %lu/%u page %lu/%u: rc %d\n",                               dir->i_ino, dir->i_generation, index,                               sai->sai_index, rc);                        break;                }                kaddr = page_address(page);                limit = kaddr + CFS_PAGE_SIZE - EXT2_DIR_REC_LEN(1);                de = (ext2_dirent *)kaddr;                if (!index) {                        de = ext2_next_entry(de); /* skip "." */                        de = ext2_next_entry(de); /* skip ".." */                }                for (; (char*)de <= limit; de = ext2_next_entry(de)) {                        if (!de->inode)                                continue;                        if (de->name[0] == '.' && !sai->sai_ls_all) {                                /* skip hidden files */                                sai->sai_skip_hidden++;                                continue;                        }                        /* don't stat-ahead first entry */                        if (unlikely(!first)) {                                first++;                                continue;                        }                        l_wait_event(thread->t_ctl_waitq,                                     sa_check_stop(sai) || sa_not_full(sai),                                     &lwi);                        if (unlikely(sa_check_stop(sai))) {                                ext2_put_page(page);                                GOTO(out, rc);                        }

⌨️ 快捷键说明

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