]> Pileus Git - ~andy/linux/blobdiff - fs/btrfs/dir-item.c
Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
[~andy/linux] / fs / btrfs / dir-item.c
index c1a074d0696ff897258c576c127af7fd8d513846..502c2158167c8fb95578f8166a9802a34e762def 100644 (file)
@@ -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);
 }
 
+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
  * we're searching in, and 'mod' tells us if you plan on deleting the