📄 obj40_repair.c
字号:
/* Copyright 2001-2005 by Hans Reiser, licensing governed by reiser4progs/COPYING. obj40_repair.c -- reiser4 file 40 plugins repair code. */#ifndef ENABLE_MINIMAL#include "obj40_repair.h"#define STAT_KEY(o) \ (&((o)->info.start.key))static void obj40_init(reiser4_object_t *object) { if (!object->info.start.plug) aal_memcpy(STAT_KEY(object), &object->info.object, sizeof(object->info.object));}/* Obtains the maxreal key of the given place. */uint64_t obj40_place_maxreal(reiser4_place_t *place) { reiser4_key_t key; objcall(place, balance->maxreal_key, &key); return objcall(&key, get_offset);}static errno_t obj40_exts_check(reiser4_object_t *obj) { reiser4_object_plug_t *ops; uint64_t extmask; aal_assert("vpf-1831", obj != NULL); extmask = obj40_extmask(&obj->info.start); ops = reiser4_psobj(obj); /* Check that there is no one unknown extension. */ if (extmask & ops->sdext_unknown) return RE_FATAL; /* Check that LW and UNIX extensions exist. */ return ((extmask & ops->sdext_mandatory) == ops->sdext_mandatory) ? 0 : RE_FATAL;}/* Checks that @obj->info.start is SD of the wanted file. */static errno_t obj40_check_stat(reiser4_object_t *obj) { object_info_t *info; errno_t res; aal_assert("vpf-1200", obj != NULL); info = &obj->info; if (!info->start.plug) { if (!obj40_valid_item(&info->start)) return RE_FATAL; if ((res = obj40_fetch_item(&info->start))) return res; } if (info->start.plug->p.id.group != STAT_ITEM) return RE_FATAL;#if 0 /* Compare the correct key with the place key. */ if (plug_call(info->object.plug, compfull, &info->object, &info->start.key)) { return RE_FATAL; }#endif /* Some SD is recognized. Check that this is our SD. */ return obj40_exts_check(obj);}/* The plugin tries to recognize the object: detects the SD, body items */static errno_t obj40_objkey_check(reiser4_object_t *obj) { object_info_t *info; reiser4_key_t key; aal_assert("vpf-1121", obj->info.tree != NULL); aal_assert("vpf-1127", obj->info.object.plug != NULL); info = &obj->info; /* Check if the key pointer is correct and then check the found item if it is SD with the proper key. */ plugcall(info->object.plug, build_generic, &key, KEY_STATDATA_TYPE, objcall(&info->object, get_locality), objcall(&info->object, get_ordering), objcall(&info->object, get_objectid), 0); /* Compare the correct key with the search one. */ return objcall(&key, compfull, &info->object) ? RE_FATAL : 0;}errno_t obj40_recognize(reiser4_object_t *obj) { errno_t res; aal_assert("vpf-1231", obj != NULL); /* Initializing file handle */ obj40_init(obj); if ((res = obj40_objkey_check(obj))) return res; if ((res = obj40_check_stat(obj))) return res; /* Positioning to the first directory unit */ if (reiser4_psobj(obj)->reset) reiser4_psobj(obj)->reset(obj); return 0;}#define OBJ40_CHECK(field, type, value, correct) \static inline int obj40_check_##field(reiser4_object_t *obj, \ type *value, \ type correct) \{ \ if (*value == correct) \ return 0; \ \ *value = correct; \ return 1; \}/* The default method for nlink and size handling. */OBJ40_CHECK(nlink, uint32_t, value, correct);OBJ40_CHECK(size, uint64_t, value, correct);OBJ40_CHECK(bytes, uint64_t, value, correct);static inline int obj40_check_mode(reiser4_object_t *obj, uint16_t *mode, uint16_t correct) { if (((*mode) & S_IFMT) == correct) return 0; *mode &= ~S_IFMT; *mode |= correct; return 1;}static inline errno_t obj40_stat_unix_check(reiser4_object_t *obj, obj40_stat_ops_t *ops, obj40_stat_hint_t *hint, uint8_t mode, int present){ reiser4_place_t *start = &obj->info.start; sdhint_unix_t unixh, correct; errno_t res; int fixed; aal_memset(&unixh, 0, sizeof(unixh)); /* If the UNIX extention is not present, skip checking or add it. */ if (!present) { trans_hint_t trans; stat_hint_t stat; /* If the LW extention is not mandatory, skip checking. */ if (!(reiser4_psobj(obj)->sdext_mandatory & (1 << SDEXT_UNIX_ID))) { return 0; } fsck_mess("Node (%llu), item (%u), [%s] (%s): no mandatory " "unix extention.%s Plugin (%s).", place_blknr(start), start->pos.item, print_inode(obj40_core, &start->key), start->plug->p.label, mode != RM_CHECK ? " Added." : "", reiser4_psobj(obj)->p.label); if (mode == RM_CHECK) return RE_FIXABLE; /* Add missed, mandatory extention. */ aal_memset(&trans, 0, sizeof(trans)); aal_memset(&stat, 0, sizeof(stat)); trans.shift_flags = SF_DEFAULT; trans.specific = &stat; trans.plug = start->plug; obj40_stat_unix_init(&stat, &unixh, hint->bytes, 0); start->pos.unit = 0; if ((res = obj40_insert(obj, start, &trans, LEAF_LEVEL))) return res; if ((res = obj40_update(obj))) return res; /* Do not return here, but check the new extention with the given set of methods instead. */ } if ((res = obj40_read_ext(obj, SDEXT_UNIX_ID, &unixh)) < 0) return res; correct = unixh; if (ops->check_bytes == NULL) { /* Call the default one. */ fixed = obj40_check_bytes(obj, &correct.bytes, hint->bytes); } else if (ops->check_bytes != SKIP_METHOD) { fixed = ops->check_bytes(obj, &correct.bytes, hint->bytes); } else { fixed = 0; } if (fixed) { /* sd_bytes are set wrongly in the kernel. */ fsck_mess("Node (%llu), item (%u), [%s] (%s): wrong bytes " "(%llu), %s (%llu).", place_blknr(start), start->pos.item, print_inode(obj40_core, &start->key), start->plug->p.label, unixh.bytes, mode == RM_CHECK ? "Should be" : "Fixed to", correct.bytes); /* Zero rdev because rdev and bytes is the union on disk but not in the unixh. */ correct.rdev = 0; res = RE_FIXABLE; } if (res && mode != RM_CHECK) return obj40_write_ext(obj, SDEXT_UNIX_ID, &correct); return res;}static inline errno_t obj40_stat_lw_check(reiser4_object_t *obj, obj40_stat_ops_t *ops, obj40_stat_hint_t *hint, uint8_t mode, int present){ reiser4_place_t *start = &obj->info.start; sdhint_lw_t lwh, correct; errno_t res; int fixed; aal_memset(&lwh, 0, sizeof(lwh)); /* If the LW extention is not present, skip checking or add it. */ if (!present) { trans_hint_t trans; stat_hint_t stat; /* If the LW extention is not mandatory, skip checking. */ if (!(reiser4_psobj(obj)->sdext_mandatory & (1 << SDEXT_LW_ID))) { return 0; } fsck_mess("Node (%llu), item (%u), [%s] (%s): no mandatory " "light-weight extention.%s Plugin (%s).", place_blknr(start), start->pos.item, print_inode(obj40_core, &start->key), start->plug->p.label, mode != RM_CHECK ? "Added." : "", reiser4_psobj(obj)->p.label); if (mode == RM_CHECK) return RE_FIXABLE; /* Add missed, mandatory extention. */ aal_memset(&trans, 0, sizeof(trans)); aal_memset(&stat, 0, sizeof(stat)); trans.shift_flags = SF_DEFAULT; trans.specific = &stat; trans.plug = start->plug; obj40_stat_lw_init(obj, &stat, &lwh, hint->size, hint->nlink, hint->mode); start->pos.unit = 0; if ((res = obj40_insert(obj, start, &trans, LEAF_LEVEL))) return res; if ((res = obj40_update(obj))) return res; /* Do not return here, but check the new extention with the given set of methods instead. */ } /* Read LW extension. */ if ((res = obj40_read_ext(obj, SDEXT_LW_ID, &lwh))) return res; /* Form the correct LW extension. */ correct = lwh; if (ops->check_nlink == NULL) { /* Call the default one. */ fixed = obj40_check_nlink(obj, &correct.nlink, hint->nlink); } else if (ops->check_nlink != SKIP_METHOD) { fixed = ops->check_nlink(obj, &correct.nlink, hint->nlink); } else { fixed = 0; } if (fixed) { /* Fix nlink silently: there is no way to check if nlink is correct, so the check is either skipped or rebuild. */ res = RE_FIXABLE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -