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

📄 dir.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 3 页
字号:
        }        return nr;}int ll_readdir(struct file *filp, void *dirent, filldir_t filldir){        struct inode *inode = filp->f_dentry->d_inode;        loff_t pos          = filp->f_pos;        unsigned offset     = pos & ~CFS_PAGE_MASK;        pgoff_t idx         = pos >> CFS_PAGE_SHIFT;        pgoff_t npages      = dir_pages(inode);        unsigned chunk_mask = ll_dir_page_mask(inode);        int need_revalidate = (filp->f_version != inode->i_version);        int rc              = 0;        int done; /* when this becomes negative --- stop iterating */        ENTRY;        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %llu/%llu\n",               inode->i_ino, inode->i_generation, inode,               pos, i_size_read(inode));        /*         * Checking ->i_size without the lock. Should be harmless, as server         * re-checks.         */        if (pos > i_size_read(inode) - ll_dir_rec_len(1))                RETURN(0);        for (done = 0; idx < npages; idx++, offset = 0) {                /*                 * We can assume that all blocks on this page are filled with                 * entries, because ll_dir_check_page() placed special dummy                 * entries for us.                 */                char *kaddr;                struct page *page;                CDEBUG(D_EXT2,"read %lu of dir %lu/%u page %lu/%lu "                       "size %llu\n",                       CFS_PAGE_SIZE, inode->i_ino, inode->i_generation,                       idx, npages, i_size_read(inode));                page = ll_get_dir_page(inode, idx);                /* size might have been updated by mdc_readpage */                npages = dir_pages(inode);                if (IS_ERR(page)) {                        rc = PTR_ERR(page);                        CERROR("error reading dir %lu/%u page %lu: rc %d\n",                               inode->i_ino, inode->i_generation, idx, rc);                        continue;                }                kaddr = page_address(page);                if (need_revalidate) {                        /*                         * File offset was changed by lseek() and possibly                         * points in the middle of an entry. Re-scan from the                         * beginning of the chunk.                         */                        offset = ll_dir_validate_entry(kaddr, offset,                                                       chunk_mask);                        need_revalidate = 0;                }                done = ll_readdir_page(kaddr, idx << CFS_PAGE_SHIFT,                                       &offset, filldir, dirent);                kunmap(page);                page_cache_release(page);                if (done > 0)                        /*                         * Some entries were sent to the user space, return                         * success.                         */                        rc = 0;                else if (done < 0)                        /*                         * filldir is satisfied.                         */                        break;        }        filp->f_pos = (idx << CFS_PAGE_SHIFT) | offset;        filp->f_version = inode->i_version;        touch_atime(filp->f_vfsmnt, filp->f_dentry);        RETURN(rc);}#define QCTL_COPY(out, in)              \do {                                    \        Q_COPY(out, in, qc_cmd);        \        Q_COPY(out, in, qc_type);       \        Q_COPY(out, in, qc_id);         \        Q_COPY(out, in, qc_stat);       \        Q_COPY(out, in, qc_dqinfo);     \        Q_COPY(out, in, qc_dqblk);      \} while (0)int ll_send_mgc_param(struct obd_export *mgc, char *string){        struct mgs_send_param *msp;        int rc = 0;        OBD_ALLOC_PTR(msp);        if (!msp)                return -ENOMEM;        strncpy(msp->mgs_param, string, MGS_PARAM_MAXLEN);        rc = obd_set_info_async(mgc, strlen(KEY_SET_INFO), KEY_SET_INFO,                                sizeof(struct mgs_send_param), msp, NULL);        if (rc)                CERROR("Failed to set parameter: %d\n", rc);        OBD_FREE_PTR(msp);        return rc;}char *ll_get_fsname(struct inode *inode){        struct lustre_sb_info *lsi = s2lsi(inode->i_sb);        char *ptr, *fsname;        int len;        OBD_ALLOC(fsname, MGS_PARAM_MAXLEN);        len = strlen(lsi->lsi_lmd->lmd_profile);        ptr = strrchr(lsi->lsi_lmd->lmd_profile, '-');        if (ptr && (strcmp(ptr, "-client") == 0))                len -= 7;        strncpy(fsname, lsi->lsi_lmd->lmd_profile, len);        fsname[len] = '\0';        return fsname;}int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,                     int set_default){        struct ll_sb_info *sbi = ll_i2sbi(inode);        struct mdc_op_data data;        struct ptlrpc_request *req = NULL;        struct lustre_sb_info *lsi = s2lsi(inode->i_sb);        struct obd_device *mgc = lsi->lsi_mgc;        char *fsname = NULL, *param = NULL;        struct iattr attr = { 0 };        int rc = 0;        /*         * This is coming from userspace, so should be in         * local endian.  But the MDS would like it in little         * endian, so we swab it before we send it.         */        if (lump->lmm_magic != LOV_USER_MAGIC)                RETURN(-EINVAL);        if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC))                lustre_swab_lov_user_md(lump);        ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0, NULL);        /* swabbing is done in lov_setstripe() on server side */        rc = mdc_setattr(sbi->ll_mdc_exp, &data,                         &attr, lump, sizeof(*lump), NULL, 0, &req);        if (rc) {                ptlrpc_req_finished(req);                if (rc != -EPERM && rc != -EACCES)                        CERROR("mdc_setattr fails: rc = %d\n", rc);                return rc;        }        ptlrpc_req_finished(req);        if (set_default && mgc->u.cli.cl_mgc_mgsexp) {                OBD_ALLOC(param, MGS_PARAM_MAXLEN);                /* Get fsname and assume devname to be -MDT0000. */                fsname = ll_get_fsname(inode);                /* Set root stripesize */                sprintf(param, "%s-MDT0000.lov.stripesize=%u", fsname,                        lump->lmm_stripe_size);                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);                if (rc)                        goto end;                /* Set root stripecount */                sprintf(param, "%s-MDT0000.lov.stripecount=%u", fsname,                        lump->lmm_stripe_count);                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);                if (rc)                        goto end;                /* Set root stripeoffset */                sprintf(param, "%s-MDT0000.lov.stripeoffset=%u", fsname,                        lump->lmm_stripe_offset);                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);                if (rc)                        goto end;end:                if (fsname)                        OBD_FREE(fsname, MGS_PARAM_MAXLEN);                if (param)                        OBD_FREE(param, MGS_PARAM_MAXLEN);        }        return rc;}int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,                     int *lmm_size, struct ptlrpc_request **request){        struct ll_sb_info *sbi = ll_i2sbi(inode);        struct ll_fid     fid;        struct mds_body   *body;        struct lov_mds_md *lmm = NULL;        struct ptlrpc_request *req = NULL;        int rc, lmmsize;        ll_inode2fid(&fid, inode);        rc = ll_get_max_mdsize(sbi, &lmmsize);        if (rc)                RETURN(rc);        rc = mdc_getattr(sbi->ll_mdc_exp, &fid,                        OBD_MD_FLEASIZE|OBD_MD_FLDIREA,                        lmmsize, &req);        if (rc < 0) {                CDEBUG(D_INFO, "mdc_getattr failed on inode "                       "%lu/%u: rc %d\n", inode->i_ino,                       inode->i_generation, rc);                GOTO(out, rc);        }        body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF,                        sizeof(*body));        LASSERT(body != NULL); /* checked by mdc_getattr_name */        /* swabbed by mdc_getattr_name */        LASSERT(lustre_rep_swabbed(req, REPLY_REC_OFF));        lmmsize = body->eadatasize;        if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||            lmmsize == 0) {                GOTO(out, rc = -ENODATA);        }        lmm = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF + 1, lmmsize);        LASSERT(lmm != NULL);        LASSERT(lustre_rep_swabbed(req, REPLY_REC_OFF + 1));        /*         * This is coming from the MDS, so is probably in         * little endian.  We convert it to host endian before         * passing it to userspace.         */        if (lmm->lmm_magic == __swab32(LOV_MAGIC)) {                lustre_swab_lov_user_md((struct lov_user_md *)lmm);        }out:        *lmmp = lmm;        *lmm_size = lmmsize;        *request = req;        return rc;}static int ll_dir_ioctl(struct inode *inode, struct file *file,                        unsigned int cmd, unsigned long arg){        struct ll_sb_info *sbi = ll_i2sbi(inode);        struct obd_ioctl_data *data;        ENTRY;        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), cmd=%#x\n",               inode->i_ino, inode->i_generation, inode, cmd);        /* asm-ppc{,64} declares TCGETS, et. al. as type 't' not 'T' */        if (_IOC_TYPE(cmd) == 'T' || _IOC_TYPE(cmd) == 't') /* tty ioctls */                return -ENOTTY;        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_IOCTL, 1);        switch(cmd) {        case EXT3_IOC_GETFLAGS:        case EXT3_IOC_SETFLAGS:                RETURN(ll_iocontrol(inode, file, cmd, arg));        case EXT3_IOC_GETVERSION_OLD:        case EXT3_IOC_GETVERSION:                RETURN(put_user(inode->i_generation, (int *)arg));        /* We need to special case any other ioctls we want to handle,         * to send them to the MDS/OST as appropriate and to properly         * network encode the arg field.        case EXT3_IOC_SETVERSION_OLD:        case EXT3_IOC_SETVERSION:        */        case IOC_MDC_LOOKUP: {                struct ptlrpc_request *request = NULL;                struct ll_fid fid;                char *buf = NULL;                char *filename;                int namelen, rc, len = 0;                rc = obd_ioctl_getdata(&buf, &len, (void *)arg);                if (rc)                        RETURN(rc);                data = (void *)buf;                filename = data->ioc_inlbuf1;                namelen = data->ioc_inllen1;                if (namelen < 1) {                        CDEBUG(D_INFO, "IOC_MDC_LOOKUP missing filename\n");                        GOTO(out, rc = -EINVAL);                }                ll_inode2fid(&fid, inode);                rc = mdc_getattr_name(sbi->ll_mdc_exp, &fid, filename, namelen,                                      OBD_MD_FLID, 0, &request);                if (rc < 0) {                        CDEBUG(D_INFO, "mdc_getattr_name: %d\n", rc);                        GOTO(out, rc);                }                ptlrpc_req_finished(request);                EXIT;        out:                obd_ioctl_freedata(buf, len);                return rc;        }        case LL_IOC_LOV_SETSTRIPE: {                struct lov_user_md lum, *lump = (struct lov_user_md *)arg;                int rc = 0;                int set_default = 0;                LASSERT(sizeof(lum) == sizeof(*lump));                LASSERT(sizeof(lum.lmm_objects[0]) ==                        sizeof(lump->lmm_objects[0]));                rc = copy_from_user(&lum, lump, sizeof(lum));                if (rc)                        return(-EFAULT);                if (inode->i_sb->s_root == file->f_dentry)                        set_default = 1;                rc = ll_dir_setstripe(inode, &lum, set_default);                return rc;        }        case LL_IOC_OBD_STATFS:                RETURN(ll_obd_statfs(inode, (void *)arg));        case LL_IOC_LOV_GETSTRIPE:        case LL_IOC_MDC_GETINFO:        case IOC_MDC_GETFILEINFO:        case IOC_MDC_GETFILESTRIPE: {                struct ptlrpc_request *request = NULL;                struct mds_body *body;                struct lov_user_md *lump;                struct lov_mds_md *lmm = NULL;                char *filename = NULL;                int rc, lmmsize;                if (cmd == IOC_MDC_GETFILEINFO ||                    cmd == IOC_MDC_GETFILESTRIPE) {                        filename = getname((const char *)arg);                        if (IS_ERR(filename))

⌨️ 快捷键说明

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