From: nathan Date: Thu, 22 Mar 2007 17:58:13 +0000 (+0000) Subject: b=11973 X-Git-Tag: v1_7_100~230 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=492125c2d1e3e77c5c2ec31e888ce3eb070f2120 b=11973 i=green atomic copy remote log instead of appending records -- earlier records may have been modfied, and record count was wrong anyhow. --- diff --git a/lustre/include/linux/lvfs.h b/lustre/include/linux/lvfs.h index 816925a..085ffb5 100644 --- a/lustre/include/linux/lvfs.h +++ b/lustre/include/linux/lvfs.h @@ -82,6 +82,7 @@ struct lvfs_run_ctxt { struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode, int fix); struct dentry *simple_mknod(struct dentry *dir, char *name, int mode, int fix); +int lustre_rename(struct dentry *dir, char *oldname, char *newname); int lustre_fread(struct file *file, void *buf, int len, loff_t *off); int lustre_fwrite(struct file *file, const void *buf, int len, loff_t *off); int lustre_fsync(struct file *file); diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index 3122ebb..94b7932 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -551,7 +551,7 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) LASSERT_REQSWAB(req, REQ_REC_OFF); str = lustre_msg_string(req->rq_reqmsg, REQ_REC_OFF, sizeof(tgtuuid)-1); if (str == NULL) { - DEBUG_REQ(D_ERROR, req, "bad target UUID for connect"); + DEBUG_REQ(D_ERROR, req, "bad target UUID for connect\n"); GOTO(out, rc = -EINVAL); } @@ -570,7 +570,7 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) if (!target || target->obd_stopping || !target->obd_set_up) { LCONSOLE_ERROR("UUID '%s' is not available " - " for connect (%s)", str, + " for connect (%s)\n", str, !target ? "no target" : (target->obd_stopping ? "stopping" : "not set up")); @@ -593,7 +593,7 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) str = lustre_msg_string(req->rq_reqmsg, REQ_REC_OFF + 1, sizeof(cluuid) - 1); if (str == NULL) { - DEBUG_REQ(D_ERROR, req, "bad client UUID for connect"); + DEBUG_REQ(D_ERROR, req, "bad client UUID for connect\n"); GOTO(out, rc = -EINVAL); } diff --git a/lustre/lvfs/lvfs_linux.c b/lustre/lvfs/lvfs_linux.c index 71c9ede..53147a4 100644 --- a/lustre/lvfs/lvfs_linux.c +++ b/lustre/lvfs/lvfs_linux.c @@ -318,6 +318,37 @@ out_up: } EXPORT_SYMBOL(simple_mkdir); +/* utility to rename a file */ +int lustre_rename(struct dentry *dir, char *oldname, char *newname) +{ + struct dentry *dchild_old, *dchild_new; + int err = 0; + ENTRY; + + ASSERT_KERNEL_CTXT("kernel doing rename outside kernel context\n"); + CDEBUG(D_INODE, "renaming file %.*s to %.*s\n", + (int)strlen(oldname), oldname, (int)strlen(newname), newname); + + dchild_old = ll_lookup_one_len(oldname, dir, strlen(oldname)); + if (IS_ERR(dchild_old)) + RETURN(PTR_ERR(dchild_old)); + + if (!dchild_old->d_inode) + GOTO(put_old, err = -ENOENT); + + dchild_new = ll_lookup_one_len(newname, dir, strlen(newname)); + if (IS_ERR(dchild_new)) + GOTO(put_old, err = PTR_ERR(dchild_new)); + + err = vfs_rename(dir->d_inode, dchild_old, dir->d_inode, dchild_new); + + dput(dchild_new); +put_old: + dput(dchild_old); + RETURN(err); +} +EXPORT_SYMBOL(lustre_rename); + /* * Read a file from within kernel context. Prior to calling this * function we should already have done a push_ctxt(). diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 4d6733e..36a578b 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -914,35 +914,54 @@ static int mgc_copy_handler(struct llog_handle *llh, struct llog_rec_hdr *rec, int rc = 0; ENTRY; - lcfg = (struct lustre_cfg *)cfg_buf; - - /* append new records */ - if (rec->lrh_index >= llog_get_size(local_llh)) { - rc = llog_write_rec(local_llh, &local_rec, NULL, 0, - (void *)cfg_buf, -1); + /* Append all records */ + local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail); + rc = llog_write_rec(local_llh, &local_rec, NULL, 0, + (void *)cfg_buf, -1); - CDEBUG(D_INFO, "idx=%d, rc=%d, len=%d, cmd %x %s %s\n", - rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, - lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1)); - } else { - CDEBUG(D_INFO, "skip idx=%d\n", rec->lrh_index); - } + lcfg = (struct lustre_cfg *)cfg_buf; + CDEBUG(D_INFO, "idx=%d, rc=%d, len=%d, cmd %x %s %s\n", + rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, + lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1)); RETURN(rc); } +/* Copy a remote log locally */ static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt, struct llog_ctxt *lctxt, char *logname) { struct llog_handle *local_llh, *remote_llh; struct obd_uuid *uuid; + char *temp_log; int rc, rc2; ENTRY; + /* Write new log to a temp name, then vfs_rename over logname + upon successful completion. */ + + OBD_ALLOC(temp_log, strlen(logname) + 1); + if (!temp_log) + RETURN(-ENOMEM); + sprintf(temp_log, "%sT", logname); + + /* Make sure there's no old temp log */ + rc = llog_create(lctxt, &local_llh, NULL, temp_log); + if (rc) + GOTO(out, rc); + rc = llog_init_handle(local_llh, LLOG_F_IS_PLAIN, NULL); + if (rc) + GOTO(out, rc); + rc = llog_destroy(local_llh); + llog_free_handle(local_llh); + if (rc) + GOTO(out, rc); + /* open local log */ - rc = llog_create(lctxt, &local_llh, NULL, logname); + rc = llog_create(lctxt, &local_llh, NULL, temp_log); if (rc) - RETURN(rc); + GOTO(out, rc); + /* set the log header uuid for fun */ OBD_ALLOC_PTR(uuid); obd_str2uuid(uuid, logname); @@ -951,9 +970,6 @@ static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt, if (rc) GOTO(out_closel, rc); - /* FIXME write new log to a temp name, then vfs_rename over logname - upon successful completion. */ - /* open remote log */ rc = llog_create(rctxt, &remote_llh, NULL, logname); if (rc) @@ -962,6 +978,7 @@ static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt, if (rc) GOTO(out_closer, rc); + /* Copy remote log */ rc = llog_process(remote_llh, mgc_copy_handler,(void *)local_llh, NULL); out_closer: @@ -973,7 +990,19 @@ out_closel: if (!rc) rc = rc2; + /* We've copied the remote log to the local temp log, now + replace the old local log with the temp log. */ + if (!rc) { + struct client_obd *cli = &obd->u.cli; + LASSERT(cli); + LASSERT(cli->cl_mgc_configs_dir); + rc = lustre_rename(cli->cl_mgc_configs_dir, temp_log, logname); + } CDEBUG(D_MGC, "Copied remote log %s (%d)\n", logname, rc); +out: + if (rc) + CERROR("Failed to copy remote log %s (%d)\n", logname, rc); + OBD_FREE(temp_log, strlen(logname) + 1); RETURN(rc); }