ecryptfs: Fix refcnt leak on ecryptfs_follow_link() error path
[safe/jmp/linux-2.6] / fs / btrfs / inode-item.c
index cba30b6..72ce3c1 100644 (file)
@@ -20,7 +20,7 @@
 #include "disk-io.h"
 #include "transaction.h"
 
-int find_name_in_backref(struct btrfs_path *path, const char * name,
+static int find_name_in_backref(struct btrfs_path *path, const char *name,
                         int name_len, struct btrfs_inode_ref **ref_ret)
 {
        struct extent_buffer *leaf;
@@ -52,7 +52,7 @@ int find_name_in_backref(struct btrfs_path *path, const char * name,
 int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root,
                           const char *name, int name_len,
-                          u64 inode_objectid, u64 ref_objectid)
+                          u64 inode_objectid, u64 ref_objectid, u64 *index)
 {
        struct btrfs_path *path;
        struct btrfs_key key;
@@ -73,6 +73,8 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
        if (!path)
                return -ENOMEM;
 
+       path->leave_spinning = 1;
+
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
        if (ret > 0) {
                ret = -ENOENT;
@@ -86,6 +88,10 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
        }
        leaf = path->nodes[0];
        item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+
+       if (index)
+               *index = btrfs_inode_ref_index(leaf, ref);
+
        if (del_len == item_size) {
                ret = btrfs_del_item(trans, root, path);
                goto out;
@@ -106,7 +112,7 @@ out:
 int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root,
                           const char *name, int name_len,
-                          u64 inode_objectid, u64 ref_objectid)
+                          u64 inode_objectid, u64 ref_objectid, u64 index)
 {
        struct btrfs_path *path;
        struct btrfs_key key;
@@ -123,6 +129,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
        if (!path)
                return -ENOMEM;
 
+       path->leave_spinning = 1;
        ret = btrfs_insert_empty_item(trans, root, path, &key,
                                      ins_len);
        if (ret == -EEXIST) {
@@ -138,14 +145,18 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
                                     struct btrfs_inode_ref);
                ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
                btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
+               btrfs_set_inode_ref_index(path->nodes[0], ref, index);
                ptr = (unsigned long)(ref + 1);
                ret = 0;
        } else if (ret < 0) {
+               if (ret == -EOVERFLOW)
+                       ret = -EMLINK;
                goto out;
        } else {
                ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
                                     struct btrfs_inode_ref);
                btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
+               btrfs_set_inode_ref_index(path->nodes[0], ref, index);
                ptr = (unsigned long)(ref + 1);
        }
        write_extent_buffer(path->nodes[0], name, ptr, name_len);
@@ -168,8 +179,6 @@ int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
 
        ret = btrfs_insert_empty_item(trans, root, path, &key,
                                      sizeof(struct btrfs_inode_item));
-       if (ret == 0 && objectid > root->highest_inode)
-               root->highest_inode = objectid;
        return ret;
 }