/* * insert a name into a directory, doing overflow properly if there is a hash * collision. data_size indicates how big the item inserted should be. On * success a struct btrfs_dir_item pointer is returned, otherwise it is * an ERR_PTR. * * The name is not copied into the dir item, you have to do that yourself.
*/ staticstruct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
*trans, struct btrfs_root *root, struct btrfs_path *path, conststruct btrfs_key *cpu_key,
u32 data_size, constchar *name, int name_len)
{ int ret; char *ptr; struct extent_buffer *leaf;
/* * insert a directory item in the tree, doing all the magic for * both indexes. 'dir' indicates which objectid to insert it into, * 'location' is the key to stuff into the directory item, 'type' is the * type of the inode we're pointing to, and 'index' is the sequence number * to use for the second index (if one is created). * Will return 0 or -ENOMEM
*/ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, conststruct fscrypt_str *name, struct btrfs_inode *dir, conststruct btrfs_key *location, u8 type, u64 index)
{ int ret = 0; int ret2 = 0; struct btrfs_root *root = dir->root; struct btrfs_path *path; struct btrfs_dir_item *dir_item; struct extent_buffer *leaf; unsignedlong name_ptr; struct btrfs_key key; struct btrfs_disk_key disk_key;
u32 data_size;
second_insert: /* FIXME, use some real flag for selecting the extra index */ if (root == root->fs_info->tree_root) {
ret = 0; goto out_free;
}
btrfs_release_path(path);
/* * Lookup for a directory item by name. * * @trans: The transaction handle to use. Can be NULL if @mod is 0. * @root: The root of the target tree. * @path: Path to use for the search. * @dir: The inode number (objectid) of the directory. * @name: The name associated to the directory entry we are looking for. * @name_len: The length of the name. * @mod: Used to indicate if the tree search is meant for a read only * lookup, for a modification lookup or for a deletion lookup, so * its value should be 0, 1 or -1, respectively. * * Returns: NULL if the dir item does not exists, an error pointer if an error * happened, or a pointer to a dir item if a dir item exists for the given name.
*/ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 dir, conststruct fscrypt_str *name, int mod)
{ struct btrfs_key key; struct btrfs_dir_item *di;
di = btrfs_lookup_match_dir(NULL, root, path, &key, name->name,
name->len, 0); if (IS_ERR(di)) {
ret = PTR_ERR(di); /* Nothing found, we're safe */ if (ret == -ENOENT) return 0;
if (ret < 0) return ret;
}
/* we found an item, look for our name in the item */ if (di) { /* our exact name was found */ return -EEXIST;
}
/* See if there is room in the item to insert this name. */
data_size = sizeof(*di) + name->len;
leaf = path->nodes[0];
slot = path->slots[0]; if (data_size + btrfs_item_size(leaf, slot) + sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(root->fs_info)) { return -EOVERFLOW;
}
/* Plenty of insertion room. */ return 0;
}
/* * Lookup for a directory index item by name and index number. * * @trans: The transaction handle to use. Can be NULL if @mod is 0. * @root: The root of the target tree. * @path: Path to use for the search. * @dir: The inode number (objectid) of the directory. * @index: The index number. * @name: The name associated to the directory entry we are looking for. * @name_len: The length of the name. * @mod: Used to indicate if the tree search is meant for a read only * lookup, for a modification lookup or for a deletion lookup, so * its value should be 0, 1 or -1, respectively. * * Returns: NULL if the dir index item does not exists, an error pointer if an * error happened, or a pointer to a dir item if the dir index item exists and * matches the criteria (name and index number).
*/ struct btrfs_dir_item *
btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 dir,
u64 index, conststruct fscrypt_str *name, int mod)
{ struct btrfs_dir_item *di; struct btrfs_key key;
di = btrfs_match_dir_item_name(path, name->name, name->len); if (di) return di;
} /* Adjust return code if the key was not found in the next leaf. */ if (ret >= 0)
ret = -ENOENT;
di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod); if (IS_ERR(di) && PTR_ERR(di) == -ENOENT) return NULL;
return di;
}
/* * helper function to look at the directory item pointed to by 'path' * this walks through all the entries in a dir item and finds one * for a specific name.
*/ struct btrfs_dir_item *btrfs_match_dir_item_name(conststruct btrfs_path *path, constchar *name, int name_len)
{ struct btrfs_dir_item *dir_item; unsignedlong name_ptr;
u32 total_len;
u32 cur = 0;
u32 this_len; struct extent_buffer *leaf;
/* * given a pointer into a directory item, delete it. This * handles items that have more than one entry in them.
*/ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, conststruct btrfs_dir_item *di)
{
struct extent_buffer *leaf;
u32 sub_item_len;
u32 item_len; int ret = 0;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.0Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.