|
@@ -213,6 +213,65 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
|
|
return btrfs_match_dir_item_name(root, path, name, name_len);
|
|
return btrfs_match_dir_item_name(root, path, name, name_len);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir,
|
|
|
|
+ const char *name, int name_len)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+ struct btrfs_key key;
|
|
|
|
+ struct btrfs_dir_item *di;
|
|
|
|
+ int data_size;
|
|
|
|
+ struct extent_buffer *leaf;
|
|
|
|
+ int slot;
|
|
|
|
+ struct btrfs_path *path;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ path = btrfs_alloc_path();
|
|
|
|
+ if (!path)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ key.objectid = dir;
|
|
|
|
+ btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
|
|
|
|
+ key.offset = btrfs_name_hash(name, name_len);
|
|
|
|
+
|
|
|
|
+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
|
|
|
+
|
|
|
|
+ /* return back any errors */
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ /* nothing found, we're safe */
|
|
|
|
+ if (ret > 0) {
|
|
|
|
+ ret = 0;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* we found an item, look for our name in the item */
|
|
|
|
+ di = btrfs_match_dir_item_name(root, path, name, name_len);
|
|
|
|
+ if (di) {
|
|
|
|
+ /* our exact name was found */
|
|
|
|
+ ret = -EEXIST;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * see if there is room in the item to insert this
|
|
|
|
+ * name
|
|
|
|
+ */
|
|
|
|
+ data_size = sizeof(*di) + name_len + sizeof(struct btrfs_item);
|
|
|
|
+ leaf = path->nodes[0];
|
|
|
|
+ slot = path->slots[0];
|
|
|
|
+ if (data_size + btrfs_item_size_nr(leaf, slot) +
|
|
|
|
+ sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(root)) {
|
|
|
|
+ ret = -EOVERFLOW;
|
|
|
|
+ } else {
|
|
|
|
+ /* plenty of insertion room */
|
|
|
|
+ ret = 0;
|
|
|
|
+ }
|
|
|
|
+out:
|
|
|
|
+ btrfs_free_path(path);
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* lookup a directory item based on index. 'dir' is the objectid
|
|
* lookup a directory item based on index. 'dir' is the objectid
|
|
* we're searching in, and 'mod' tells us if you plan on deleting the
|
|
* we're searching in, and 'mod' tells us if you plan on deleting the
|