Whamcloud - gitweb
LU-2059 llog: MGC to use OSD API for backup logs 49/5049/19
authorMikhail Pershin <mike.pershin@intel.com>
Sun, 3 Mar 2013 20:06:41 +0000 (00:06 +0400)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 23 Jul 2013 05:01:38 +0000 (05:01 +0000)
MGC uses lvfs API to access local llogs blocking removal of old code

- MGS is converted to use OSD API for local llogs
- llog_is_empty() and llog_backup() are introduced
- initial OSD start initialize run ctxt so llog can use it too
- shrink dcache after initial scrub in osd-ldiskfs to avoid holding
  data of unlinked objects until umount.

Signed-off-by: Mikhail Pershin <mike.pershin@intel.com>
Change-Id: I137e38abb0e93c12406c6610c0922f4294e67290
Reviewed-on: http://review.whamcloud.com/5049
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
13 files changed:
lustre/include/dt_object.h
lustre/include/lustre_log.h
lustre/include/obd.h
lustre/mgc/libmgc.c
lustre/mgc/mgc_request.c
lustre/mgs/mgs_llog.c
lustre/obdclass/llog.c
lustre/obdclass/local_storage.c
lustre/obdclass/local_storage.h
lustre/obdclass/lu_object.c
lustre/obdclass/obd_mount.c
lustre/obdclass/obd_mount_server.c
lustre/osd-ldiskfs/osd_scrub.c

index fb81d4b..477433f 100644 (file)
@@ -692,7 +692,7 @@ struct local_oid_storage {
        struct dt_object *los_obj;
 
        /* data used to generate new fids */
-       struct mutex     los_id_lock;
+       struct mutex      los_id_lock;
        __u64             los_seq;
        __u32             los_last_oid;
 };
index e4c4bcf..708d7c8 100644 (file)
@@ -144,7 +144,11 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
              struct llog_handle **lgh, struct llog_logid *logid,
              char *name, enum llog_open_param open_param);
 int llog_close(const struct lu_env *env, struct llog_handle *cathandle);
-int llog_get_size(struct llog_handle *loghandle);
+int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
+                 char *name);
+int llog_backup(const struct lu_env *env, struct obd_device *obd,
+               struct llog_ctxt *ctxt, struct llog_ctxt *bak_ctxt,
+               char *name, char *backup);
 
 /* llog_process flags */
 #define LLOG_FLAG_NODEAMON 0x0001
@@ -390,6 +394,13 @@ static inline int llog_data_len(int len)
         return cfs_size_round(len);
 }
 
+static inline int llog_get_size(struct llog_handle *loghandle)
+{
+       if (loghandle && loghandle->lgh_hdr)
+               return loghandle->lgh_hdr->llh_count;
+       return 0;
+}
+
 static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt)
 {
         cfs_atomic_inc(&ctxt->loc_refcount);
index 73805a4..e9150ae 100644 (file)
@@ -411,8 +411,8 @@ struct client_obd {
 
         /* mgc datastruct */
        struct semaphore         cl_mgc_sem;
-        struct vfsmount         *cl_mgc_vfsmnt;
-        struct dentry           *cl_mgc_configs_dir;
+       struct local_oid_storage *cl_mgc_los;
+       struct dt_object        *cl_mgc_configs_dir;
         cfs_atomic_t             cl_mgc_refcount;
         struct obd_export       *cl_mgc_mgsexp;
 
index ff98ece..b156ebb 100644 (file)
@@ -99,12 +99,9 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
 
 static int mgc_cleanup(struct obd_device *obd)
 {
-        struct client_obd *cli = &obd->u.cli;
         int rc;
         ENTRY;
 
-        LASSERT(cli->cl_mgc_vfsmnt == NULL);
-
         ptlrpcd_decref();
 
         rc = client_obd_cleanup(obd);
index cd77628..e503c1b 100644 (file)
 #define DEBUG_SUBSYSTEM S_MGC
 #define D_MGC D_CONFIG /*|D_WARNING*/
 
-#ifdef __KERNEL__
-# include <linux/module.h>
-# include <linux/pagemap.h>
-# include <linux/miscdevice.h>
-# include <linux/init.h>
-#else
-# include <liblustre.h>
-#endif
-
+#include <linux/module.h>
 #include <obd_class.h>
 #include <lustre_dlm.h>
 #include <lprocfs_status.h>
 #include <lustre_log.h>
-#include <lustre_fsfilt.h>
 #include <lustre_disk.h>
+#include <dt_object.h>
+
 #include "mgc_internal.h"
 
 static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
@@ -602,101 +595,191 @@ static void mgc_requeue_add(struct config_llog_data *cld)
 }
 
 /********************** class fns **********************/
+static int mgc_local_llog_init(const struct lu_env *env,
+                              struct obd_device *obd,
+                              struct obd_device *disk)
+{
+       struct llog_ctxt        *ctxt;
+       int                      rc;
+
+       ENTRY;
+
+       rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_ORIG_CTXT, disk,
+                       &llog_osd_ops);
+       if (rc)
+               RETURN(rc);
+
+       ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+       LASSERT(ctxt);
+       ctxt->loc_dir = obd->u.cli.cl_mgc_configs_dir;
+       llog_ctxt_put(ctxt);
 
-static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb,
-                        struct vfsmount *mnt)
+       RETURN(0);
+}
+
+static int mgc_local_llog_fini(const struct lu_env *env,
+                              struct obd_device *obd)
 {
-        struct lvfs_run_ctxt saved;
-        struct lustre_sb_info *lsi = s2lsi(sb);
-        struct client_obd *cli = &obd->u.cli;
-        struct dentry *dentry;
-        char *label;
-        int err = 0;
-        ENTRY;
+       struct llog_ctxt *ctxt;
+
+       ENTRY;
+
+       ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+       llog_cleanup(env, ctxt);
+
+       RETURN(0);
+}
+
+static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb)
+{
+       struct lustre_sb_info   *lsi = s2lsi(sb);
+       struct client_obd       *cli = &obd->u.cli;
+       struct lu_fid            rfid, fid;
+       struct dt_object        *root, *dto;
+       struct lu_env           *env;
+       int                      rc = 0;
+
+       ENTRY;
 
-        LASSERT(lsi);
-        LASSERT(lsi->lsi_srv_mnt == mnt);
+       LASSERT(lsi);
+       LASSERT(lsi->lsi_dt_dev);
 
-        /* The mgc fs exclusion sem. Only one fs can be setup at a time. */
+       OBD_ALLOC_PTR(env);
+       if (env == NULL)
+               RETURN(-ENOMEM);
+
+       /* The mgc fs exclusion sem. Only one fs can be setup at a time. */
        down(&cli->cl_mgc_sem);
 
-        cfs_cleanup_group_info();
+       cfs_cleanup_group_info();
 
-       obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype);
-        if (IS_ERR(obd->obd_fsops)) {
-               up(&cli->cl_mgc_sem);
-               CERROR("%s: No fstype %s: rc = %ld\n", lsi->lsi_fstype,
-                      obd->obd_name, PTR_ERR(obd->obd_fsops));
-                RETURN(PTR_ERR(obd->obd_fsops));
-        }
+       /* Setup the configs dir */
+       rc = lu_env_init(env, LCT_MG_THREAD);
+       if (rc)
+               GOTO(out_err, rc);
 
-        cli->cl_mgc_vfsmnt = mnt;
-        err = fsfilt_setup(obd, mnt->mnt_sb);
-        if (err)
-                GOTO(err_ops, err);
-
-        OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
-        obd->obd_lvfs_ctxt.pwdmnt = mnt;
-        obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
-        obd->obd_lvfs_ctxt.fs = get_ds();
-
-        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs),
-                                   strlen(MOUNT_CONFIGS_DIR));
-        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        if (IS_ERR(dentry)) {
-                err = PTR_ERR(dentry);
-                CERROR("cannot lookup %s directory: rc = %d\n",
-                       MOUNT_CONFIGS_DIR, err);
-                GOTO(err_ops, err);
-        }
-        cli->cl_mgc_configs_dir = dentry;
+       fid.f_seq = FID_SEQ_LOCAL_NAME;
+       fid.f_oid = 1;
+       fid.f_ver = 0;
+       rc = local_oid_storage_init(env, lsi->lsi_dt_dev, &fid,
+                                   &cli->cl_mgc_los);
+       if (rc)
+               GOTO(out_env, rc);
 
-        /* We take an obd ref to insure that we can't get to mgc_cleanup
-           without calling mgc_fs_cleanup first. */
-        class_incref(obd, "mgc_fs", obd);
+       rc = dt_root_get(env, lsi->lsi_dt_dev, &rfid);
+       if (rc)
+               GOTO(out_env, rc);
 
-        label = fsfilt_get_label(obd, mnt->mnt_sb);
-        if (label)
-                CDEBUG(D_MGC, "MGC using disk labelled=%s\n", label);
+       root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid,
+                           &cli->cl_mgc_los->los_dev->dd_lu_dev);
+       if (unlikely(IS_ERR(root)))
+               GOTO(out_los, rc = PTR_ERR(root));
 
-        /* We keep the cl_mgc_sem until mgc_fs_cleanup */
-        RETURN(0);
+       dto = local_file_find_or_create(env, cli->cl_mgc_los, root,
+                                       MOUNT_CONFIGS_DIR,
+                                       S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
+       lu_object_put_nocache(env, &root->do_lu);
+       if (IS_ERR(dto))
+               GOTO(out_los, rc = PTR_ERR(dto));
 
-err_ops:
-        fsfilt_put_ops(obd->obd_fsops);
-        obd->obd_fsops = NULL;
-        cli->cl_mgc_vfsmnt = NULL;
-       up(&cli->cl_mgc_sem);
-        RETURN(err);
+       cli->cl_mgc_configs_dir = dto;
+
+       LASSERT(lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt);
+       rc = mgc_local_llog_init(env, obd, lsi->lsi_osd_exp->exp_obd);
+       if (rc)
+               GOTO(out_llog, rc);
+
+       /* We take an obd ref to insure that we can't get to mgc_cleanup
+        * without calling mgc_fs_cleanup first. */
+       class_incref(obd, "mgc_fs", obd);
+
+       /* We keep the cl_mgc_sem until mgc_fs_cleanup */
+       EXIT;
+out_llog:
+       if (rc) {
+               lu_object_put(env, &cli->cl_mgc_configs_dir->do_lu);
+               cli->cl_mgc_configs_dir = NULL;
+       }
+out_los:
+       if (rc < 0) {
+               local_oid_storage_fini(env, cli->cl_mgc_los);
+               cli->cl_mgc_los = NULL;
+               up(&cli->cl_mgc_sem);
+       }
+out_env:
+       lu_env_fini(env);
+out_err:
+       OBD_FREE_PTR(env);
+       return rc;
 }
 
 static int mgc_fs_cleanup(struct obd_device *obd)
 {
-        struct client_obd *cli = &obd->u.cli;
-        int rc = 0;
-        ENTRY;
+       struct lu_env            env;
+       struct client_obd       *cli = &obd->u.cli;
+       int                      rc;
 
-        LASSERT(cli->cl_mgc_vfsmnt != NULL);
+       ENTRY;
 
-        if (cli->cl_mgc_configs_dir != NULL) {
-                struct lvfs_run_ctxt saved;
-                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                l_dput(cli->cl_mgc_configs_dir);
-                cli->cl_mgc_configs_dir = NULL;
-                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                class_decref(obd, "mgc_fs", obd);
-        }
+       LASSERT(cli->cl_mgc_los != NULL);
 
-        cli->cl_mgc_vfsmnt = NULL;
-        if (obd->obd_fsops)
-                fsfilt_put_ops(obd->obd_fsops);
+       rc = lu_env_init(&env, LCT_MG_THREAD);
+       if (rc)
+               GOTO(unlock, rc);
+
+       mgc_local_llog_fini(&env, obd);
+
+       lu_object_put_nocache(&env, &cli->cl_mgc_configs_dir->do_lu);
+       cli->cl_mgc_configs_dir = NULL;
+
+       local_oid_storage_fini(&env, cli->cl_mgc_los);
+       cli->cl_mgc_los = NULL;
+       lu_env_fini(&env);
 
+unlock:
+       class_decref(obd, "mgc_fs", obd);
        up(&cli->cl_mgc_sem);
 
-        RETURN(rc);
+       RETURN(0);
+}
+
+static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd)
+{
+       struct llog_ctxt        *ctxt;
+       int                      rc;
+
+       ENTRY;
+
+       /* setup only remote ctxt, the local disk context is switched per each
+        * filesystem during mgc_fs_setup() */
+       rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_REPL_CTXT, obd,
+                       &llog_client_ops);
+       if (rc)
+               RETURN(rc);
+
+       ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
+       LASSERT(ctxt);
+
+       llog_initiator_connect(ctxt);
+       llog_ctxt_put(ctxt);
+
+       RETURN(0);
 }
 
+static int mgc_llog_fini(const struct lu_env *env, struct obd_device *obd)
+{
+       struct llog_ctxt *ctxt;
+
+       ENTRY;
+
+       ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
+       if (ctxt)
+               llog_cleanup(env, ctxt);
+
+       RETURN(0);
+}
+
+
 static cfs_atomic_t mgc_count = CFS_ATOMIC_INIT(0);
 static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
 {
@@ -721,7 +804,7 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
                         }
                 }
                 obd_cleanup_client_import(obd);
-                rc = obd_llog_finish(obd, 0);
+               rc = mgc_llog_fini(NULL, obd);
                 if (rc != 0)
                         CERROR("failed to cleanup llogging subsystems\n");
                 break;
@@ -731,12 +814,9 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
 
 static int mgc_cleanup(struct obd_device *obd)
 {
-        struct client_obd *cli = &obd->u.cli;
         int rc;
         ENTRY;
 
-        LASSERT(cli->cl_mgc_vfsmnt == NULL);
-
         /* COMPAT_146 - old config logs may have added profiles we don't
            know about */
         if (obd->obd_type->typ_refcnt <= 1)
@@ -762,7 +842,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
         if (rc)
                 GOTO(err_decref, rc);
 
-        rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL);
+       rc = mgc_llog_init(NULL, obd);
         if (rc) {
                 CERROR("failed to setup llogging subsystems\n");
                 GOTO(err_cleanup, rc);
@@ -1045,27 +1125,21 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp,
                 rc =  mgc_target_register(exp, mti);
                 RETURN(rc);
         }
-        if (KEY_IS(KEY_SET_FS)) {
-                struct super_block *sb = (struct super_block *)val;
-                struct lustre_sb_info *lsi;
-                if (vallen != sizeof(struct super_block))
-                        RETURN(-EINVAL);
-                lsi = s2lsi(sb);
-                rc = mgc_fs_setup(exp->exp_obd, sb, lsi->lsi_srv_mnt);
-                if (rc) {
-                        CERROR("set_fs got %d\n", rc);
-                }
-                RETURN(rc);
-        }
-        if (KEY_IS(KEY_CLEAR_FS)) {
-                if (vallen != 0)
-                        RETURN(-EINVAL);
-                rc = mgc_fs_cleanup(exp->exp_obd);
-                if (rc) {
-                        CERROR("clear_fs got %d\n", rc);
-                }
-                RETURN(rc);
-        }
+       if (KEY_IS(KEY_SET_FS)) {
+               struct super_block *sb = (struct super_block *)val;
+
+               if (vallen != sizeof(struct super_block))
+                       RETURN(-EINVAL);
+
+               rc = mgc_fs_setup(exp->exp_obd, sb);
+               RETURN(rc);
+       }
+       if (KEY_IS(KEY_CLEAR_FS)) {
+               if (vallen != 0)
+                       RETURN(-EINVAL);
+               rc = mgc_fs_cleanup(exp->exp_obd);
+               RETURN(rc);
+       }
         if (KEY_IS(KEY_SET_INFO)) {
                 struct mgs_send_param *msp;
 
@@ -1181,58 +1255,6 @@ static int mgc_import_event(struct obd_device *obd,
         RETURN(rc);
 }
 
-static int mgc_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
-                         struct obd_device *tgt, int *index)
-{
-        struct llog_ctxt *ctxt;
-        int rc;
-        ENTRY;
-
-        LASSERT(olg == &obd->obd_olg);
-
-#ifdef HAVE_LDISKFS_OSD
-       rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_ORIG_CTXT, tgt,
-                       &llog_lvfs_ops);
-       if (rc)
-               RETURN(rc);
-#endif
-
-       rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_REPL_CTXT, tgt,
-                       &llog_client_ops);
-       if (rc)
-               GOTO(out, rc);
-
-       ctxt = llog_group_get_ctxt(olg, LLOG_CONFIG_REPL_CTXT);
-       if (!ctxt)
-               GOTO(out, rc = -ENODEV);
-
-       llog_initiator_connect(ctxt);
-       llog_ctxt_put(ctxt);
-
-       RETURN(0);
-out:
-       ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
-       if (ctxt)
-               llog_cleanup(NULL, ctxt);
-        RETURN(rc);
-}
-
-static int mgc_llog_finish(struct obd_device *obd, int count)
-{
-       struct llog_ctxt *ctxt;
-
-       ENTRY;
-
-       ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
-       if (ctxt)
-               llog_cleanup(NULL, ctxt);
-
-       ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
-       if (ctxt)
-               llog_cleanup(NULL, ctxt);
-       RETURN(0);
-}
-
 enum {
        CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT),
         CONFIG_READ_NRPAGES      = 4
@@ -1587,229 +1609,155 @@ out:
        return rc;
 }
 
-#ifdef HAVE_LDISKFS_OSD
-
-/*
- * XXX: mgc_copy_llog() does not support osd-based llogs yet
- */
-
-/* identical to mgs_log_is_empty */
-static int mgc_llog_is_empty(struct obd_device *obd, struct llog_ctxt *ctxt,
-                            char *name)
-{
-       struct lvfs_run_ctxt     saved;
-       struct llog_handle      *llh;
-       int                      rc = 0;
-
-       push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-       rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
-       if (rc == 0) {
-               rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
-               if (rc == 0)
-                       rc = llog_get_size(llh);
-               llog_close(NULL, llh);
-       } else if (rc == -ENOENT) {
-               rc = 0;
-       }
-       pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-       /* header is record 1 */
-       return (rc <= 1);
-}
-
 /* Copy a remote log locally */
-static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt,
-                         struct llog_ctxt *lctxt, char *logname)
+static int mgc_llog_local_copy(const struct lu_env *env,
+                              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;
+       char    *temp_log;
+       int      rc;
 
-        /* Write new log to a temp name, then vfs_rename over logname
-           upon successful completion. */
+       ENTRY;
 
-        OBD_ALLOC(temp_log, strlen(logname) + 1);
-        if (!temp_log)
-                RETURN(-ENOMEM);
-        sprintf(temp_log, "%sT", logname);
+       /*
+        * - copy it to backup using llog_backup()
+        * - copy remote llog to logname using llog_backup()
+        * - if failed then move bakup to logname again
+        */
 
-        /* Make sure there's no old temp log */
-       rc = llog_erase(NULL, lctxt, NULL, temp_log);
-       if (rc < 0 && rc != -ENOENT)
-               GOTO(out, rc);
+       OBD_ALLOC(temp_log, strlen(logname) + 1);
+       if (!temp_log)
+               RETURN(-ENOMEM);
+       sprintf(temp_log, "%sT", logname);
 
-       /* open local log */
-       rc = llog_open_create(NULL, lctxt, &local_llh, NULL, temp_log);
-       if (rc)
+       /* make a copy of local llog at first */
+       rc = llog_backup(env, obd, lctxt, lctxt, logname, temp_log);
+       if (rc < 0 && rc != -ENOENT)
                GOTO(out, rc);
-
-       /* set the log header uuid for fun */
-       OBD_ALLOC_PTR(uuid);
-       obd_str2uuid(uuid, logname);
-       rc = llog_init_handle(NULL, local_llh, LLOG_F_IS_PLAIN, uuid);
-       OBD_FREE_PTR(uuid);
-       if (rc)
-               GOTO(out_closel, rc);
-
-       /* open remote log */
-       rc = llog_open(NULL, rctxt, &remote_llh, NULL, logname,
-                      LLOG_OPEN_EXISTS);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       rc = 0;
-               GOTO(out_closel, rc);
-       }
-
-       rc = llog_init_handle(NULL, remote_llh, LLOG_F_IS_PLAIN, NULL);
-       if (rc)
-               GOTO(out_closer, rc);
-
-       /* Copy remote log */
-       rc = llog_process(NULL, remote_llh, llog_copy_handler,
-                         (void *)local_llh, NULL);
-
-out_closer:
-       rc2 = llog_close(NULL, remote_llh);
-       if (!rc)
-               rc = rc2;
-out_closel:
-       rc2 = llog_close(NULL, local_llh);
-        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 == 0) {
-                struct client_obd *cli = &obd->u.cli;
-
-                LASSERT(cli);
-                LASSERT(cli->cl_mgc_configs_dir);
-                rc = lustre_rename(cli->cl_mgc_configs_dir, cli->cl_mgc_vfsmnt,
-                                   temp_log, logname);
-        }
-        CDEBUG(D_MGC, "Copied remote log %s (%d)\n", logname, rc);
+       /* copy remote llog to the local copy */
+       rc = llog_backup(env, obd, rctxt, lctxt, logname, logname);
+       if (rc == -ENOENT) {
+               /* no remote llog, delete local one too */
+               llog_erase(env, lctxt, NULL, logname);
+       } else if (rc < 0) {
+               /* error during backup, get local one back from the copy */
+               llog_backup(env, obd, lctxt, lctxt, temp_log, logname);
 out:
-        if (rc)
-                CERROR("Failed to copy remote log %s (%d)\n", logname, rc);
-        OBD_FREE(temp_log, strlen(logname) + 1);
-        RETURN(rc);
+               CERROR("%s: failed to copy remote log %s: rc = %d\n",
+                      obd->obd_name, logname, rc);
+       }
+       llog_erase(env, lctxt, NULL, temp_log);
+       OBD_FREE(temp_log, strlen(logname) + 1);
+       return rc;
 }
-#endif
 
 /* local_only means it cannot get remote llogs */
 static int mgc_process_cfg_log(struct obd_device *mgc,
-                               struct config_llog_data *cld,
-                               int local_only)
+                              struct config_llog_data *cld, int local_only)
 {
-        struct llog_ctxt *ctxt, *lctxt = NULL;
-#ifdef HAVE_LDISKFS_OSD
-        struct client_obd *cli = &mgc->u.cli;
-#endif
-        struct lvfs_run_ctxt *saved_ctxt;
-        struct lustre_sb_info *lsi = NULL;
-        int rc = 0, must_pop = 0;
-        bool sptlrpc_started = false;
+       struct llog_ctxt        *ctxt, *lctxt = NULL;
+       struct client_obd       *cli = &mgc->u.cli;
+       struct lustre_sb_info   *lsi = NULL;
+       int                      rc = 0;
+       bool                     sptlrpc_started = false;
+       struct lu_env           *env;
 
-        ENTRY;
+       ENTRY;
 
-        LASSERT(cld);
+       LASSERT(cld);
        LASSERT(mutex_is_locked(&cld->cld_lock));
 
-        /*
-         * local copy of sptlrpc log is controlled elsewhere, don't try to
-         * read it up here.
-         */
-        if (cld_is_sptlrpc(cld) && local_only)
-                RETURN(0);
-
-        if (cld->cld_cfg.cfg_sb)
-                lsi = s2lsi(cld->cld_cfg.cfg_sb);
-
-        ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT);
-        if (!ctxt) {
-                CERROR("missing llog context\n");
-                RETURN(-EINVAL);
-        }
+       /*
+        * local copy of sptlrpc log is controlled elsewhere, don't try to
+        * read it up here.
+        */
+       if (cld_is_sptlrpc(cld) && local_only)
+               RETURN(0);
 
-        OBD_ALLOC_PTR(saved_ctxt);
-        if (saved_ctxt == NULL)
-                RETURN(-ENOMEM);
+       if (cld->cld_cfg.cfg_sb)
+               lsi = s2lsi(cld->cld_cfg.cfg_sb);
 
-        lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT);
+       OBD_ALLOC_PTR(env);
+       if (env == NULL)
+               RETURN(-ENOMEM);
 
-#ifdef HAVE_LDISKFS_OSD
-       /*
-        * XXX: at the moment mgc_copy_llog() works with lvfs-based llogs
-        */
-        /* Copy the setup log locally if we can. Don't mess around if we're
-           running an MGS though (logs are already local). */
-       if (lctxt && lsi && IS_SERVER(lsi) &&
-            (lsi->lsi_srv_mnt == cli->cl_mgc_vfsmnt) &&
-           !IS_MGS(lsi) && lsi->lsi_srv_mnt) {
-                push_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL);
-                must_pop++;
-                if (!local_only)
-                        /* Only try to copy log if we have the lock. */
-                        rc = mgc_copy_llog(mgc, ctxt, lctxt, cld->cld_logname);
-                if (local_only || rc) {
-                        if (mgc_llog_is_empty(mgc, lctxt, cld->cld_logname)) {
-                                LCONSOLE_ERROR_MSG(0x13a, "Failed to get MGS "
-                                                   "log %s and no local copy."
-                                                   "\n", cld->cld_logname);
-                                GOTO(out_pop, rc = -ENOTCONN);
-                        }
-                        CDEBUG(D_MGC, "Failed to get MGS log %s, using local "
-                               "copy for now, will try to update later.\n",
-                               cld->cld_logname);
-                }
-                /* Now, whether we copied or not, start using the local llog.
-                   If we failed to copy, we'll start using whatever the old
-                   log has. */
-                llog_ctxt_put(ctxt);
-                ctxt = lctxt;
-                lctxt = NULL;
-       } else
-#endif
-               if (local_only) { /* no local log at client side */
-                GOTO(out_pop, rc = -EIO);
-        }
+       rc = lu_env_init(env, LCT_MG_THREAD);
+       if (rc)
+               GOTO(out_free, rc);
+
+       ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT);
+       LASSERT(ctxt);
+
+       lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT);
+
+       /* Copy the setup log locally if we can. Don't mess around if we're
+        * running an MGS though (logs are already local). */
+       if (lctxt && lsi && IS_SERVER(lsi) && !IS_MGS(lsi) &&
+           cli->cl_mgc_configs_dir != NULL &&
+           lu2dt_dev(cli->cl_mgc_configs_dir->do_lu.lo_dev) ==
+           lsi->lsi_dt_dev) {
+               if (!local_only)
+                       /* Only try to copy log if we have the lock. */
+                       rc = mgc_llog_local_copy(env, mgc, ctxt, lctxt,
+                                                cld->cld_logname);
+               if (local_only || rc) {
+                       if (llog_is_empty(env, lctxt, cld->cld_logname)) {
+                               LCONSOLE_ERROR_MSG(0x13a, "Failed to get MGS "
+                                                  "log %s and no local copy."
+                                                  "\n", cld->cld_logname);
+                               GOTO(out_pop, rc = -ENOTCONN);
+                       }
+                       CDEBUG(D_MGC, "Failed to get MGS log %s, using local "
+                              "copy for now, will try to update later.\n",
+                              cld->cld_logname);
+               }
+               /* Now, whether we copied or not, start using the local llog.
+                * If we failed to copy, we'll start using whatever the old
+                * log has. */
+               llog_ctxt_put(ctxt);
+               ctxt = lctxt;
+               lctxt = NULL;
+       } else {
+               if (local_only) /* no local log at client side */
+                       GOTO(out_pop, rc = -EIO);
+       }
 
-        if (cld_is_sptlrpc(cld)) {
-                sptlrpc_conf_log_update_begin(cld->cld_logname);
-                sptlrpc_started = true;
-        }
+       if (cld_is_sptlrpc(cld)) {
+               sptlrpc_conf_log_update_begin(cld->cld_logname);
+               sptlrpc_started = true;
+       }
 
-        /* logname and instance info should be the same, so use our
-           copy of the instance for the update.  The cfg_last_idx will
-           be updated here. */
-       rc = class_config_parse_llog(NULL, ctxt, cld->cld_logname,
+       /* logname and instance info should be the same, so use our
+        * copy of the instance for the update.  The cfg_last_idx will
+        * be updated here. */
+       rc = class_config_parse_llog(env, ctxt, cld->cld_logname,
                                     &cld->cld_cfg);
-        EXIT;
+       EXIT;
 
 out_pop:
-        llog_ctxt_put(ctxt);
-        if (lctxt)
-                llog_ctxt_put(lctxt);
-        if (must_pop)
-                pop_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL);
+       __llog_ctxt_put(env, ctxt);
+       if (lctxt)
+               __llog_ctxt_put(env, lctxt);
 
-        OBD_FREE_PTR(saved_ctxt);
-        /*
-         * update settings on existing OBDs. doing it inside
-         * of llog_process_lock so no device is attaching/detaching
-         * in parallel.
-         * the logname must be <fsname>-sptlrpc
-         */
-        if (sptlrpc_started) {
-                LASSERT(cld_is_sptlrpc(cld));
-                sptlrpc_conf_log_update_end(cld->cld_logname);
-                class_notify_sptlrpc_conf(cld->cld_logname,
-                                          strlen(cld->cld_logname) -
-                                          strlen("-sptlrpc"));
-        }
+       /*
+        * update settings on existing OBDs. doing it inside
+        * of llog_process_lock so no device is attaching/detaching
+        * in parallel.
+        * the logname must be <fsname>-sptlrpc
+        */
+       if (sptlrpc_started) {
+               LASSERT(cld_is_sptlrpc(cld));
+               sptlrpc_conf_log_update_end(cld->cld_logname);
+               class_notify_sptlrpc_conf(cld->cld_logname,
+                                         strlen(cld->cld_logname) -
+                                         strlen("-sptlrpc"));
+       }
 
-        RETURN(rc);
+       lu_env_fini(env);
+out_free:
+       OBD_FREE_PTR(env);
+       return rc;
 }
 
 /** Get a config log from the MGS and process it.
@@ -1998,8 +1946,6 @@ struct obd_ops mgc_obd_ops = {
         .o_set_info_async = mgc_set_info_async,
         .o_get_info       = mgc_get_info,
         .o_import_event = mgc_import_event,
-        .o_llog_init    = mgc_llog_init,
-        .o_llog_finish  = mgc_llog_finish,
         .o_process_config = mgc_process_config,
 };
 
index d84d3fe..baaec4a 100644 (file)
@@ -947,7 +947,6 @@ static int mgs_replace_handler(const struct lu_env *env,
                               struct llog_rec_hdr *rec,
                               void *data)
 {
-       struct llog_rec_hdr local_rec = *rec;
        struct mgs_replace_uuid_lookup *mrul;
        struct lustre_cfg *lcfg = REC_DATA(rec);
        int cfg_len = REC_DATA_LEN(rec);
@@ -994,9 +993,7 @@ static int mgs_replace_handler(const struct lu_env *env,
                RETURN(0);
 copy_out:
        /* Record is placed in temporary llog as is */
-       local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
-       rc = llog_write(env, mrul->temp_llh, &local_rec, NULL, 0,
-                        (void *)lcfg, -1);
+       rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
 
        CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
               rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
@@ -1010,83 +1007,20 @@ skip_out:
        RETURN(rc);
 }
 
-static int mgs_backup_llog(const struct lu_env *env,
-                          struct obd_device *mgs,
-                          char *fsname, char *backup)
+static int mgs_log_is_empty(const struct lu_env *env,
+                           struct mgs_device *mgs, char *name)
 {
-       struct obd_uuid *uuid;
-       struct llog_handle *orig_llh, *bak_llh;
-       struct llog_ctxt *lctxt;
-       int rc, rc2;
-       ENTRY;
-
-       lctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
-       if (!lctxt) {
-               CERROR("%s: missing llog context\n", mgs->obd_name);
-               GOTO(out, rc = -EINVAL);
-       }
-
-       /* Make sure there's no old backup log */
-       rc = llog_erase(env, lctxt, NULL, backup);
-       if (rc < 0 && rc != -ENOENT)
-               GOTO(out_put, rc);
-
-       /* open backup log */
-       rc = llog_open_create(env, lctxt, &bak_llh, NULL, backup);
-       if (rc) {
-               CERROR("%s: backup logfile open %s: rc = %d\n",
-                      mgs->obd_name, backup, rc);
-               GOTO(out_put, rc);
-       }
-
-       /* set the log header uuid */
-       OBD_ALLOC_PTR(uuid);
-       if (uuid == NULL)
-                GOTO(out_put, rc = -ENOMEM);
-       obd_str2uuid(uuid, backup);
-       rc = llog_init_handle(env, bak_llh, LLOG_F_IS_PLAIN, uuid);
-       OBD_FREE_PTR(uuid);
-       if (rc)
-               GOTO(out_close1, rc);
-
-       /* open original log */
-       rc = llog_open(env, lctxt, &orig_llh, NULL, fsname,
-                      LLOG_OPEN_EXISTS);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       rc = 0;
-               GOTO(out_close1, rc);
-       }
-
-       rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL);
-       if (rc)
-               GOTO(out_close2, rc);
+       struct llog_ctxt        *ctxt;
+       int                      rc;
 
-       /* Copy remote log */
-       rc = llog_process(env, orig_llh, llog_copy_handler,
-                         (void *)bak_llh, NULL);
+       ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
+       LASSERT(ctxt != NULL);
 
-out_close2:
-       rc2 = llog_close(env, orig_llh);
-       if (!rc)
-               rc = rc2;
-out_close1:
-       rc2 = llog_close(env, bak_llh);
-        if (!rc)
-                rc = rc2;
-out_put:
-       if (lctxt)
-               llog_ctxt_put(lctxt);
-out:
-       if (rc)
-               CERROR("%s: Failed to backup log %s: rc = %d\n",
-                      mgs->obd_name, fsname, rc);
-       RETURN(rc);
+       rc = llog_is_empty(env, ctxt, name);
+       llog_ctxt_put(ctxt);
+       return rc;
 }
 
-static int mgs_log_is_empty(const struct lu_env *env, struct mgs_device *mgs,
-                           char *name);
-
 static int mgs_replace_nids_log(const struct lu_env *env,
                                struct obd_device *mgs, struct fs_db *fsdb,
                                char *logname, char *devname, char *nids)
@@ -1116,19 +1050,19 @@ static int mgs_replace_nids_log(const struct lu_env *env,
 
        sprintf(backup, "%s.bak", logname);
 
-       rc = mgs_backup_llog(env, mgs, logname, backup);
-       if (rc < 0) {
+       rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
+       if (rc == 0) {
+               /* Now erase original log file. Connections are not allowed.
+                  Backup is already saved */
+               rc = llog_erase(env, ctxt, NULL, logname);
+               if (rc < 0)
+                       GOTO(out_free, rc);
+       } else if (rc != -ENOENT) {
                CERROR("%s: can't make backup for %s: rc = %d\n",
                       mgs->obd_name, logname, rc);
                GOTO(out_free,rc);
        }
 
-       /* Now erase original log file. Connections are not allowed.
-          Backup is already saved */
-       rc = llog_erase(env, ctxt, NULL, logname);
-       if (rc < 0 && rc != -ENOENT)
-               GOTO(out_free, rc);
-
        /* open local log */
        rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
        if (rc)
@@ -1177,7 +1111,8 @@ out_restore:
        if (rc) {
                CERROR("%s: llog should be restored: rc = %d\n",
                       mgs->obd_name, rc);
-               rc2 = mgs_backup_llog(env, mgs, backup, logname);
+               rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
+                                 logname);
                if (rc2 < 0)
                        CERROR("%s: can't restore backup %s: rc = %d\n",
                               mgs->obd_name, logname, rc2);
@@ -1468,35 +1403,6 @@ static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
        return rc;
 }
 
-static int mgs_log_is_empty(const struct lu_env *env,
-                           struct mgs_device *mgs, char *name)
-{
-        struct llog_handle *llh;
-        struct llog_ctxt *ctxt;
-        int rc = 0;
-
-       ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
-        LASSERT(ctxt != NULL);
-       rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       rc = 0;
-               GOTO(out_ctxt, rc);
-       }
-
-       rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
-       if (rc)
-               GOTO(out_close, rc);
-       rc = llog_get_size(llh);
-
-out_close:
-       llog_close(env, llh);
-out_ctxt:
-       llog_ctxt_put(ctxt);
-       /* header is record 1 */
-       return (rc <= 1);
-}
-
 /******************** config "macros" *********************/
 
 /* write an lcfg directly into a log (with markers) */
@@ -4052,5 +3958,3 @@ out_label:
        OBD_FREE(label, label_sz);
         return rc;
 }
-
-
index 2cd9598..9477fbb 100644 (file)
@@ -270,32 +270,6 @@ out:
 }
 EXPORT_SYMBOL(llog_init_handle);
 
