LCOV - code coverage report
Current view: top level - fs/btrfs - inode-item.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 190 0.0 %
Date: 2014-02-18 Functions: 0 11 0.0 %
Branches: 0 100 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2007 Oracle.  All rights reserved.
       3                 :            :  *
       4                 :            :  * This program is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU General Public
       6                 :            :  * License v2 as published by the Free Software Foundation.
       7                 :            :  *
       8                 :            :  * This program is distributed in the hope that it will be useful,
       9                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      10                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      11                 :            :  * General Public License for more details.
      12                 :            :  *
      13                 :            :  * You should have received a copy of the GNU General Public
      14                 :            :  * License along with this program; if not, write to the
      15                 :            :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      16                 :            :  * Boston, MA 021110-1307, USA.
      17                 :            :  */
      18                 :            : 
      19                 :            : #include "ctree.h"
      20                 :            : #include "disk-io.h"
      21                 :            : #include "hash.h"
      22                 :            : #include "transaction.h"
      23                 :            : #include "print-tree.h"
      24                 :            : 
      25                 :          0 : static int find_name_in_backref(struct btrfs_path *path, const char *name,
      26                 :            :                          int name_len, struct btrfs_inode_ref **ref_ret)
      27                 :            : {
      28                 :            :         struct extent_buffer *leaf;
      29                 :            :         struct btrfs_inode_ref *ref;
      30                 :            :         unsigned long ptr;
      31                 :            :         unsigned long name_ptr;
      32                 :            :         u32 item_size;
      33                 :            :         u32 cur_offset = 0;
      34                 :            :         int len;
      35                 :            : 
      36                 :          0 :         leaf = path->nodes[0];
      37                 :          0 :         item_size = btrfs_item_size_nr(leaf, path->slots[0]);
      38                 :          0 :         ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
      39         [ #  # ]:          0 :         while (cur_offset < item_size) {
      40                 :          0 :                 ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
      41                 :          0 :                 len = btrfs_inode_ref_name_len(leaf, ref);
      42                 :          0 :                 name_ptr = (unsigned long)(ref + 1);
      43                 :          0 :                 cur_offset += len + sizeof(*ref);
      44         [ #  # ]:          0 :                 if (len != name_len)
      45                 :          0 :                         continue;
      46         [ #  # ]:          0 :                 if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) {
      47                 :          0 :                         *ref_ret = ref;
      48                 :            :                         return 1;
      49                 :            :                 }
      50                 :            :         }
      51                 :            :         return 0;
      52                 :            : }
      53                 :            : 
      54                 :          0 : int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
      55                 :            :                                    const char *name, int name_len,
      56                 :            :                                    struct btrfs_inode_extref **extref_ret)
      57                 :            : {
      58                 :            :         struct extent_buffer *leaf;
      59                 :            :         struct btrfs_inode_extref *extref;
      60                 :            :         unsigned long ptr;
      61                 :            :         unsigned long name_ptr;
      62                 :            :         u32 item_size;
      63                 :            :         u32 cur_offset = 0;
      64                 :            :         int ref_name_len;
      65                 :            : 
      66                 :          0 :         leaf = path->nodes[0];
      67                 :          0 :         item_size = btrfs_item_size_nr(leaf, path->slots[0]);
      68                 :          0 :         ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
      69                 :            : 
      70                 :            :         /*
      71                 :            :          * Search all extended backrefs in this item. We're only
      72                 :            :          * looking through any collisions so most of the time this is
      73                 :            :          * just going to compare against one buffer. If all is well,
      74                 :            :          * we'll return success and the inode ref object.
      75                 :            :          */
      76         [ #  # ]:          0 :         while (cur_offset < item_size) {
      77                 :          0 :                 extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
      78                 :          0 :                 name_ptr = (unsigned long)(&extref->name);
      79                 :          0 :                 ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
      80                 :            : 
      81   [ #  #  #  # ]:          0 :                 if (ref_name_len == name_len &&
      82         [ #  # ]:          0 :                     btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
      83                 :          0 :                     (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)) {
      84         [ #  # ]:          0 :                         if (extref_ret)
      85                 :          0 :                                 *extref_ret = extref;
      86                 :            :                         return 1;
      87                 :            :                 }
      88                 :            : 
      89                 :          0 :                 cur_offset += ref_name_len + sizeof(*extref);
      90                 :            :         }
      91                 :            :         return 0;
      92                 :            : }
      93                 :            : 
      94                 :            : static struct btrfs_inode_ref *
      95                 :          0 : btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
      96                 :            :                        struct btrfs_root *root,
      97                 :          0 :                        struct btrfs_path *path,
      98                 :            :                        const char *name, int name_len,
      99                 :            :                        u64 inode_objectid, u64 ref_objectid, int ins_len,
     100                 :            :                        int cow)
     101                 :            : {
     102                 :            :         int ret;
     103                 :            :         struct btrfs_key key;
     104                 :            :         struct btrfs_inode_ref *ref;
     105                 :            : 
     106                 :          0 :         key.objectid = inode_objectid;
     107                 :          0 :         key.type = BTRFS_INODE_REF_KEY;
     108                 :          0 :         key.offset = ref_objectid;
     109                 :            : 
     110                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
     111         [ #  # ]:          0 :         if (ret < 0)
     112                 :          0 :                 return ERR_PTR(ret);
     113         [ #  # ]:          0 :         if (ret > 0)
     114                 :            :                 return NULL;
     115         [ #  # ]:          0 :         if (!find_name_in_backref(path, name, name_len, &ref))
     116                 :            :                 return NULL;
     117                 :          0 :         return ref;
     118                 :            : }
     119                 :            : 
     120                 :            : /* Returns NULL if no extref found */
     121                 :            : struct btrfs_inode_extref *
     122                 :          0 : btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
     123                 :            :                           struct btrfs_root *root,
     124                 :            :                           struct btrfs_path *path,
     125                 :            :                           const char *name, int name_len,
     126                 :            :                           u64 inode_objectid, u64 ref_objectid, int ins_len,
     127                 :            :                           int cow)
     128                 :            : {
     129                 :            :         int ret;
     130                 :            :         struct btrfs_key key;
     131                 :            :         struct btrfs_inode_extref *extref;
     132                 :            : 
     133                 :          0 :         key.objectid = inode_objectid;
     134                 :          0 :         key.type = BTRFS_INODE_EXTREF_KEY;
     135                 :          0 :         key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
     136                 :            : 
     137                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
     138         [ #  # ]:          0 :         if (ret < 0)
     139                 :          0 :                 return ERR_PTR(ret);
     140         [ #  # ]:          0 :         if (ret > 0)
     141                 :            :                 return NULL;
     142         [ #  # ]:          0 :         if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref))
     143                 :            :                 return NULL;
     144                 :          0 :         return extref;
     145                 :            : }
     146                 :            : 
     147                 :          0 : int btrfs_get_inode_ref_index(struct btrfs_trans_handle *trans,
     148                 :            :                               struct btrfs_root *root,
     149                 :            :                               struct btrfs_path *path,
     150                 :            :                               const char *name, int name_len,
     151                 :            :                               u64 inode_objectid, u64 ref_objectid, int mod,
     152                 :            :                               u64 *ret_index)
     153                 :            : {
     154                 :            :         struct btrfs_inode_ref *ref;
     155                 :            :         struct btrfs_inode_extref *extref;
     156         [ #  # ]:          0 :         int ins_len = mod < 0 ? -1 : 0;
     157                 :          0 :         int cow = mod != 0;
     158                 :            : 
     159                 :          0 :         ref = btrfs_lookup_inode_ref(trans, root, path, name, name_len,
     160                 :            :                                      inode_objectid, ref_objectid, ins_len,
     161                 :            :                                      cow);
     162         [ #  # ]:          0 :         if (IS_ERR(ref))
     163                 :          0 :                 return PTR_ERR(ref);
     164                 :            : 
     165         [ #  # ]:          0 :         if (ref != NULL) {
     166                 :          0 :                 *ret_index = btrfs_inode_ref_index(path->nodes[0], ref);
     167                 :          0 :                 return 0;
     168                 :            :         }
     169                 :            : 
     170                 :          0 :         btrfs_release_path(path);
     171                 :            : 
     172                 :          0 :         extref = btrfs_lookup_inode_extref(trans, root, path, name,
     173                 :            :                                            name_len, inode_objectid,
     174                 :            :                                            ref_objectid, ins_len, cow);
     175         [ #  # ]:          0 :         if (IS_ERR(extref))
     176                 :          0 :                 return PTR_ERR(extref);
     177                 :            : 
     178         [ #  # ]:          0 :         if (extref) {
     179                 :          0 :                 *ret_index = btrfs_inode_extref_index(path->nodes[0], extref);
     180                 :          0 :                 return 0;
     181                 :            :         }
     182                 :            : 
     183                 :            :         return -ENOENT;
     184                 :            : }
     185                 :            : 
     186                 :          0 : static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
     187                 :            :                                   struct btrfs_root *root,
     188                 :            :                                   const char *name, int name_len,
     189                 :            :                                   u64 inode_objectid, u64 ref_objectid,
     190                 :            :                                   u64 *index)
     191                 :            : {
     192                 :            :         struct btrfs_path *path;
     193                 :            :         struct btrfs_key key;
     194                 :            :         struct btrfs_inode_extref *extref;
     195                 :            :         struct extent_buffer *leaf;
     196                 :            :         int ret;
     197                 :          0 :         int del_len = name_len + sizeof(*extref);
     198                 :            :         unsigned long ptr;
     199                 :            :         unsigned long item_start;
     200                 :            :         u32 item_size;
     201                 :            : 
     202                 :          0 :         key.objectid = inode_objectid;
     203                 :            :         btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
     204                 :          0 :         key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
     205                 :            : 
     206                 :          0 :         path = btrfs_alloc_path();
     207         [ #  # ]:          0 :         if (!path)
     208                 :            :                 return -ENOMEM;
     209                 :            : 
     210                 :          0 :         path->leave_spinning = 1;
     211                 :            : 
     212                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
     213         [ #  # ]:          0 :         if (ret > 0)
     214                 :            :                 ret = -ENOENT;
     215         [ #  # ]:          0 :         if (ret < 0)
     216                 :            :                 goto out;
     217                 :            : 
     218                 :            :         /*
     219                 :            :          * Sanity check - did we find the right item for this name?
     220                 :            :          * This should always succeed so error here will make the FS
     221                 :            :          * readonly.
     222                 :            :          */
     223         [ #  # ]:          0 :         if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
     224                 :            :                                             name, name_len, &extref)) {
     225                 :          0 :                 btrfs_std_error(root->fs_info, -ENOENT);
     226                 :            :                 ret = -EROFS;
     227                 :          0 :                 goto out;
     228                 :            :         }
     229                 :            : 
     230                 :          0 :         leaf = path->nodes[0];
     231                 :          0 :         item_size = btrfs_item_size_nr(leaf, path->slots[0]);
     232         [ #  # ]:          0 :         if (index)
     233                 :          0 :                 *index = btrfs_inode_extref_index(leaf, extref);
     234                 :            : 
     235         [ #  # ]:          0 :         if (del_len == item_size) {
     236                 :            :                 /*
     237                 :            :                  * Common case only one ref in the item, remove the
     238                 :            :                  * whole item.
     239                 :            :                  */
     240                 :            :                 ret = btrfs_del_item(trans, root, path);
     241                 :          0 :                 goto out;
     242                 :            :         }
     243                 :            : 
     244                 :          0 :         ptr = (unsigned long)extref;
     245                 :          0 :         item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
     246                 :            : 
     247                 :          0 :         memmove_extent_buffer(leaf, ptr, ptr + del_len,
     248                 :          0 :                               item_size - (ptr + del_len - item_start));
     249                 :            : 
     250                 :          0 :         btrfs_truncate_item(root, path, item_size - del_len, 1);
     251                 :            : 
     252                 :            : out:
     253                 :          0 :         btrfs_free_path(path);
     254                 :            : 
     255                 :          0 :         return ret;
     256                 :            : }
     257                 :            : 
     258                 :          0 : int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
     259                 :            :                         struct btrfs_root *root,
     260                 :            :                         const char *name, int name_len,
     261                 :            :                         u64 inode_objectid, u64 ref_objectid, u64 *index)
     262                 :            : {
     263                 :          0 :         struct btrfs_path *path;
     264                 :            :         struct btrfs_key key;
     265                 :            :         struct btrfs_inode_ref *ref;
     266                 :            :         struct extent_buffer *leaf;
     267                 :            :         unsigned long ptr;
     268                 :            :         unsigned long item_start;
     269                 :            :         u32 item_size;
     270                 :            :         u32 sub_item_len;
     271                 :            :         int ret;
     272                 :            :         int search_ext_refs = 0;
     273                 :          0 :         int del_len = name_len + sizeof(*ref);
     274                 :            : 
     275                 :          0 :         key.objectid = inode_objectid;
     276                 :          0 :         key.offset = ref_objectid;
     277                 :            :         btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY);
     278                 :            : 
     279                 :          0 :         path = btrfs_alloc_path();
     280         [ #  # ]:          0 :         if (!path)
     281                 :            :                 return -ENOMEM;
     282                 :            : 
     283                 :          0 :         path->leave_spinning = 1;
     284                 :            : 
     285                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
     286         [ #  # ]:          0 :         if (ret > 0) {
     287                 :            :                 ret = -ENOENT;
     288                 :            :                 search_ext_refs = 1;
     289                 :            :                 goto out;
     290         [ #  # ]:          0 :         } else if (ret < 0) {
     291                 :            :                 goto out;
     292                 :            :         }
     293         [ #  # ]:          0 :         if (!find_name_in_backref(path, name, name_len, &ref)) {
     294                 :            :                 ret = -ENOENT;
     295                 :            :                 search_ext_refs = 1;
     296                 :            :                 goto out;
     297                 :            :         }
     298                 :          0 :         leaf = path->nodes[0];
     299                 :          0 :         item_size = btrfs_item_size_nr(leaf, path->slots[0]);
     300                 :            : 
     301         [ #  # ]:          0 :         if (index)
     302                 :          0 :                 *index = btrfs_inode_ref_index(leaf, ref);
     303                 :            : 
     304         [ #  # ]:          0 :         if (del_len == item_size) {
     305                 :            :                 ret = btrfs_del_item(trans, root, path);
     306                 :          0 :                 goto out;
     307                 :            :         }
     308                 :          0 :         ptr = (unsigned long)ref;
     309                 :            :         sub_item_len = name_len + sizeof(*ref);
     310                 :          0 :         item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
     311                 :          0 :         memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
     312                 :          0 :                               item_size - (ptr + sub_item_len - item_start));
     313                 :          0 :         btrfs_truncate_item(root, path, item_size - sub_item_len, 1);
     314                 :            : out:
     315                 :          0 :         btrfs_free_path(path);
     316                 :            : 
     317         [ #  # ]:          0 :         if (search_ext_refs) {
     318                 :            :                 /*
     319                 :            :                  * No refs were found, or we could not find the
     320                 :            :                  * name in our ref array. Find and remove the extended
     321                 :            :                  * inode ref then.
     322                 :            :                  */
     323                 :          0 :                 return btrfs_del_inode_extref(trans, root, name, name_len,
     324                 :            :                                               inode_objectid, ref_objectid, index);
     325                 :            :         }
     326                 :            : 
     327                 :            :         return ret;
     328                 :            : }
     329                 :            : 
     330                 :            : /*
     331                 :            :  * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
     332                 :            :  *
     333                 :            :  * The caller must have checked against BTRFS_LINK_MAX already.
     334                 :            :  */
     335                 :          0 : static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
     336                 :            :                                      struct btrfs_root *root,
     337                 :            :                                      const char *name, int name_len,
     338                 :            :                                      u64 inode_objectid, u64 ref_objectid, u64 index)
     339                 :            : {
     340                 :            :         struct btrfs_inode_extref *extref;
     341                 :            :         int ret;
     342                 :          0 :         int ins_len = name_len + sizeof(*extref);
     343                 :            :         unsigned long ptr;
     344                 :            :         struct btrfs_path *path;
     345                 :            :         struct btrfs_key key;
     346                 :            :         struct extent_buffer *leaf;
     347                 :            :         struct btrfs_item *item;
     348                 :            : 
     349                 :          0 :         key.objectid = inode_objectid;
     350                 :          0 :         key.type = BTRFS_INODE_EXTREF_KEY;
     351                 :          0 :         key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
     352                 :            : 
     353                 :          0 :         path = btrfs_alloc_path();
     354         [ #  # ]:          0 :         if (!path)
     355                 :            :                 return -ENOMEM;
     356                 :            : 
     357                 :          0 :         path->leave_spinning = 1;
     358                 :            :         ret = btrfs_insert_empty_item(trans, root, path, &key,
     359                 :            :                                       ins_len);
     360         [ #  # ]:          0 :         if (ret == -EEXIST) {
     361         [ #  # ]:          0 :                 if (btrfs_find_name_in_ext_backref(path, ref_objectid,
     362                 :            :                                                    name, name_len, NULL))
     363                 :            :                         goto out;
     364                 :            : 
     365                 :          0 :                 btrfs_extend_item(root, path, ins_len);
     366                 :            :                 ret = 0;
     367                 :            :         }
     368         [ #  # ]:          0 :         if (ret < 0)
     369                 :            :                 goto out;
     370                 :            : 
     371                 :          0 :         leaf = path->nodes[0];
     372                 :          0 :         item = btrfs_item_nr(path->slots[0]);
     373                 :          0 :         ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
     374                 :          0 :         ptr += btrfs_item_size(leaf, item) - ins_len;
     375                 :          0 :         extref = (struct btrfs_inode_extref *)ptr;
     376                 :            : 
     377                 :          0 :         btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len);
     378                 :          0 :         btrfs_set_inode_extref_index(path->nodes[0], extref, index);
     379                 :          0 :         btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
     380                 :            : 
     381                 :          0 :         ptr = (unsigned long)&extref->name;
     382                 :          0 :         write_extent_buffer(path->nodes[0], name, ptr, name_len);
     383                 :          0 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     384                 :            : 
     385                 :            : out:
     386                 :          0 :         btrfs_free_path(path);
     387                 :          0 :         return ret;
     388                 :            : }
     389                 :            : 
     390                 :            : /* Will return 0, -ENOMEM, -EMLINK, or -EEXIST or anything from the CoW path */
     391                 :          0 : int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
     392                 :            :                            struct btrfs_root *root,
     393                 :            :                            const char *name, int name_len,
     394                 :            :                            u64 inode_objectid, u64 ref_objectid, u64 index)
     395                 :            : {
     396                 :          0 :         struct btrfs_path *path;
     397                 :            :         struct btrfs_key key;
     398                 :            :         struct btrfs_inode_ref *ref;
     399                 :            :         unsigned long ptr;
     400                 :            :         int ret;
     401                 :          0 :         int ins_len = name_len + sizeof(*ref);
     402                 :            : 
     403                 :          0 :         key.objectid = inode_objectid;
     404                 :          0 :         key.offset = ref_objectid;
     405                 :            :         btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY);
     406                 :            : 
     407                 :          0 :         path = btrfs_alloc_path();
     408         [ #  # ]:          0 :         if (!path)
     409                 :            :                 return -ENOMEM;
     410                 :            : 
     411                 :          0 :         path->leave_spinning = 1;
     412                 :            :         ret = btrfs_insert_empty_item(trans, root, path, &key,
     413                 :            :                                       ins_len);
     414         [ #  # ]:          0 :         if (ret == -EEXIST) {
     415                 :            :                 u32 old_size;
     416                 :            : 
     417         [ #  # ]:          0 :                 if (find_name_in_backref(path, name, name_len, &ref))
     418                 :            :                         goto out;
     419                 :            : 
     420                 :          0 :                 old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
     421                 :          0 :                 btrfs_extend_item(root, path, ins_len);
     422                 :          0 :                 ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
     423                 :            :                                      struct btrfs_inode_ref);
     424                 :          0 :                 ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
     425                 :          0 :                 btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
     426                 :          0 :                 btrfs_set_inode_ref_index(path->nodes[0], ref, index);
     427                 :          0 :                 ptr = (unsigned long)(ref + 1);
     428                 :            :                 ret = 0;
     429         [ #  # ]:          0 :         } else if (ret < 0) {
     430         [ #  # ]:          0 :                 if (ret == -EOVERFLOW)
     431                 :            :                         ret = -EMLINK;
     432                 :            :                 goto out;
     433                 :            :         } else {
     434                 :          0 :                 ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
     435                 :            :                                      struct btrfs_inode_ref);
     436                 :          0 :                 btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
     437                 :          0 :                 btrfs_set_inode_ref_index(path->nodes[0], ref, index);
     438                 :          0 :                 ptr = (unsigned long)(ref + 1);
     439                 :            :         }
     440                 :          0 :         write_extent_buffer(path->nodes[0], name, ptr, name_len);
     441                 :          0 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     442                 :            : 
     443                 :            : out:
     444                 :          0 :         btrfs_free_path(path);
     445                 :            : 
     446         [ #  # ]:          0 :         if (ret == -EMLINK) {
     447                 :          0 :                 struct btrfs_super_block *disk_super = root->fs_info->super_copy;
     448                 :            :                 /* We ran out of space in the ref array. Need to
     449                 :            :                  * add an extended ref. */
     450         [ #  # ]:          0 :                 if (btrfs_super_incompat_flags(disk_super)
     451                 :          0 :                     & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
     452                 :          0 :                         ret = btrfs_insert_inode_extref(trans, root, name,
     453                 :            :                                                         name_len,
     454                 :            :                                                         inode_objectid,
     455                 :            :                                                         ref_objectid, index);
     456                 :            :         }
     457                 :            : 
     458                 :          0 :         return ret;
     459                 :            : }
     460                 :            : 
     461                 :          0 : int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
     462                 :            :                              struct btrfs_root *root,
     463                 :            :                              struct btrfs_path *path, u64 objectid)
     464                 :            : {
     465                 :            :         struct btrfs_key key;
     466                 :            :         int ret;
     467                 :          0 :         key.objectid = objectid;
     468                 :            :         btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
     469                 :          0 :         key.offset = 0;
     470                 :            : 
     471                 :            :         ret = btrfs_insert_empty_item(trans, root, path, &key,
     472                 :            :                                       sizeof(struct btrfs_inode_item));
     473                 :          0 :         return ret;
     474                 :            : }
     475                 :            : 
     476                 :          0 : int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
     477                 :            :                        *root, struct btrfs_path *path,
     478                 :          0 :                        struct btrfs_key *location, int mod)
     479                 :            : {
     480         [ #  # ]:          0 :         int ins_len = mod < 0 ? -1 : 0;
     481                 :          0 :         int cow = mod != 0;
     482                 :            :         int ret;
     483                 :            :         int slot;
     484                 :            :         struct extent_buffer *leaf;
     485                 :            :         struct btrfs_key found_key;
     486                 :            : 
     487                 :          0 :         ret = btrfs_search_slot(trans, root, location, path, ins_len, cow);
     488 [ #  # ][ #  # ]:          0 :         if (ret > 0 && btrfs_key_type(location) == BTRFS_ROOT_ITEM_KEY &&
                 [ #  # ]
     489         [ #  # ]:          0 :             location->offset == (u64)-1 && path->slots[0] != 0) {
     490                 :          0 :                 slot = path->slots[0] - 1;
     491                 :          0 :                 leaf = path->nodes[0];
     492                 :            :                 btrfs_item_key_to_cpu(leaf, &found_key, slot);
     493 [ #  # ][ #  # ]:          0 :                 if (found_key.objectid == location->objectid &&
     494                 :            :                     btrfs_key_type(&found_key) == btrfs_key_type(location)) {
     495                 :          0 :                         path->slots[0]--;
     496                 :          0 :                         return 0;
     497                 :            :                 }
     498                 :            :         }
     499                 :          0 :         return ret;
     500                 :            : }

Generated by: LCOV version 1.9