Whamcloud - gitweb
b=11973
authornathan <nathan>
Thu, 22 Mar 2007 17:58:13 +0000 (17:58 +0000)
committernathan <nathan>
Thu, 22 Mar 2007 17:58:13 +0000 (17:58 +0000)
i=green
atomic copy remote log instead of appending records -- earlier records may
have been modfied, and record count was wrong anyhow.

lustre/include/linux/lvfs.h
lustre/ldlm/ldlm_lib.c
lustre/lvfs/lvfs_linux.c
lustre/mgc/mgc_request.c

index 816925a..085ffb5 100644 (file)
@@ -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);
index 3122ebb..94b7932 100644 (file)
@@ -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);
         }
 
index 71c9ede..53147a4 100644 (file)
@@ -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().
index 4d6733e..36a578b 100644 (file)
@@ -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);
 }