* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2013, Intel Corporation.
+ * Copyright (c) 2013, 2015, Intel Corporation.
*/
/*
* lustre/lfsck/lfsck_bookmark.c
* Author: Fan, Yong <fan.yong@intel.com>
*/
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
#define DEBUG_SUBSYSTEM S_LFSCK
#include <lu_object.h>
#define LFSCK_BOOKMARK_MAGIC 0x20130C1D
-static const char lfsck_bookmark_name[] = "lfsck_bookmark";
-
static void lfsck_bookmark_le_to_cpu(struct lfsck_bookmark *des,
struct lfsck_bookmark *src)
{
des->lb_version = le16_to_cpu(src->lb_version);
des->lb_param = le16_to_cpu(src->lb_param);
des->lb_speed_limit = le32_to_cpu(src->lb_speed_limit);
+ des->lb_async_windows = le16_to_cpu(src->lb_async_windows);
+ fid_le_to_cpu(&des->lb_lpf_fid, &src->lb_lpf_fid);
+ fid_le_to_cpu(&des->lb_last_fid, &src->lb_last_fid);
}
-static void lfsck_bookmark_cpu_to_le(struct lfsck_bookmark *des,
- struct lfsck_bookmark *src)
+void lfsck_bookmark_cpu_to_le(struct lfsck_bookmark *des,
+ struct lfsck_bookmark *src)
{
des->lb_magic = cpu_to_le32(src->lb_magic);
des->lb_version = cpu_to_le16(src->lb_version);
des->lb_param = cpu_to_le16(src->lb_param);
des->lb_speed_limit = cpu_to_le32(src->lb_speed_limit);
+ des->lb_async_windows = cpu_to_le16(src->lb_async_windows);
+ fid_cpu_to_le(&des->lb_lpf_fid, &src->lb_lpf_fid);
+ fid_cpu_to_le(&des->lb_last_fid, &src->lb_last_fid);
}
static int lfsck_bookmark_load(const struct lu_env *env,
lfsck_bookmark_le_to_cpu(bm, &lfsck->li_bookmark_disk);
if (bm->lb_magic != LFSCK_BOOKMARK_MAGIC) {
- CWARN("%.16s: invalid lfsck_bookmark magic "
- "0x%x != 0x%x\n", lfsck_lfsck2name(lfsck),
+ CDEBUG(D_LFSCK, "%s: invalid lfsck_bookmark magic "
+ "%#x != %#x\n", lfsck_lfsck2name(lfsck),
bm->lb_magic, LFSCK_BOOKMARK_MAGIC);
/* Process it as new lfsck_bookmark. */
rc = -ENODATA;
/* return -ENODATA for empty lfsck_bookmark. */
rc = -ENODATA;
else
- CERROR("%.16s: fail to load lfsck_bookmark, "
- "expected = %d, rc = %d\n",
+ CDEBUG(D_LFSCK, "%s: fail to load lfsck_bookmark, "
+ "expected = %d: rc = %d\n",
lfsck_lfsck2name(lfsck), len, rc);
}
return rc;
{
struct thandle *handle;
struct dt_object *obj = lfsck->li_bookmark_obj;
+ struct dt_device *dev = lfsck_obj2dev(obj);
loff_t pos = 0;
int len = sizeof(struct lfsck_bookmark);
int rc;
lfsck_bookmark_cpu_to_le(&lfsck->li_bookmark_disk,
&lfsck->li_bookmark_ram);
- handle = dt_trans_create(env, lfsck->li_bottom);
- if (IS_ERR(handle)) {
- rc = PTR_ERR(handle);
- CERROR("%.16s: fail to create trans for storing "
- "lfsck_bookmark: %d\n,", lfsck_lfsck2name(lfsck), rc);
- RETURN(rc);
- }
+ handle = dt_trans_create(env, dev);
+ if (IS_ERR(handle))
+ GOTO(log, rc = PTR_ERR(handle));
- rc = dt_declare_record_write(env, obj, len, 0, handle);
- if (rc != 0) {
- CERROR("%.16s: fail to declare trans for storing "
- "lfsck_bookmark: %d\n,", lfsck_lfsck2name(lfsck), rc);
+ rc = dt_declare_record_write(env, obj,
+ lfsck_buf_get(env,
+ &lfsck->li_bookmark_disk, len),
+ 0, handle);
+ if (rc != 0)
GOTO(out, rc);
- }
- rc = dt_trans_start_local(env, lfsck->li_bottom, handle);
- if (rc != 0) {
- CERROR("%.16s: fail to start trans for storing "
- "lfsck_bookmark: %d\n,", lfsck_lfsck2name(lfsck), rc);
+ rc = dt_trans_start_local(env, dev, handle);
+ if (rc != 0)
GOTO(out, rc);
- }
rc = dt_record_write(env, obj,
lfsck_buf_get(env, &lfsck->li_bookmark_disk, len),
&pos, handle);
- if (rc != 0)
- CERROR("%.16s: fail to store lfsck_bookmark, expected = %d, "
- "rc = %d\n", lfsck_lfsck2name(lfsck), len, rc);
GOTO(out, rc);
out:
- dt_trans_stop(env, lfsck->li_bottom, handle);
+ dt_trans_stop(env, dev, handle);
+
+log:
+ if (rc != 0)
+ CDEBUG(D_LFSCK, "%s: fail to store lfsck_bookmark: rc = %d\n",
+ lfsck_lfsck2name(lfsck), rc);
return rc;
}
memset(mb, 0, sizeof(*mb));
mb->lb_magic = LFSCK_BOOKMARK_MAGIC;
mb->lb_version = LFSCK_VERSION_V2;
+ mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
mutex_lock(&lfsck->li_mutex);
rc = lfsck_bookmark_store(env, lfsck);
mutex_unlock(&lfsck->li_mutex);
int lfsck_bookmark_setup(const struct lu_env *env,
struct lfsck_instance *lfsck)
{
+ struct dt_object *root;
struct dt_object *obj;
int rc;
ENTRY;
- obj = local_file_find_or_create(env, lfsck->li_los,
- lfsck->li_local_root,
- lfsck_bookmark_name,
+ root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
+ if (IS_ERR(root))
+ RETURN(PTR_ERR(root));
+
+ if (unlikely(!dt_try_as_dir(env, root))) {
+ lfsck_object_put(env, root);
+
+ RETURN(-ENOTDIR);
+ }
+
+ obj = local_file_find_or_create(env, lfsck->li_los, root,
+ LFSCK_BOOKMARK,
S_IFREG | S_IRUGO | S_IWUSR);
+ lfsck_object_put(env, root);
if (IS_ERR(obj))
RETURN(PTR_ERR(obj));
lfsck->li_bookmark_obj = obj;
rc = lfsck_bookmark_load(env, lfsck);
- if (rc == -ENODATA)
+ if (rc == 0) {
+ struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram;
+
+ /* It is upgraded from old release, set it as
+ * LFSCK_ASYNC_WIN_DEFAULT to avoid memory pressure. */
+ if (unlikely(mb->lb_async_windows == 0)) {
+ mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
+ mutex_lock(&lfsck->li_mutex);
+ rc = lfsck_bookmark_store(env, lfsck);
+ mutex_unlock(&lfsck->li_mutex);
+ }
+ } else if (rc == -ENODATA) {
rc = lfsck_bookmark_init(env, lfsck);
+ }
RETURN(rc);
}
+
+int lfsck_set_param(const struct lu_env *env, struct lfsck_instance *lfsck,
+ struct lfsck_start *start, bool reset)
+{
+ struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
+ int rc = 0;
+ bool dirty = false;
+
+ if (start == NULL) {
+ LASSERT(reset);
+
+ if (bk->lb_param & LPF_ALL_TGT) {
+ bk->lb_param &= ~LPF_ALL_TGT;
+ dirty = true;
+ }
+
+ if (bk->lb_param & LPF_CREATE_OSTOBJ) {
+ bk->lb_param &= ~LPF_CREATE_OSTOBJ;
+ dirty = true;
+ }
+
+ if (bk->lb_param & LPF_CREATE_MDTOBJ) {
+ bk->lb_param &= ~LPF_CREATE_MDTOBJ;
+ dirty = true;
+ }
+
+ if (bk->lb_param & LPF_FAILOUT) {
+ bk->lb_param &= ~LPF_FAILOUT;
+ dirty = true;
+ }
+
+ if (bk->lb_param & LPF_DRYRUN) {
+ bk->lb_param &= ~LPF_DRYRUN;
+ dirty = true;
+ }
+
+ if (bk->lb_param & LPF_OST_ORPHAN) {
+ bk->lb_param &= ~LPF_OST_ORPHAN;
+ dirty = true;
+ }
+
+ if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
+ dirty = true;
+
+ if (bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
+ bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
+ dirty = true;
+ }
+ } else {
+ if ((bk->lb_param & LPF_ALL_TGT) &&
+ !(start->ls_flags & LPF_ALL_TGT)) {
+ bk->lb_param &= ~LPF_ALL_TGT;
+ dirty = true;
+ } else if (!(bk->lb_param & LPF_ALL_TGT) &&
+ (start->ls_flags & LPF_ALL_TGT)) {
+ bk->lb_param |= LPF_ALL_TGT;
+ dirty = true;
+ }
+
+ if ((start->ls_valid & LSV_CREATE_OSTOBJ) || reset) {
+ if ((bk->lb_param & LPF_CREATE_OSTOBJ) &&
+ !(start->ls_valid & LSV_CREATE_OSTOBJ)) {
+ bk->lb_param &= ~LPF_CREATE_OSTOBJ;
+ dirty = true;
+ } else if (!(bk->lb_param & LPF_CREATE_OSTOBJ) &&
+ (start->ls_flags & LPF_CREATE_OSTOBJ)) {
+ bk->lb_param |= LPF_CREATE_OSTOBJ;
+ dirty = true;
+ }
+ }
+
+ if ((start->ls_valid & LSV_CREATE_MDTOBJ) || reset) {
+ if ((bk->lb_param & LPF_CREATE_MDTOBJ) &&
+ !(start->ls_valid & LSV_CREATE_MDTOBJ)) {
+ bk->lb_param &= ~LPF_CREATE_MDTOBJ;
+ dirty = true;
+ } else if (!(bk->lb_param & LPF_CREATE_MDTOBJ) &&
+ (start->ls_flags & LPF_CREATE_MDTOBJ)) {
+ bk->lb_param |= LPF_CREATE_MDTOBJ;
+ dirty = true;
+ }
+ }
+
+ if ((start->ls_valid & LSV_ERROR_HANDLE) || reset) {
+ if ((bk->lb_param & LPF_FAILOUT) &&
+ !(start->ls_valid & LSV_ERROR_HANDLE)) {
+ bk->lb_param &= ~LPF_FAILOUT;
+ dirty = true;
+ } else if (!(start->ls_flags & LPF_FAILOUT) &&
+ (bk->lb_param & LPF_FAILOUT)) {
+ bk->lb_param &= ~LPF_FAILOUT;
+ dirty = true;
+ }
+ }
+
+ if ((start->ls_valid & LSV_DRYRUN) || reset) {
+ if ((bk->lb_param & LPF_DRYRUN) &&
+ !(start->ls_valid & LSV_DRYRUN)) {
+ bk->lb_param &= ~LPF_DRYRUN;
+ dirty = true;
+ } else if (!(start->ls_flags & LPF_DRYRUN) &&
+ (bk->lb_param & LPF_DRYRUN)) {
+ bk->lb_param &= ~LPF_DRYRUN;
+ lfsck->li_drop_dryrun = 1;
+ dirty = true;
+ }
+ }
+
+ if ((bk->lb_param & LPF_OST_ORPHAN) &&
+ !(start->ls_flags & LPF_OST_ORPHAN)) {
+ bk->lb_param &= ~LPF_OST_ORPHAN;
+ dirty = true;
+ } else if (!(bk->lb_param & LPF_OST_ORPHAN) &&
+ (start->ls_flags & LPF_OST_ORPHAN)) {
+ bk->lb_param |= LPF_OST_ORPHAN;
+ dirty = true;
+ }
+
+ if (start->ls_valid & LSV_SPEED_LIMIT) {
+ if (__lfsck_set_speed(lfsck, start->ls_speed_limit))
+ dirty = true;
+ } else if (reset) {
+ if (__lfsck_set_speed(lfsck, LFSCK_SPEED_NO_LIMIT))
+ dirty = true;
+ }
+
+ if (start->ls_valid & LSV_ASYNC_WINDOWS) {
+ if (start->ls_async_windows < 1 ||
+ start->ls_async_windows > LFSCK_ASYNC_WIN_MAX)
+ return -EINVAL;
+
+ if (bk->lb_async_windows != start->ls_async_windows) {
+ bk->lb_async_windows = start->ls_async_windows;
+ dirty = true;
+ }
+ } else if (reset &&
+ bk->lb_async_windows != LFSCK_ASYNC_WIN_DEFAULT) {
+ bk->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT;
+ dirty = true;
+ }
+ }
+
+ if (dirty)
+ rc = lfsck_bookmark_store(env, lfsck);
+
+ return rc;
+}