diff --git a/lustre/include/lustre_log.h b/lustre/include/lustre_log.h index c5afafb8ce6a99fabbba9624074a96ee64064b02..129459de9636e3dc7e2d3729b9e749454b2bc787 100644 --- a/lustre/include/lustre_log.h +++ b/lustre/include/lustre_log.h @@ -182,7 +182,7 @@ int llog_obd_origin_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec, struct lov_stripe_md *lsm, struct llog_cookie *logcookies, int numcookies); -int llog_cat_initialize(struct obd_device *obd, int count, +int llog_cat_initialize(struct obd_device *obd, int idx, struct obd_uuid *uuid); int obd_llog_init(struct obd_device *obd, struct obd_device *disk_obd, int count, struct llog_catid *logid, struct obd_uuid *uuid); @@ -245,7 +245,8 @@ struct llog_operations { /* llog_lvfs.c */ extern struct llog_operations llog_lvfs_ops; int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, - char *name, int count, struct llog_catid *idarray); + char *name, int idx, int count, + struct llog_catid *idarray); struct llog_ctxt { int loc_idx; /* my index the obd array of ctxt's */ diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 4322670dd00f3bff0a27315841a9851cd8551548..b80d35005c1ddabf79b38f549385eec6b079bec6 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -827,7 +827,6 @@ struct obd_device { struct list_head obd_nid_stats; atomic_t obd_refcount; cfs_waitq_t obd_refcount_waitq; - cfs_waitq_t obd_llog_waitq; struct list_head obd_exports; int obd_num_exports; spinlock_t obd_nid_lock; @@ -842,7 +841,11 @@ struct obd_device { struct obd_statfs obd_osfs; /* locked by obd_osfs_lock */ __u64 obd_osfs_age; struct lvfs_run_ctxt obd_lvfs_ctxt; - struct llog_ctxt *obd_llog_ctxt[LLOG_MAX_CTXTS]; + + struct llog_ctxt *obd_llog_ctxt[LLOG_MAX_CTXTS]; + struct semaphore obd_llog_alloc; + cfs_waitq_t obd_llog_waitq; + struct obd_device *obd_observer; struct obd_notify_upcall obd_upcall; struct obd_export *obd_self_export; diff --git a/lustre/lov/lov_log.c b/lustre/lov/lov_log.c index 1e606b02cb3f30905510e430d16a1c76c200199b..9fc3e79c359b52a7f9ce01a5de3520b76ba33419 100644 --- a/lustre/lov/lov_log.c +++ b/lustre/lov/lov_log.c @@ -202,6 +202,8 @@ int lov_llog_init(struct obd_device *obd, struct obd_device *tgt, int i, rc = 0, err = 0; ENTRY; + LASSERT(uuid); + rc = llog_setup(obd, LLOG_MDS_OST_ORIG_CTXT, tgt, 0, NULL, &lov_mds_ost_orig_logops); if (rc) @@ -213,16 +215,15 @@ int lov_llog_init(struct obd_device *obd, struct obd_device *tgt, RETURN(rc); lov_getref(obd); - /* count may not match lov->desc.ld_tgt_count during dynamic ost add */ - for (i = 0; i < count; i++) { + for (i = 0; i < lov->desc.ld_tgt_count ; i++) { if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) continue; - if (uuid && !obd_uuid_equals(uuid, &lov->lov_tgts[i]->ltd_uuid)) + if (!obd_uuid_equals(uuid, &lov->lov_tgts[i]->ltd_uuid)) continue; CDEBUG(D_CONFIG, "init %d/%d\n", i, count); LASSERT(lov->lov_tgts[i]->ltd_exp); child = lov->lov_tgts[i]->ltd_exp->exp_obd; - rc = obd_llog_init(child, tgt, 1, logid + i, uuid); + rc = obd_llog_init(child, tgt, 1, logid, uuid); if (rc) { CERROR("error osc_llog_init idx %d osc '%s' tgt '%s' " "(rc=%d)\n", i, child->obd_name, tgt->obd_name, diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index 5a75a3a8743847ad83652f9133fe3b04ffa79f44..f9b677049f2c3576c194e5d3d1ec1d0366010cb6 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -289,8 +289,7 @@ static int mds_lov_update_from_read(struct mds_obd *mds, obd_id *data, mds->mds_max_mdsize = lov_mds_md_size(stripes); mds->mds_max_cookiesize = stripes * sizeof(struct llog_cookie); CDEBUG(D_CONFIG, "updated max_mdsize/max_cookiesize for %d stripes: " - "%d/%d\n", mds->mds_max_mdsize, mds->mds_max_cookiesize, - stripes); + "%d/%d\n", stripes, mds->mds_max_mdsize, mds->mds_max_cookiesize); } EXIT; return 0; @@ -401,7 +400,7 @@ static int mds_lov_get_objid(struct obd_device * obd, off = idx % OBJID_PER_PAGE(); data = mds->mds_lov_page_array[page]; - if (data[off] == 0) { + if (data[off] < 2) { /* We never read this lastid; ask the osc */ struct obd_id_info lastid; __u32 size = sizeof(lastid); @@ -413,6 +412,10 @@ static int mds_lov_get_objid(struct obd_device * obd, if (rc) GOTO(out, rc); + /* workaround for clean filter */ + if (data[off] == 0) + data[off] = 1; + cfs_bitmap_set(mds->mds_lov_page_dirty, page); } CDEBUG(D_INFO, "idx "LPU64" - %p - %d/%d - "LPU64"\n", @@ -467,8 +470,8 @@ static int mds_lov_set_one_nextid(struct obd_device * obd, __u32 idx, obd_id *id } /* Update the lov desc for a new size lov. */ -static int mds_lov_update_desc(struct obd_device *obd, struct obd_export *lov, - __u32 index) +static int mds_lov_update_desc(struct obd_device *obd, __u32 index, + struct obd_uuid *uuid) { struct mds_obd *mds = &obd->u.mds; struct lov_desc *ld; @@ -480,7 +483,7 @@ static int mds_lov_update_desc(struct obd_device *obd, struct obd_export *lov, if (!ld) RETURN(-ENOMEM); - rc = obd_get_info(lov, sizeof(KEY_LOVDESC), KEY_LOVDESC, + rc = obd_get_info(mds->mds_osc_exp, sizeof(KEY_LOVDESC), KEY_LOVDESC, &valsize, ld, NULL); if (rc) GOTO(out, rc); @@ -500,7 +503,7 @@ static int mds_lov_update_desc(struct obd_device *obd, struct obd_export *lov, /* If we added a target we have to reconnect the llogs */ /* We only _need_ to do this at first add (idx), or the first time after recovery. However, it should now be safe to call anytime. */ - rc = llog_cat_initialize(obd, mds->mds_lov_desc.ld_tgt_count, NULL); + rc = llog_cat_initialize(obd, index, uuid); out: OBD_FREE(ld, sizeof(*ld)); @@ -524,7 +527,7 @@ static int mds_lov_update_mds(struct obd_device *obd, /* Don't let anyone else mess with mds_lov_objids now */ old_count = mds->mds_lov_desc.ld_tgt_count; - rc = mds_lov_update_desc(obd, mds->mds_osc_exp, idx); + rc = mds_lov_update_desc(obd, idx, &watched->u.cli.cl_target_uuid); if (rc) GOTO(out, rc); @@ -1069,8 +1072,9 @@ int mds_notify(struct obd_device *obd, struct obd_device *watched, after the mdt in the config log. They didn't make it into mds_lov_connect. */ LASSERT(data); - rc = mds_lov_update_desc(obd, obd->u.mds.mds_osc_exp, - *(__u32 *)data); + rc = mds_lov_update_desc(obd, *(__u32 *)data, + &watched->u.cli.cl_target_uuid); + mds_allow_cli(obd, CONFIG_SYNC); RETURN(rc); } diff --git a/lustre/obdclass/llog_internal.h b/lustre/obdclass/llog_internal.h index a992c1bbf1a0dcf4b6217cface9cef67acfad6b9..4c310161522afe1d9ea96875626528da814819ba 100644 --- a/lustre/obdclass/llog_internal.h +++ b/lustre/obdclass/llog_internal.h @@ -49,7 +49,9 @@ struct llog_process_info { }; int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, - char *name, int count, struct llog_catid *idarray); + char *name, int idx, int count, + struct llog_catid *idarray); + int llog_cat_id2handle(struct llog_handle *cathandle, struct llog_handle **res, struct llog_logid *logid); int class_config_dump_handler(struct llog_handle * handle, diff --git a/lustre/obdclass/llog_ioctl.c b/lustre/obdclass/llog_ioctl.c index d1c3fa5def18c5a8bf73c25d9ea951446efce773..48b9cc1ec016b51a09b44524b80565c5b1fa8dc5 100644 --- a/lustre/obdclass/llog_ioctl.c +++ b/lustre/obdclass/llog_ioctl.c @@ -432,12 +432,11 @@ int llog_catalog_list(struct obd_device *obd, int count, ENTRY; size = sizeof(*idarray) * count; - OBD_ALLOC(idarray, size); + OBD_VMALLOC(idarray, size); if (!idarray) RETURN(-ENOMEM); - memset(idarray, 0, size); - rc = llog_get_cat_list(obd, obd, name, count, idarray); + rc = llog_get_cat_list(obd, obd, name, 0, count, idarray); if (rc) { OBD_FREE(idarray, size); RETURN(rc); @@ -457,7 +456,7 @@ int llog_catalog_list(struct obd_device *obd, int count, break; } } - OBD_FREE(idarray, size); + OBD_VFREE(idarray, size); RETURN(0); } diff --git a/lustre/obdclass/llog_lvfs.c b/lustre/obdclass/llog_lvfs.c index 20b20126e268cf2dfaa9b25cee93b50dda18b3cc..dfcf1446f2f0d5b6b578175658ff0d4dcc5888b7 100644 --- a/lustre/obdclass/llog_lvfs.c +++ b/lustre/obdclass/llog_lvfs.c @@ -765,13 +765,13 @@ static int llog_lvfs_destroy(struct llog_handle *handle) /* reads the catalog list */ int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, - char *name, int count, struct llog_catid *idarray) + char *name, int idx, int count, struct llog_catid *idarray) { struct lvfs_run_ctxt saved; struct l_file *file; - int rc; + int rc, rc1 = 0; int size = sizeof(*idarray) * count; - loff_t off = 0; + loff_t off = idx * sizeof(*idarray); ENTRY; if (!count) @@ -785,7 +785,7 @@ int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, name, rc); GOTO(out, rc); } - + if (!S_ISREG(file->f_dentry->d_inode->i_mode)) { CERROR("%s is not a regular file!: mode = %o\n", name, file->f_dentry->d_inode->i_mode); @@ -795,6 +795,12 @@ int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, CDEBUG(D_CONFIG, "cat list: disk size=%d, read=%d\n", (int)i_size_read(file->f_dentry->d_inode), size); + /* read for new ost index or for empty file */ + if (i_size_read(file->f_dentry->d_inode) < off) { + memset(idarray, 0, size); + GOTO(out, rc = 0); + } + rc = fsfilt_read_record(disk_obd, file, idarray, size, &off); if (rc) { CERROR("OBD filter: error reading %s: rc %d\n", name, rc); @@ -805,22 +811,24 @@ int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, out: pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); if (file && !IS_ERR(file)) - rc = filp_close(file, 0); + rc1 = filp_close(file, 0); + if (rc == 0) + rc = rc1; return rc; } EXPORT_SYMBOL(llog_get_cat_list); /* writes the cat list */ int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, - char *name, int count, struct llog_catid *idarray) + char *name, int idx, int count, struct llog_catid *idarray) { struct lvfs_run_ctxt saved; struct l_file *file; - int rc; + int rc, rc1 = 0; int size = sizeof(*idarray) * count; - loff_t off = 0; + loff_t off = idx * sizeof(*idarray); - if (!count) + if (!count) return (0); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); @@ -840,7 +848,7 @@ int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, rc = fsfilt_write_record(disk_obd, file, idarray, size, &off, 1); if (rc) { - CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n", + CDEBUG(D_INODE,"OBD filter: error writeing %s: rc %d\n", name, rc); GOTO(out, rc); } @@ -848,7 +856,10 @@ int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, out: pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); if (file && !IS_ERR(file)) - rc = filp_close(file, 0); + rc1 = filp_close(file, 0); + + if (rc == 0) + rc = rc1; RETURN(rc); } @@ -917,14 +928,14 @@ static int llog_lvfs_destroy(struct llog_handle *handle) } int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, - char *name, int count, struct llog_catid *idarray) + char *name, int idx, int count, struct llog_catid *idarray) { LBUG(); return 0; } int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, - char *name, int count, struct llog_catid *idarray) + char *name, int idx, int count, struct llog_catid *idarray) { LBUG(); return 0; diff --git a/lustre/obdclass/llog_obd.c b/lustre/obdclass/llog_obd.c index 638f1fdee181258a484280d7c8d9c218bf51a6e7..d03b6372bdbcb61d160e8ea4da703d4d6363c843 100644 --- a/lustre/obdclass/llog_obd.c +++ b/lustre/obdclass/llog_obd.c @@ -57,10 +57,10 @@ static struct llog_ctxt* llog_new_ctxt(struct obd_device *obd) OBD_ALLOC(ctxt, sizeof(*ctxt)); if (!ctxt) return NULL; - + ctxt->loc_obd = obd; atomic_set(&ctxt->loc_refcount, 1); - + return ctxt; } @@ -144,18 +144,22 @@ int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd, if (index < 0 || index >= LLOG_MAX_CTXTS) RETURN(-EFAULT); - ctxt = llog_get_context(obd, index); + /* someone can call lov_llog_init with NULL uuid - this can produce + * parallel enter to this function */ + mutex_down(&obd->obd_llog_alloc); + ctxt = llog_get_context(obd, index); if (ctxt) { /* mds_lov_update_mds might call here multiple times. So if the llog is already set up then don't to do it again. */ - CDEBUG(D_CONFIG, "obd %s ctxt %d already set up\n", + CDEBUG(D_CONFIG, "obd %s ctxt %d already set up\n", obd->obd_name, index); LASSERT(ctxt->loc_obd == obd); LASSERT(ctxt->loc_exp == disk_obd->obd_self_export); LASSERT(ctxt->loc_logops == op); - llog_ctxt_put(ctxt); + llog_ctxt_put(ctxt); GOTO(out, rc = 0); } + ctxt = llog_new_ctxt(obd); if (!ctxt) GOTO(out, rc = -ENOMEM); @@ -178,6 +182,7 @@ int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd, obd->obd_llog_ctxt[index] = NULL; } out: + mutex_up(&obd->obd_llog_alloc); RETURN(rc); } EXPORT_SYMBOL(llog_setup); @@ -396,42 +401,33 @@ int llog_obd_origin_add(struct llog_ctxt *ctxt, } EXPORT_SYMBOL(llog_obd_origin_add); -int llog_cat_initialize(struct obd_device *obd, int count, +int llog_cat_initialize(struct obd_device *obd, int idx, struct obd_uuid *uuid) { + struct llog_catid idarray; char name[32] = CATLIST; - struct llog_catid *idarray = NULL; - int size = sizeof(*idarray) * count; int rc; ENTRY; - if (count) { - OBD_VMALLOC(idarray, size); - if (!idarray) - RETURN(-ENOMEM); - } - - rc = llog_get_cat_list(obd, obd, name, count, idarray); + rc = llog_get_cat_list(obd, obd, name, idx, 1, &idarray); if (rc) { CERROR("rc: %d\n", rc); GOTO(out, rc); } - rc = obd_llog_init(obd, obd, count, idarray, uuid); + rc = obd_llog_init(obd, obd, 1, &idarray, uuid); if (rc) { CERROR("rc: %d\n", rc); GOTO(out, rc); } - rc = llog_put_cat_list(obd, obd, name, count, idarray); + rc = llog_put_cat_list(obd, obd, name, idx, 1, &idarray); if (rc) { CERROR("rc: %d\n", rc); GOTO(out, rc); } out: - if (idarray) - OBD_VFREE(idarray, size); RETURN(rc); } EXPORT_SYMBOL(llog_cat_initialize); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 980d34459e3b83884d538b017d0983a73971eb10..565b0f15d0d0dcc0480ae6a0d533a24fb8db637f 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -223,6 +223,7 @@ int class_attach(struct lustre_cfg *lcfg) cfs_waitq_init(&obd->obd_next_transno_waitq); cfs_waitq_init(&obd->obd_evict_inprogress_waitq); cfs_waitq_init(&obd->obd_llog_waitq); + init_mutex(&obd->obd_llog_alloc); CFS_INIT_LIST_HEAD(&obd->obd_recovery_queue); CFS_INIT_LIST_HEAD(&obd->obd_delayed_reply_queue); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 765b748e0931a9fdd17fd82dc5486e52d8aef56b..e611d96361725170aba9ca3f1649bb4d1d786f6b 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -1817,7 +1817,7 @@ int filter_common_setup(struct obd_device *obd, obd_count len, void *buf, ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, "filter_ldlm_cb_client", &obd->obd_ldlm_client); - rc = llog_cat_initialize(obd, 1, NULL); + rc = obd_llog_init(obd, obd, 1, NULL, NULL); if (rc) { CERROR("failed to setup llogging subsystems\n"); GOTO(err_post, rc); diff --git a/lustre/ptlrpc/llog_net.c b/lustre/ptlrpc/llog_net.c index 5a16b56c7f842f67d9def817ac92719ff379f536..2a79e1d889636b646588669c4038edf2b1f2aa12 100644 --- a/lustre/ptlrpc/llog_net.c +++ b/lustre/ptlrpc/llog_net.c @@ -73,11 +73,17 @@ int llog_origin_connect(struct llog_ctxt *ctxt, int count, struct llogd_conn_body *req_body; int size[2] = { sizeof(struct ptlrpc_body), sizeof(struct llogd_conn_body) }; - struct inode* inode = ctxt->loc_handle->lgh_file->f_dentry->d_inode; + struct inode *inode; void *handle; int rc, rc1; ENTRY; + LASSERT(ctxt != NULL); + LASSERT(ctxt->loc_handle != NULL); + LASSERT(ctxt->loc_handle->lgh_file != NULL); + LASSERT(ctxt->loc_handle->lgh_file->f_dentry != NULL); + inode = ctxt->loc_handle->lgh_file->f_dentry->d_inode; + if (list_empty(&ctxt->loc_handle->u.chd.chd_head)) { CDEBUG(D_HA, "there is no record related to ctxt %p\n", ctxt); RETURN(0); @@ -93,9 +99,9 @@ int llog_origin_connect(struct llog_ctxt *ctxt, int count, lgr->lgr_hdr.lrh_len = lgr->lgr_tail.lrt_len = sizeof(*lgr); lgr->lgr_hdr.lrh_type = LLOG_GEN_REC; - handle = fsfilt_start_log(ctxt->loc_exp->exp_obd, inode, + handle = fsfilt_start_log(ctxt->loc_exp->exp_obd, inode, FSFILT_OP_CANCEL_UNLINK, NULL, 1); - + if (IS_ERR(handle)) { CERROR("fsfilt_start failed: %ld\n", PTR_ERR(handle)); OBD_FREE(lgr, sizeof(*lgr)); @@ -105,7 +111,7 @@ int llog_origin_connect(struct llog_ctxt *ctxt, int count, lgr->lgr_gen = ctxt->loc_gen; rc = llog_add(ctxt, &lgr->lgr_hdr, NULL, NULL, 1); OBD_FREE(lgr, sizeof(*lgr)); - + rc1 = fsfilt_commit(ctxt->loc_exp->exp_obd, inode, handle, 0); if (rc != 1 || rc1 != 0) { rc = (rc != 1) ? rc : rc1; diff --git a/lustre/ptlrpc/llog_server.c b/lustre/ptlrpc/llog_server.c index 2fa7892b52491ae0d2b3c1e7b5b54a7791976f73..f5ee909bfeaae4f00503ab649d479012ed2a0ee9 100644 --- a/lustre/ptlrpc/llog_server.c +++ b/lustre/ptlrpc/llog_server.c @@ -582,7 +582,6 @@ static int llog_catinfo_deletions(struct obd_device *obd, char *buf, struct lvfs_run_ctxt saved; int size, i, count; struct llog_catid *idarray; - struct llog_logid *id; char name[32] = CATLIST; int rc; struct cb_data data; @@ -594,11 +593,11 @@ static int llog_catinfo_deletions(struct obd_device *obd, char *buf, count = mds->mds_lov_desc.ld_tgt_count; size = sizeof(*idarray) * count; - OBD_ALLOC(idarray, size); + OBD_VMALLOC(idarray, size); if (!idarray) GOTO(release_ctxt, rc = -ENOMEM); - rc = llog_get_cat_list(obd, obd, name, count, idarray); + rc = llog_get_cat_list(obd, obd, name, 0, count, idarray); if (rc) GOTO(out_free, rc); @@ -610,8 +609,7 @@ static int llog_catinfo_deletions(struct obd_device *obd, char *buf, for (i = 0; i < count; i++) { int l, index, uncanceled = 0; - id = &idarray[i].lci_logid; - rc = llog_create(ctxt, &handle, id, NULL); + rc = llog_create(ctxt, &handle, &idarray[i].lci_logid, NULL); if (rc) GOTO(out_pop, rc); rc = llog_init_handle(handle, 0, NULL); @@ -626,8 +624,9 @@ static int llog_catinfo_deletions(struct obd_device *obd, char *buf, l = snprintf(data.out, data.remains, "\n[Catlog ID]: #"LPX64"#"LPX64"#%08x " "[Log Count]: %d\n", - id->lgl_oid, id->lgl_ogr, id->lgl_ogen, - uncanceled); + idarray[i].lci_logid.lgl_oid, + idarray[i].lci_logid.lgl_ogr, + idarray[i].lci_logid.lgl_ogen, uncanceled); data.out += l; data.remains -= l; @@ -642,7 +641,7 @@ static int llog_catinfo_deletions(struct obd_device *obd, char *buf, out_pop: pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL); out_free: - OBD_FREE(idarray, size); + OBD_VFREE(idarray, size); release_ctxt: llog_ctxt_put(ctxt); diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 409cb3de58e707baeb1f9601e5da0ba36def5375..fd80cc94f6e32dc6b8ea98c0a17e475a8e359da1 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -1322,6 +1322,9 @@ test_33a() { # bug 12333, was test_33 cp /etc/hosts $MOUNT2/. || rc=3 echo "ok." + cp /etc/hosts $MOUNT2/ || rc=3 + $LFS getstripe $MOUNT2/hosts + umount -d $MOUNT2 stop fs2ost -f stop fs2mds -f