-int llog_copy_handler(const struct lu_env *env,
-                     struct llog_handle *llh,
-                     struct llog_rec_hdr *rec,
-                     void *data)
-{
-       struct llog_rec_hdr local_rec = *rec;
-       struct llog_handle *local_llh = (struct llog_handle *)data;
-       char *cfg_buf = (char*) (rec + 1);
-       struct lustre_cfg *lcfg;
-       int rc = 0;
-       ENTRY;
-
-       /* Append all records */
-       local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
-       rc = llog_write(env, local_llh, &local_rec, NULL, 0,
-                       (void *)cfg_buf, -1);
-
-       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);
-}
-EXPORT_SYMBOL(llog_copy_handler);
-
 static int llog_process_thread(void *arg)
 {
        struct llog_process_info        *lpi = arg;
@@ -510,14 +484,6 @@ int llog_process(const struct lu_env *env, struct llog_handle *loghandle,
 }
 EXPORT_SYMBOL(llog_process);
 
-inline int llog_get_size(struct llog_handle *loghandle)
-{
-        if (loghandle && loghandle->lgh_hdr)
-                return loghandle->lgh_hdr->llh_count;
-        return 0;
-}
-EXPORT_SYMBOL(llog_get_size);
-
 int llog_reverse_process(const struct lu_env *env,
                         struct llog_handle *loghandle, llog_cb_t cb,
                         void *data, void *catdata)
@@ -799,8 +765,9 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
                     struct llog_handle **res, struct llog_logid *logid,
                     char *name)
 {
-       struct thandle  *th;
-       int              rc;
+       struct dt_device        *d;
+       struct thandle          *th;
+       int                      rc;
 
        ENTRY;
 
@@ -811,27 +778,21 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
        if (llog_exist(*res))
                RETURN(0);
 
-       if ((*res)->lgh_obj != NULL) {
-               struct dt_device *d;
+       LASSERT((*res)->lgh_obj != NULL);
 
-               d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);
+       d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);
 
-               th = dt_trans_create(env, d);
-               if (IS_ERR(th))
-                       GOTO(out, rc = PTR_ERR(th));
+       th = dt_trans_create(env, d);
+       if (IS_ERR(th))
+               GOTO(out, rc = PTR_ERR(th));
 
-               rc = llog_declare_create(env, *res, th);
-               if (rc == 0) {
-                       rc = dt_trans_start_local(env, d, th);
-                       if (rc == 0)
-                               rc = llog_create(env, *res, th);
-               }
-               dt_trans_stop(env, d, th);
-       } else {
-               /* lvfs compat code */
-               LASSERT((*res)->lgh_file == NULL);
-               rc = llog_create(env, *res, NULL);
+       rc = llog_declare_create(env, *res, th);
+       if (rc == 0) {
+               rc = dt_trans_start_local(env, d, th);
+               if (rc == 0)
+                       rc = llog_create(env, *res, th);
        }
+       dt_trans_stop(env, d, th);
 out:
        if (rc)
                llog_close(env, *res);
@@ -878,43 +839,36 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
               struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
               int cookiecount, void *buf, int idx)
 {
-       int rc;
+       struct dt_device        *dt;
+       struct thandle          *th;
+       int                      rc;
 
        ENTRY;
 
        LASSERT(loghandle);
        LASSERT(loghandle->lgh_ctxt);
+       LASSERT(loghandle->lgh_obj != NULL);
 
-       if (loghandle->lgh_obj != NULL) {
-               struct dt_device        *dt;
-               struct thandle          *th;
-
-               dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);
+       dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);
 
-               th = dt_trans_create(env, dt);
-               if (IS_ERR(th))
-                       RETURN(PTR_ERR(th));
+       th = dt_trans_create(env, dt);
+       if (IS_ERR(th))
+               RETURN(PTR_ERR(th));
 
-               rc = llog_declare_write_rec(env, loghandle, rec, idx, th);
-               if (rc)
-                       GOTO(out_trans, rc);
+       rc = llog_declare_write_rec(env, loghandle, rec, idx, th);
+       if (rc)
+               GOTO(out_trans, rc);
 
-               rc = dt_trans_start_local(env, dt, th);
-               if (rc)
-                       GOTO(out_trans, rc);
+       rc = dt_trans_start_local(env, dt, th);
+       if (rc)
+               GOTO(out_trans, rc);
 
-               down_write(&loghandle->lgh_lock);
-               rc = llog_write_rec(env, loghandle, rec, reccookie,
-                                   cookiecount, buf, idx, th);
-               up_write(&loghandle->lgh_lock);
+       down_write(&loghandle->lgh_lock);
+       rc = llog_write_rec(env, loghandle, rec, reccookie,
+                           cookiecount, buf, idx, th);
+       up_write(&loghandle->lgh_lock);
 out_trans:
-               dt_trans_stop(env, dt, th);
-       } else { /* lvfs compatibility */
-               down_write(&loghandle->lgh_lock);
-               rc = llog_write_rec(env, loghandle, rec, reccookie,
-                                   cookiecount, buf, idx, NULL);
-               up_write(&loghandle->lgh_lock);
-       }
+       dt_trans_stop(env, dt, th);
        RETURN(rc);
 }
 EXPORT_SYMBOL(llog_write);
@@ -974,3 +928,104 @@ out:
        RETURN(rc);
 }
 EXPORT_SYMBOL(llog_close);
+
+int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
+                 char *name)
+{
+       struct llog_handle      *llh;
+       int                      rc = 0;
+
+       rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
+       if (rc < 0) {
+               if (likely(rc == -ENOENT))
+                       rc = 0;
+               GOTO(out, rc);
+       }
+
+       rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
+       if (rc)
+               GOTO(out_close, rc);
+       rc = llog_get_size(llh);
+
+out_close:
+       llog_close(env, llh);
+out:
+       /* header is record 1 */
+       return (rc <= 1);
+}
+EXPORT_SYMBOL(llog_is_empty);
+
+int llog_copy_handler(const struct lu_env *env, struct llog_handle *llh,
+                     struct llog_rec_hdr *rec, void *data)
+{
+       struct llog_handle      *copy_llh = data;
+
+       /* Append all records */
+       return llog_write(env, copy_llh, rec, NULL, 0, NULL, -1);
+}
+EXPORT_SYMBOL(llog_copy_handler);
+
+/* backup plain llog */
+int llog_backup(const struct lu_env *env, struct obd_device *obd,
+               struct llog_ctxt *ctxt, struct llog_ctxt *bctxt,
+               char *name, char *backup)
+{
+       struct llog_handle      *llh, *bllh;
+       int                      rc;
+
+       ENTRY;
+
+       /* open original log */
+       rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
+       if (rc < 0) {
+               /* the -ENOENT case is also reported to the caller
+                * but silently so it should handle that if needed.
+                */
+               if (rc != -ENOENT)
+                       CERROR("%s: failed to open log %s: rc = %d\n",
+                              obd->obd_name, name, rc);
+               RETURN(rc);
+       }
+
+       rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
+       if (rc)
+               GOTO(out_close, rc);
+
+       /* Make sure there's no old backup log */
+       rc = llog_erase(env, bctxt, NULL, backup);
+       if (rc < 0 && rc != -ENOENT)
+               GOTO(out_close, rc);
+
+       /* open backup log */
+       rc = llog_open_create(env, bctxt, &bllh, NULL, backup);
+       if (rc) {
+               CERROR("%s: failed to open backup logfile %s: rc = %d\n",
+                      obd->obd_name, backup, rc);
+               GOTO(out_close, rc);
+       }
+
+       /* check that backup llog is not the same object as original one */
+       if (llh->lgh_obj == bllh->lgh_obj) {
+               CERROR("%s: backup llog %s to itself (%s), objects %p/%p\n",
+                      obd->obd_name, name, backup, llh->lgh_obj,
+                      bllh->lgh_obj);
+               GOTO(out_backup, rc = -EEXIST);
+       }
+
+       rc = llog_init_handle(env, bllh, LLOG_F_IS_PLAIN, NULL);
+       if (rc)
+               GOTO(out_backup, rc);
+
+       /* Copy log record by record */
+       rc = llog_process_or_fork(env, llh, llog_copy_handler, (void *)bllh,
+                                 NULL, false);
+       if (rc)
+               CERROR("%s: failed to backup log %s: rc = %d\n",
+                      obd->obd_name, name, rc);
+out_backup:
+       llog_close(env, bllh);
+out_close:
+       llog_close(env, llh);
+       RETURN(rc);
+}
+EXPORT_SYMBOL(llog_backup);
index 26a3137..7f41304 100644 (file)
@@ -867,9 +867,12 @@ out_los:
                (*los)->los_seq = fid_seq(first_fid);
                (*los)->los_last_oid = le64_to_cpu(lastid);
                (*los)->los_obj = o;
-               /* read value should not be less than initial one */
-               LASSERTF((*los)->los_last_oid >= first_oid, "%u < %u\n",
-                        (*los)->los_last_oid, first_oid);
+               /* Read value should not be less than initial one
+                * but possible after upgrade from older fs.
+                * In this case just switch to the first_oid in memory and
+                * it will be updated on disk with first object generated */
+               if ((*los)->los_last_oid < first_oid)
+                       (*los)->los_last_oid = first_oid;
        }
 out:
        mutex_unlock(&ls->ls_los_mutex);
index 9f50128..f7d6c9a 100644 (file)
@@ -29,6 +29,8 @@
  *
  * Author: Mikhail Pershin <mike.pershin@intel.com>
  */
+#ifndef __LOCAL_STORAGE_H
+#define __LOCAL_STORAGE_H
 
 #include <dt_object.h>
 #include <obd.h>
@@ -87,3 +89,4 @@ struct los_ondisk {
 
 #define LOS_MAGIC      0xdecafbee
 
+#endif
index 084506c..ba45a0d 100644 (file)
@@ -425,10 +425,10 @@ LU_KEY_INIT_FINI(lu_global, struct lu_cdebug_data);
  * lu_global_init().
  */
 struct lu_context_key lu_global_key = {
-        .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD |
-                    LCT_MG_THREAD | LCT_CL_THREAD,
-        .lct_init = lu_global_key_init,
-        .lct_fini = lu_global_key_fini
+       .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD |
+                   LCT_MG_THREAD | LCT_CL_THREAD | LCT_LOCAL,
+       .lct_init = lu_global_key_init,
+       .lct_fini = lu_global_key_fini
 };
 
 /**
index 425336c..922e877 100644 (file)
@@ -639,6 +639,9 @@ int lustre_put_lsi(struct super_block *sb)
         CDEBUG(D_MOUNT, "put %p %d\n", sb, cfs_atomic_read(&lsi->lsi_mounts));
         if (cfs_atomic_dec_and_test(&lsi->lsi_mounts)) {
                if (IS_SERVER(lsi) && lsi->lsi_osd_exp) {
+                       lu_device_put(&lsi->lsi_dt_dev->dd_lu_dev);
+                       lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt = NULL;
+                       lsi->lsi_dt_dev = NULL;
                        obd_disconnect(lsi->lsi_osd_exp);
                        /* wait till OSD is gone */
                        obd_zombie_barrier();
index 9b8b144..9137219 100644 (file)
@@ -1663,14 +1663,18 @@ static int osd_start(struct lustre_sb_info *lsi, unsigned long mflags)
                obd->obd_force = 1;
                class_manual_cleanup(obd);
                lsi->lsi_dt_dev = NULL;
+               RETURN(rc);
        }
 
-       /* XXX: to keep support old components relying on lsi_srv_mnt
-        *      we get this info from OSD just started */
        LASSERT(obd->obd_lu_dev);
+       lu_device_get(obd->obd_lu_dev);
        lsi->lsi_dt_dev = lu2dt_dev(obd->obd_lu_dev);
        LASSERT(lsi->lsi_dt_dev);
 
+       /* set disk context for llog usage */
+       OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
+       obd->obd_lvfs_ctxt.dt = lsi->lsi_dt_dev;
+
        dt_conf_get(NULL, lsi->lsi_dt_dev, &p);
 
        lsi->lsi_srv_mnt = p.ddp_mnt;
index 72ed5b8..98a3b24 100644 (file)
@@ -1021,7 +1021,7 @@ static int osd_scrub_main(void *args)
        int                   rc;
        ENTRY;
 
-       rc = lu_env_init(&env, LCT_DT_THREAD);
+       rc = lu_env_init(&env, LCT_LOCAL);
        if (rc != 0) {
                CERROR("%.16s: OI scrub, fail to init env, rc = %d\n",
                       LDISKFS_SB(sb)->s_es->s_volume_name, rc);
@@ -1796,6 +1796,13 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev)
                        rc = osd_scrub_start(dev);
        }
 
+       /* it is possible that dcache entries may keep objects after they are
+        * deleted by OSD. While it looks safe this can cause object data to
+        * stay until umount causing failures in tests calculating free space,
+        * e.g. replay-ost-single. Since those dcache entries are not used
+        * anymore let's just free them after use here */
+       shrink_dcache_sb(sb);
+
        RETURN(rc);
 }