filter.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,698 行 · 第 1/5 页

C
1,698
字号
                mount_count = fsd->lsd_mount_count = 0;                fsd->lsd_server_size = cpu_to_le32(LR_SERVER_SIZE);                fsd->lsd_client_start = cpu_to_le32(LR_CLIENT_START);                fsd->lsd_client_size = cpu_to_le16(LR_CLIENT_SIZE);                fsd->lsd_subdir_count = cpu_to_le16(FILTER_SUBDIR_COUNT);                filter->fo_subdir_count = FILTER_SUBDIR_COUNT;                fsd->lsd_feature_incompat = cpu_to_le32(OBD_INCOMPAT_OST);        } else {                rc = fsfilt_read_record(obd, filp, fsd, sizeof(*fsd), &off);                if (rc) {                        CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",                               LAST_RCVD, rc);                        GOTO(err_fsd, rc);                }                if (strcmp(fsd->lsd_uuid, obd->obd_uuid.uuid) != 0) {                        LCONSOLE_ERROR_MSG(0x134, "Trying to start OBD %s using"                                           " the wrong disk %s. Were the /dev/ "                                           "assignments rearranged?\n",                                           obd->obd_uuid.uuid, fsd->lsd_uuid);                        GOTO(err_fsd, rc = -EINVAL);                }                mount_count = le64_to_cpu(fsd->lsd_mount_count);                filter->fo_subdir_count = le16_to_cpu(fsd->lsd_subdir_count);                /* COMPAT_146 */                /* Assume old last_rcvd format unless I_C_LR is set */                if (!(fsd->lsd_feature_incompat &                      cpu_to_le32(OBD_INCOMPAT_COMMON_LR)))                        fsd->lsd_last_transno = fsd->lsd_compat14;                /* end COMPAT_146 */        }        if (fsd->lsd_feature_incompat & ~cpu_to_le32(FILTER_INCOMPAT_SUPP)) {                CERROR("%s: unsupported incompat filesystem feature(s) %x\n",                       obd->obd_name, le32_to_cpu(fsd->lsd_feature_incompat) &                       ~FILTER_INCOMPAT_SUPP);                GOTO(err_fsd, rc = -EINVAL);        }        if (fsd->lsd_feature_rocompat & ~cpu_to_le32(FILTER_ROCOMPAT_SUPP)) {                CERROR("%s: unsupported read-only filesystem feature(s) %x\n",                       obd->obd_name, le32_to_cpu(fsd->lsd_feature_rocompat) &                       ~FILTER_ROCOMPAT_SUPP);                /* Do something like remount filesystem read-only */                GOTO(err_fsd, rc = -EINVAL);        }        CDEBUG(D_INODE, "%s: server last_transno : "LPU64"\n",               obd->obd_name, le64_to_cpu(fsd->lsd_last_transno));        CDEBUG(D_INODE, "%s: server mount_count: "LPU64"\n",               obd->obd_name, mount_count + 1);        CDEBUG(D_INODE, "%s: server data size: %u\n",               obd->obd_name, le32_to_cpu(fsd->lsd_server_size));        CDEBUG(D_INODE, "%s: per-client data start: %u\n",               obd->obd_name, le32_to_cpu(fsd->lsd_client_start));        CDEBUG(D_INODE, "%s: per-client data size: %u\n",               obd->obd_name, le32_to_cpu(fsd->lsd_client_size));        CDEBUG(D_INODE, "%s: server subdir_count: %u\n",               obd->obd_name, le16_to_cpu(fsd->lsd_subdir_count));        CDEBUG(D_INODE, "%s: last_rcvd clients: %lu\n", obd->obd_name,               last_rcvd_size <= le32_to_cpu(fsd->lsd_client_start) ? 0 :               (last_rcvd_size - le32_to_cpu(fsd->lsd_client_start)) /                le16_to_cpu(fsd->lsd_client_size));        if (!obd->obd_replayable) {                CWARN("%s: recovery support OFF\n", obd->obd_name);                GOTO(out, rc = 0);        }        for (cl_idx = 0, off = le32_to_cpu(fsd->lsd_client_start);             off < last_rcvd_size; cl_idx++) {                __u64 last_rcvd;                struct obd_export *exp;                struct filter_export_data *fed;                if (!fcd) {                        OBD_ALLOC(fcd, sizeof(*fcd));                        if (!fcd)                                GOTO(err_client, rc = -ENOMEM);                }                /* Don't assume off is incremented properly by                 * fsfilt_read_record(), in case sizeof(*fcd)                 * isn't the same as fsd->lsd_client_size.  */                off = le32_to_cpu(fsd->lsd_client_start) +                        cl_idx * le16_to_cpu(fsd->lsd_client_size);                rc = fsfilt_read_record(obd, filp, fcd, sizeof(*fcd), &off);                if (rc) {                        CERROR("error reading FILT %s idx %d off %llu: rc %d\n",                               LAST_RCVD, cl_idx, off, rc);                        break; /* read error shouldn't cause startup to fail */                }                if (fcd->fcd_uuid[0] == '\0') {                        CDEBUG(D_INFO, "skipping zeroed client at offset %d\n",                               cl_idx);                        continue;                }                last_rcvd = le64_to_cpu(fcd->fcd_last_rcvd);                /* These exports are cleaned up by filter_disconnect(), so they                 * need to be set up like real exports as filter_connect() does.                 */                exp = class_new_export(obd, (struct obd_uuid *)fcd->fcd_uuid);                CDEBUG(D_HA, "RCVRNG CLIENT uuid: %s idx: %d lr: "LPU64                       " srv lr: "LPU64"\n", fcd->fcd_uuid, cl_idx,                       last_rcvd, le64_to_cpu(fsd->lsd_last_transno));                if (IS_ERR(exp)) {                        if (PTR_ERR(exp) == -EALREADY) {                                /* export already exists, zero out this one */                                CERROR("Zeroing out duplicate export due to "                                       "bug 10479.\n");                                fcd->fcd_uuid[0] = '\0';                        } else {                                GOTO(err_client, rc = PTR_ERR(exp));                        }                } else {                        fed = &exp->exp_filter_data;                        fed->fed_fcd = fcd;                        filter_export_stats_init(obd, exp, 0);                        rc = filter_client_add(obd, exp, cl_idx, 0);                        /* can't fail for existing client */                        LASSERTF(rc == 0, "rc = %d\n", rc);                        fcd = NULL;                        spin_lock(&exp->exp_lock);                        exp->exp_replay_needed = 1;                        exp->exp_connecting = 0;                        spin_unlock(&exp->exp_lock);                        obd->obd_recoverable_clients++;                        obd->obd_max_recoverable_clients++;                        class_export_put(exp);                }                /* Need to check last_rcvd even for duplicated exports. */                CDEBUG(D_OTHER, "client at idx %d has last_rcvd = "LPU64"\n",                       cl_idx, last_rcvd);                if (last_rcvd > le64_to_cpu(fsd->lsd_last_transno))                        fsd->lsd_last_transno = cpu_to_le64(last_rcvd);        }        if (fcd)                OBD_FREE(fcd, sizeof(*fcd));        obd->obd_last_committed = le64_to_cpu(fsd->lsd_last_transno);        if (obd->obd_recoverable_clients) {                CWARN("RECOVERY: service %s, %d recoverable clients, "                      "last_rcvd "LPU64"\n", obd->obd_name,                      obd->obd_recoverable_clients,                      le64_to_cpu(fsd->lsd_last_transno));                obd->obd_next_recovery_transno = obd->obd_last_committed + 1;                obd->obd_recovering = 1;                obd->obd_recovery_start = 0;                obd->obd_recovery_end = 0;                obd->obd_recovery_timeout = OBD_RECOVERY_FACTOR * obd_timeout;#ifdef CRAY_XT3                /* b13079: this should be set to desired value for ost */                obd->obd_recovery_max_time = OBD_RECOVERY_MAX_TIME;#endif        }out:        filter->fo_mount_count = mount_count + 1;        fsd->lsd_mount_count = cpu_to_le64(filter->fo_mount_count);        /* save it, so mount count and last_transno is current */        rc = filter_update_server_data(obd, filp, filter->fo_fsd, 1);        if (rc)                GOTO(err_client, rc);        RETURN(0);err_client:        class_disconnect_exports(obd);err_fsd:        filter_free_server_data(filter);        RETURN(rc);}static int filter_cleanup_groups(struct obd_device *obd){        struct filter_obd *filter = &obd->u.filter;        struct file *filp;        struct dentry *dentry;        int i;        ENTRY;        if (filter->fo_dentry_O_groups != NULL) {                for (i = 0; i < FILTER_GROUPS; i++) {                        dentry = filter->fo_dentry_O_groups[i];                        if (dentry != NULL)                                f_dput(dentry);                }                OBD_FREE(filter->fo_dentry_O_groups,                         FILTER_GROUPS * sizeof(*filter->fo_dentry_O_groups));                filter->fo_dentry_O_groups = NULL;        }        if (filter->fo_last_objid_files != NULL) {                for (i = 0; i < FILTER_GROUPS; i++) {                        filp = filter->fo_last_objid_files[i];                        if (filp != NULL)                                filp_close(filp, 0);                }                OBD_FREE(filter->fo_last_objid_files,                         FILTER_GROUPS * sizeof(*filter->fo_last_objid_files));                filter->fo_last_objid_files = NULL;        }        if (filter->fo_dentry_O_sub != NULL) {                for (i = 0; i < filter->fo_subdir_count; i++) {                        dentry = filter->fo_dentry_O_sub[i];                        if (dentry != NULL)                                f_dput(dentry);                }                OBD_FREE(filter->fo_dentry_O_sub,                         filter->fo_subdir_count *                         sizeof(*filter->fo_dentry_O_sub));                filter->fo_dentry_O_sub = NULL;        }        if (filter->fo_last_objids != NULL) {                OBD_FREE(filter->fo_last_objids,                         FILTER_GROUPS * sizeof(*filter->fo_last_objids));                filter->fo_last_objids = NULL;        }        if (filter->fo_dentry_O != NULL) {                f_dput(filter->fo_dentry_O);                filter->fo_dentry_O = NULL;        }        RETURN(0);}/* FIXME: object groups */static int filter_prep_groups(struct obd_device *obd){        struct filter_obd *filter = &obd->u.filter;        struct dentry *dentry, *O_dentry;        struct file *filp;        int i, rc = 0, cleanup_phase = 0;        ENTRY;        O_dentry = simple_mkdir(current->fs->pwd, "O", 0700, 1);        CDEBUG(D_INODE, "got/created O: %p\n", O_dentry);        if (IS_ERR(O_dentry)) {                rc = PTR_ERR(O_dentry);                CERROR("cannot open/create O: rc = %d\n", rc);                GOTO(cleanup, rc);        }        filter->fo_dentry_O = O_dentry;        cleanup_phase = 1; /* O_dentry */        OBD_ALLOC(filter->fo_last_objids, FILTER_GROUPS * sizeof(__u64));        if (filter->fo_last_objids == NULL)                GOTO(cleanup, rc = -ENOMEM);        cleanup_phase = 2; /* groups */        OBD_ALLOC(filter->fo_dentry_O_groups, FILTER_GROUPS * sizeof(dentry));        if (filter->fo_dentry_O_groups == NULL)                GOTO(cleanup, rc = -ENOMEM);        OBD_ALLOC(filter->fo_last_objid_files, FILTER_GROUPS * sizeof(filp));        if (filter->fo_last_objid_files == NULL)                GOTO(cleanup, rc = -ENOMEM);        for (i = 0; i < FILTER_GROUPS; i++) {                char name[25];                loff_t off = 0;                sprintf(name, "%d", i);                dentry = simple_mkdir(O_dentry, name, 0700, 1);                CDEBUG(D_INODE, "got/created O/%s: %p\n", name, dentry);                if (IS_ERR(dentry)) {                        rc = PTR_ERR(dentry);                        CERROR("cannot lookup/create O/%s: rc = %d\n",                               name, rc);                        GOTO(cleanup, rc);                }                filter->fo_dentry_O_groups[i] = dentry;                sprintf(name, "O/%d/LAST_ID", i);                filp = filp_open(name, O_CREAT | O_RDWR, 0700);                if (IS_ERR(filp)) {                        rc = PTR_ERR(filp);                        CERROR("cannot create %s: rc = %d\n", name, rc);                        GOTO(cleanup, rc);                }                filter->fo_last_objid_files[i] = filp;                if (i_size_read(filp->f_dentry->d_inode) == 0) {                        filter->fo_last_objids[i] = FILTER_INIT_OBJID;                        rc = filter_update_last_objid(obd, i, 1);                        if (rc)                                GOTO(cleanup, rc);                        continue;                }                rc = fsfilt_read_record(obd, filp, &filter->fo_last_objids[i],                                        sizeof(__u64), &off);                if (rc) {                        CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",                               name, rc);                        GOTO(cleanup, rc);                }                filter->fo_last_objids[i] =                        le64_to_cpu(filter->fo_last_objids[i]);                CDEBUG(D_HA, "%s: server last_objid group %d: "LPU64"\n",                       obd->obd_name, i, filter->fo_last_objids[i]);        }        if (filter->fo_subdir_count) {                O_dentry = filter->fo_dentry_O_groups[0];                OBD_ALLOC(filter->fo_dentry_O_sub,                          filter->fo_subdir_count * sizeof(dentry));                if (filter->fo_dentry_O_sub == NULL)                        GOTO(cleanup, rc = -ENOMEM);                for (i = 0; i < filter->fo_subdir_count; i++) {                        char dir[20];                        snprintf(dir, sizeof(dir), "d%u", i);                        dentry = simple_mkdir(O_dentry, dir, 0700, 1);                        CDEBUG(D_INODE, "got/created O/0/%s: %p\n", dir,dentry);                        if (IS_ERR(dentry)) {                                rc = PTR_ERR(dentry);                                CERROR("can't lookup/create O/0/%s: rc = %d\n",                                       dir, rc);                                GOTO(cleanup, rc);                        }                        filter->fo_dentry_O_sub[i] = dentry;                }        }        RETURN(0); cleanup:        filter_cleanup_groups(obd);        return rc;}/* setup the object store with correct subdirectories */static int filter_prep(struct obd_device *obd)

⌨️ 快捷键说明

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