📄 obj40.c
字号:
/* Prepapre the StatData hint. */ aal_memset(&stat, 0, sizeof(stat)); if ((res = obj40_stat_unix_init(&stat, &unixh, bytes, rdev))) return res; if ((res = obj40_stat_lw_init(obj, &stat, &lwh, size, nlink, mode))) return res; if ((res = obj40_stat_plug_init(obj, &stat, &plugh))) return res; if ((res = obj40_stat_heir_init(obj, &stat, &heirh))) return res; if ((res = obj40_stat_sym_init(obj, &stat, str))) return res; if ((res = obj40_stat_crc_init(obj, &stat, &crch, str))) return res; hint.specific = &stat; /* Lookup place new item to be insert at and insert it to tree */ switch ((lookup = obj40_find_item(obj, &hint.offset, FIND_CONV, NULL, NULL, STAT_PLACE(obj)))) { case ABSENT: break; default: return lookup < 0 ? lookup : -EIO; } /* Insert stat data to tree */ res = obj40_insert(obj, STAT_PLACE(obj), &hint, LEAF_LEVEL); /* Reset file. */ if (reiser4_psobj(obj)->reset) reiser4_psobj(obj)->reset(obj); return res < 0 ? res : 0;}errno_t obj40_create(reiser4_object_t *obj, object_hint_t *hint) { if (hint == NULL) return obj40_create_stat(obj, 0, 0, 0, 0, 0, NULL); return obj40_create_stat(obj, 0, 0, hint->rdev, 0, hint->mode, hint->str);}/* Writes one stat data extension. */errno_t obj40_write_ext(reiser4_object_t *obj, rid_t id, void *data) { stat_hint_t stat; aal_memset(&stat, 0, sizeof(stat)); stat.extmask |= (1 << id); if (data) stat.ext[id] = data; return obj40_save_stat(obj, &stat);}/* Returns extensions mask from stat data item at @place. */uint64_t obj40_extmask(reiser4_place_t *place) { trans_hint_t hint; stat_hint_t stat; aal_memset(&stat, 0, sizeof(stat)); /* Preparing hint and mask */ hint.specific = &stat; hint.place_func = NULL; hint.region_func = NULL; hint.shift_flags = SF_DEFAULT; /* Calling statdata open method if any */ if (objcall(place, object->fetch_units, &hint) != 1) return MAX_UINT64; return stat.extmask;}/* Updates size field in the stat data */errno_t obj40_set_size(reiser4_object_t *obj, uint64_t size) { sdhint_lw_t lwh; errno_t res; if ((res = obj40_read_ext(obj, SDEXT_LW_ID, &lwh))) return res; lwh.size = size; return obj40_write_ext(obj, SDEXT_LW_ID, &lwh);}/* Gets nlink field from the stat data */int64_t obj40_get_nlink(reiser4_object_t *obj, int update) { sdhint_lw_t lwh; errno_t res; if (update) { if ((res = obj40_update(obj))) return res; } if ((res = obj40_read_ext(obj, SDEXT_LW_ID, &lwh))) return res; return lwh.nlink;}/* Updates nlink field in the stat data */errno_t obj40_set_nlink(reiser4_object_t *obj, uint32_t nlink) { sdhint_lw_t lwh; errno_t res; if ((res = obj40_read_ext(obj, SDEXT_LW_ID, &lwh))) return res; lwh.nlink = nlink; return obj40_write_ext(obj, SDEXT_LW_ID, &lwh);}/* Gets bytes field from the stat data */uint64_t obj40_get_bytes(reiser4_object_t *obj) { sdhint_unix_t unixh; if (obj40_read_ext(obj, SDEXT_UNIX_ID, &unixh)) return 0; return unixh.bytes;}/* Updates bytes field in the stat data */errno_t obj40_set_bytes(reiser4_object_t *obj, uint64_t bytes) { sdhint_unix_t unixh; errno_t res; if ((res = obj40_read_ext(obj, SDEXT_UNIX_ID, &unixh))) return res; unixh.rdev = 0; unixh.bytes = bytes; return obj40_write_ext(obj, SDEXT_UNIX_ID, &unixh);}/* Changes nlink field in statdata by passed @value */static errno_t obj40_inc_link(reiser4_object_t *obj, int32_t value, int update){ uint32_t nlink = obj40_get_nlink(obj, update); return obj40_set_nlink(obj, nlink + value);}/* Removes object stat data. */errno_t obj40_clobber(reiser4_object_t *obj) { errno_t res; trans_hint_t hint; aal_assert("umka-2546", obj != NULL); if ((res = obj40_update(obj))) return res; aal_memset(&hint, 0, sizeof(hint)); hint.count = 1; hint.shift_flags = SF_DEFAULT; STAT_PLACE(obj)->pos.unit = MAX_UINT32; return obj40_remove(obj, STAT_PLACE(obj), &hint);}/* Enumerates object metadata. */errno_t obj40_metadata(reiser4_object_t *obj, place_func_t place_func, void *data){ errno_t res; aal_assert("umka-2549", obj != NULL); aal_assert("umka-2550", place_func != NULL); if ((res = obj40_update(obj))) return res; return place_func(STAT_PLACE(obj), data);}errno_t obj40_link(reiser4_object_t *obj) { return obj40_inc_link(obj, 1, 1);}errno_t obj40_unlink(reiser4_object_t *obj) { return obj40_inc_link(obj, -1, 1);}/* Check if linked. Needed to let higher API levels know, that file has zero links and may be clobbered. */bool_t obj40_linked(reiser4_object_t *entity) { return obj40_get_nlink(entity, 1) != 0;}#endif/* Makes sure, that passed place points to right location in tree by means of calling tree_lookup() for its key. This is needed, because items may move to somewhere after each balancing. */errno_t obj40_update(reiser4_object_t *obj) { lookup_t res; aal_assert("umka-1905", obj != NULL); /* Looking for stat data place by */ switch ((res = obj40_find_item(obj, &obj->info.object, FIND_EXACT, NULL, NULL, STAT_PLACE(obj)))) { case PRESENT: return 0; case ABSENT: return -EIO; default: return res; }}/* Reads data from the tree to passed @hint. */int64_t obj40_read(reiser4_object_t *obj, trans_hint_t *hint, void *buff, uint64_t off, uint64_t count){ /* Preparing hint to be used for calling read with it. Here we initialize @count -- number of bytes to read, @specific -- pointer to buffer data will be read into, and pointer to tree instance, file is opened on. */ aal_memset(hint, 0, sizeof(*hint)); /* Initializing offset data must be read from. This is current file offset, so we use @reg->position. */ aal_memcpy(&hint->offset, &obj->position, sizeof(hint->offset)); objcall(&hint->offset, set_offset, off); hint->count = count; hint->specific = buff; return obj40_core->flow_ops.read(obj->info.tree, hint);}#ifndef ENABLE_MINIMALint64_t obj40_convert(reiser4_object_t *obj, conv_hint_t *hint) { return obj40_core->flow_ops.convert(obj->info.tree, hint);}int64_t obj40_cut(reiser4_object_t *obj, trans_hint_t *hint, uint64_t off, uint64_t count, region_func_t func, void *data){ aal_memset(hint, 0, sizeof(*hint)); /* Preparing key of the data to be cut. */ aal_memcpy(&hint->offset, &obj->position, sizeof(hint->offset)); objcall(&hint->offset, set_offset, off); /* Removing data from the tree. */ hint->count = count; hint->shift_flags = SF_DEFAULT; hint->region_func = func; hint->data = data; return obj40_core->flow_ops.cut(obj->info.tree, hint);}/* Truncates data in tree */int64_t obj40_truncate(reiser4_object_t *obj, uint64_t n, reiser4_item_plug_t *item_plug){ trans_hint_t hint; uint64_t size; uint64_t bytes; errno_t res; aal_assert("vpf-1882", obj != NULL); aal_assert("vpf-1884", item_plug != NULL); if ((res = obj40_update(obj))) return res; size = obj40_get_size(obj); if (size == n) return 0; if (n > size) { if ((res = obj40_write(obj, &hint, NULL, size, n - size, item_plug, NULL, NULL)) < 0) { return res; } bytes = hint.bytes; } else { res = obj40_cut(obj, &hint, n, MAX_UINT64, NULL, NULL); if (res < 0) return res; bytes = -hint.bytes; } /* Updating stat data fields. */ return obj40_touch(obj, n - size, bytes);}/* Inserts passed item hint into the tree. After function is finished, place contains the place of the inserted item. */int64_t obj40_insert(reiser4_object_t *obj, reiser4_place_t *place, trans_hint_t *hint, uint8_t level){ return obj40_core->tree_ops.insert(obj->info.tree, place, hint, level);}/* Removes item/unit by @key */errno_t obj40_remove(reiser4_object_t *obj, reiser4_place_t *place, trans_hint_t *trans){ return obj40_core->tree_ops.remove(obj->info.tree, place, trans);}/* This fucntion implements object item enumerator function. Used for getting directory metadata on packing, etc. */errno_t obj40_traverse(reiser4_object_t *obj, place_func_t place_func, obj_func_t obj_func, void *data){ errno_t res; aal_assert("umka-1712", obj != NULL); aal_assert("umka-1713", place_func != NULL); /* Calculating stat data item. */ if ((res = obj40_metadata(obj, place_func, data))) return res; /* Update current body item coord. */ if ((res = obj40_update_body(obj, obj_func)) != PRESENT) return res == ABSENT ? 0 : res; /* Loop until all items are enumerated. */ while (1) { /* Calling callback function. */ if ((res = place_func(&obj->body, data))) return res; /* Getting next item. */ if ((res = obj40_next_item(obj)) < 0) return res; if (res == ABSENT) return 0; } return 0;}/* File data enumeration related stuff. */typedef struct layout_hint { void *data; region_func_t region_func;} layout_hint_t;static errno_t cb_item_layout(blk_t start, count_t width, void *data) { layout_hint_t *hint = (layout_hint_t *)data; return hint->region_func(start, width, hint->data);}/* This fucntion implements hashed directory enumerator function. It is used when calculating fargmentation, prining. */errno_t obj40_layout(reiser4_object_t *obj, region_func_t region_func, obj_func_t obj_func, void *data){ layout_hint_t hint; errno_t res; aal_assert("umka-1473", obj != NULL); aal_assert("umka-1474", region_func != NULL); /* Update current body item coord. */ if ((res = obj40_update_body(obj, obj_func)) != PRESENT) return res == ABSENT ? 0 : res; /* Prepare layout hint. */ hint.data = data; hint.region_func = region_func; /* Loop until all items are enumerated. */ while (1) { reiser4_place_t *place = &obj->body; if (obj->body.plug->object->layout) { /* Calling item's layout method */ if ((res = objcall(place, object->layout, cb_item_layout, &hint))) { return res; } } else { /* Layout method is not implemented. Counting item itself. */ blk_t blk = place_blknr(place); if ((res = cb_item_layout(blk, 1, &hint))) return res; } /* Getting next item. */ if ((res = obj40_next_item(obj)) < 0) return res; /* Object is over? */ if (res == ABSENT) return 0; } return 0;}/* Writes passed data to the file. Returns amount of written bytes. */int64_t obj40_write(reiser4_object_t *obj, trans_hint_t *hint, void *buff, uint64_t off, uint64_t count, reiser4_item_plug_t *item_plug, place_func_t func, void *data){ /* Preparing hint to be used for calling write method. This is initializing @count - number of bytes to write, @specific - buffer to write into and @offset -- file offset data must be written at. */ aal_memset(hint, 0, sizeof(*hint)); hint->count = count; hint->specific = buff; hint->shift_flags = SF_DEFAULT; hint->place_func = func; hint->plug = item_plug; hint->data = data; aal_memcpy(&hint->offset, &obj->position, sizeof(hint->offset)); objcall(&hint->offset, set_offset, off); /* Write data to tree. */ return obj40_core->flow_ops.write(obj->info.tree, hint);}errno_t obj40_touch(reiser4_object_t *obj, int64_t size, int64_t bytes) { uint64_t fbytes; uint64_t fsize; errno_t res; /* Updating the SD place and update size, bytes there. */ if ((res = obj40_update(obj))) return res; fsize = obj40_get_size(obj); fbytes = obj40_get_bytes(obj); /* Update size & bytes unless they do not change. */ if (size && (res = obj40_set_size(obj, fsize + size))) return res; if (bytes && (res = obj40_set_bytes(obj, fbytes + bytes))) return res; return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -