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 + -
显示快捷键?