LCOV - code coverage report
Current view: top level - fs/btrfs - dir-item.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 162 0.0 %
Date: 2014-02-18 Functions: 0 11 0.0 %
Branches: 0 84 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                 :            : 
      24                 :            : static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
      25                 :            :                               struct btrfs_path *path,
      26                 :            :                               const char *name, int name_len);
      27                 :            : 
      28                 :            : /*
      29                 :            :  * insert a name into a directory, doing overflow properly if there is a hash
      30                 :            :  * collision.  data_size indicates how big the item inserted should be.  On
      31                 :            :  * success a struct btrfs_dir_item pointer is returned, otherwise it is
      32                 :            :  * an ERR_PTR.
      33                 :            :  *
      34                 :            :  * The name is not copied into the dir item, you have to do that yourself.
      35                 :            :  */
      36                 :          0 : static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
      37                 :            :                                                    *trans,
      38                 :            :                                                    struct btrfs_root *root,
      39                 :          0 :                                                    struct btrfs_path *path,
      40                 :            :                                                    struct btrfs_key *cpu_key,
      41                 :            :                                                    u32 data_size,
      42                 :            :                                                    const char *name,
      43                 :            :                                                    int name_len)
      44                 :            : {
      45                 :            :         int ret;
      46                 :            :         char *ptr;
      47                 :            :         struct btrfs_item *item;
      48                 :            :         struct extent_buffer *leaf;
      49                 :            : 
      50                 :            :         ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
      51         [ #  # ]:          0 :         if (ret == -EEXIST) {
      52                 :            :                 struct btrfs_dir_item *di;
      53                 :          0 :                 di = btrfs_match_dir_item_name(root, path, name, name_len);
      54         [ #  # ]:          0 :                 if (di)
      55                 :            :                         return ERR_PTR(-EEXIST);
      56                 :          0 :                 btrfs_extend_item(root, path, data_size);
      57         [ #  # ]:          0 :         } else if (ret < 0)
      58                 :          0 :                 return ERR_PTR(ret);
      59         [ #  # ]:          0 :         WARN_ON(ret > 0);
      60                 :          0 :         leaf = path->nodes[0];
      61                 :          0 :         item = btrfs_item_nr(path->slots[0]);
      62                 :          0 :         ptr = btrfs_item_ptr(leaf, path->slots[0], char);
      63         [ #  # ]:          0 :         BUG_ON(data_size > btrfs_item_size(leaf, item));
      64                 :          0 :         ptr += btrfs_item_size(leaf, item) - data_size;
      65                 :          0 :         return (struct btrfs_dir_item *)ptr;
      66                 :            : }
      67                 :            : 
      68                 :            : /*
      69                 :            :  * xattrs work a lot like directories, this inserts an xattr item
      70                 :            :  * into the tree
      71                 :            :  */
      72                 :          0 : int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans,
      73                 :            :                             struct btrfs_root *root,
      74                 :            :                             struct btrfs_path *path, u64 objectid,
      75                 :            :                             const char *name, u16 name_len,
      76                 :            :                             const void *data, u16 data_len)
      77                 :            : {
      78                 :            :         int ret = 0;
      79                 :            :         struct btrfs_dir_item *dir_item;
      80                 :            :         unsigned long name_ptr, data_ptr;
      81                 :            :         struct btrfs_key key, location;
      82                 :            :         struct btrfs_disk_key disk_key;
      83                 :            :         struct extent_buffer *leaf;
      84                 :            :         u32 data_size;
      85                 :            : 
      86         [ #  # ]:          0 :         BUG_ON(name_len + data_len > BTRFS_MAX_XATTR_SIZE(root));
      87                 :            : 
      88                 :          0 :         key.objectid = objectid;
      89                 :            :         btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
      90                 :          0 :         key.offset = btrfs_name_hash(name, name_len);
      91                 :            : 
      92                 :          0 :         data_size = sizeof(*dir_item) + name_len + data_len;
      93                 :          0 :         dir_item = insert_with_overflow(trans, root, path, &key, data_size,
      94                 :            :                                         name, name_len);
      95         [ #  # ]:          0 :         if (IS_ERR(dir_item))
      96                 :          0 :                 return PTR_ERR(dir_item);
      97                 :          0 :         memset(&location, 0, sizeof(location));
      98                 :            : 
      99                 :          0 :         leaf = path->nodes[0];
     100                 :            :         btrfs_cpu_key_to_disk(&disk_key, &location);
     101                 :            :         btrfs_set_dir_item_key(leaf, dir_item, &disk_key);
     102                 :            :         btrfs_set_dir_type(leaf, dir_item, BTRFS_FT_XATTR);
     103                 :            :         btrfs_set_dir_name_len(leaf, dir_item, name_len);
     104                 :          0 :         btrfs_set_dir_transid(leaf, dir_item, trans->transid);
     105                 :            :         btrfs_set_dir_data_len(leaf, dir_item, data_len);
     106                 :          0 :         name_ptr = (unsigned long)(dir_item + 1);
     107                 :          0 :         data_ptr = (unsigned long)((char *)name_ptr + name_len);
     108                 :            : 
     109                 :          0 :         write_extent_buffer(leaf, name, name_ptr, name_len);
     110                 :          0 :         write_extent_buffer(leaf, data, data_ptr, data_len);
     111                 :          0 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     112                 :            : 
     113                 :          0 :         return ret;
     114                 :            : }
     115                 :            : 
     116                 :            : /*
     117                 :            :  * insert a directory item in the tree, doing all the magic for
     118                 :            :  * both indexes. 'dir' indicates which objectid to insert it into,
     119                 :            :  * 'location' is the key to stuff into the directory item, 'type' is the
     120                 :            :  * type of the inode we're pointing to, and 'index' is the sequence number
     121                 :            :  * to use for the second index (if one is created).
     122                 :            :  * Will return 0 or -ENOMEM
     123                 :            :  */
     124                 :          0 : int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
     125                 :            :                           *root, const char *name, int name_len,
     126                 :            :                           struct inode *dir, struct btrfs_key *location,
     127                 :            :                           u8 type, u64 index)
     128                 :            : {
     129                 :            :         int ret = 0;
     130                 :            :         int ret2 = 0;
     131                 :            :         struct btrfs_path *path;
     132                 :            :         struct btrfs_dir_item *dir_item;
     133                 :            :         struct extent_buffer *leaf;
     134                 :            :         unsigned long name_ptr;
     135                 :            :         struct btrfs_key key;
     136                 :            :         struct btrfs_disk_key disk_key;
     137                 :            :         u32 data_size;
     138                 :            : 
     139                 :          0 :         key.objectid = btrfs_ino(dir);
     140                 :            :         btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
     141                 :          0 :         key.offset = btrfs_name_hash(name, name_len);
     142                 :            : 
     143                 :          0 :         path = btrfs_alloc_path();
     144         [ #  # ]:          0 :         if (!path)
     145                 :            :                 return -ENOMEM;
     146                 :          0 :         path->leave_spinning = 1;
     147                 :            : 
     148                 :            :         btrfs_cpu_key_to_disk(&disk_key, location);
     149                 :            : 
     150                 :          0 :         data_size = sizeof(*dir_item) + name_len;
     151                 :          0 :         dir_item = insert_with_overflow(trans, root, path, &key, data_size,
     152                 :            :                                         name, name_len);
     153         [ #  # ]:          0 :         if (IS_ERR(dir_item)) {
     154                 :            :                 ret = PTR_ERR(dir_item);
     155         [ #  # ]:          0 :                 if (ret == -EEXIST)
     156                 :            :                         goto second_insert;
     157                 :            :                 goto out_free;
     158                 :            :         }
     159                 :            : 
     160                 :          0 :         leaf = path->nodes[0];
     161                 :            :         btrfs_set_dir_item_key(leaf, dir_item, &disk_key);
     162                 :            :         btrfs_set_dir_type(leaf, dir_item, type);
     163                 :            :         btrfs_set_dir_data_len(leaf, dir_item, 0);
     164                 :          0 :         btrfs_set_dir_name_len(leaf, dir_item, name_len);
     165                 :          0 :         btrfs_set_dir_transid(leaf, dir_item, trans->transid);
     166                 :          0 :         name_ptr = (unsigned long)(dir_item + 1);
     167                 :            : 
     168                 :          0 :         write_extent_buffer(leaf, name, name_ptr, name_len);
     169                 :          0 :         btrfs_mark_buffer_dirty(leaf);
     170                 :            : 
     171                 :            : second_insert:
     172                 :            :         /* FIXME, use some real flag for selecting the extra index */
     173         [ #  # ]:          0 :         if (root == root->fs_info->tree_root) {
     174                 :            :                 ret = 0;
     175                 :            :                 goto out_free;
     176                 :            :         }
     177                 :          0 :         btrfs_release_path(path);
     178                 :            : 
     179                 :          0 :         ret2 = btrfs_insert_delayed_dir_index(trans, root, name, name_len, dir,
     180                 :            :                                               &disk_key, type, index);
     181                 :            : out_free:
     182                 :          0 :         btrfs_free_path(path);
     183         [ #  # ]:          0 :         if (ret)
     184                 :            :                 return ret;
     185         [ #  # ]:          0 :         if (ret2)
     186                 :          0 :                 return ret2;
     187                 :            :         return 0;
     188                 :            : }
     189                 :            : 
     190                 :            : /*
     191                 :            :  * lookup a directory item based on name.  'dir' is the objectid
     192                 :            :  * we're searching in, and 'mod' tells us if you plan on deleting the
     193                 :            :  * item (use mod < 0) or changing the options (use mod > 0)
     194                 :            :  */
     195                 :          0 : struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
     196                 :            :                                              struct btrfs_root *root,
     197                 :          0 :                                              struct btrfs_path *path, u64 dir,
     198                 :            :                                              const char *name, int name_len,
     199                 :            :                                              int mod)
     200                 :            : {
     201                 :            :         int ret;
     202                 :            :         struct btrfs_key key;
     203         [ #  # ]:          0 :         int ins_len = mod < 0 ? -1 : 0;
     204                 :          0 :         int cow = mod != 0;
     205                 :            : 
     206                 :          0 :         key.objectid = dir;
     207                 :            :         btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
     208                 :            : 
     209                 :          0 :         key.offset = btrfs_name_hash(name, name_len);
     210                 :            : 
     211                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
     212         [ #  # ]:          0 :         if (ret < 0)
     213                 :          0 :                 return ERR_PTR(ret);
     214         [ #  # ]:          0 :         if (ret > 0)
     215                 :            :                 return NULL;
     216                 :            : 
     217                 :          0 :         return btrfs_match_dir_item_name(root, path, name, name_len);
     218                 :            : }
     219                 :            : 
     220                 :          0 : int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir,
     221                 :            :                                    const char *name, int name_len)
     222                 :            : {
     223                 :            :         int ret;
     224                 :            :         struct btrfs_key key;
     225                 :            :         struct btrfs_dir_item *di;
     226                 :            :         int data_size;
     227                 :            :         struct extent_buffer *leaf;
     228                 :            :         int slot;
     229                 :          0 :         struct btrfs_path *path;
     230                 :            : 
     231                 :            : 
     232                 :          0 :         path = btrfs_alloc_path();
     233         [ #  # ]:          0 :         if (!path)
     234                 :            :                 return -ENOMEM;
     235                 :            : 
     236                 :          0 :         key.objectid = dir;
     237                 :            :         btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
     238                 :          0 :         key.offset = btrfs_name_hash(name, name_len);
     239                 :            : 
     240                 :          0 :         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
     241                 :            : 
     242                 :            :         /* return back any errors */
     243         [ #  # ]:          0 :         if (ret < 0)
     244                 :            :                 goto out;
     245                 :            : 
     246                 :            :         /* nothing found, we're safe */
     247         [ #  # ]:          0 :         if (ret > 0) {
     248                 :            :                 ret = 0;
     249                 :            :                 goto out;
     250                 :            :         }
     251                 :            : 
     252                 :            :         /* we found an item, look for our name in the item */
     253                 :          0 :         di = btrfs_match_dir_item_name(root, path, name, name_len);
     254         [ #  # ]:          0 :         if (di) {
     255                 :            :                 /* our exact name was found */
     256                 :            :                 ret = -EEXIST;
     257                 :            :                 goto out;
     258                 :            :         }
     259                 :            : 
     260                 :            :         /*
     261                 :            :          * see if there is room in the item to insert this
     262                 :            :          * name
     263                 :            :          */
     264                 :          0 :         data_size = sizeof(*di) + name_len + sizeof(struct btrfs_item);
     265                 :          0 :         leaf = path->nodes[0];
     266                 :          0 :         slot = path->slots[0];
     267         [ #  # ]:          0 :         if (data_size + btrfs_item_size_nr(leaf, slot) +
     268                 :          0 :             sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(root)) {
     269                 :            :                 ret = -EOVERFLOW;
     270                 :            :         } else {
     271                 :            :                 /* plenty of insertion room */
     272                 :            :                 ret = 0;
     273                 :            :         }
     274                 :            : out:
     275                 :          0 :         btrfs_free_path(path);
     276                 :          0 :         return ret;
     277                 :            : }
     278                 :            : 
     279                 :            : /*
     280                 :            :  * lookup a directory item based on index.  'dir' is the objectid
     281                 :            :  * we're searching in, and 'mod' tells us if you plan on deleting the
     282                 :            :  * item (use mod < 0) or changing the options (use mod > 0)
     283                 :            :  *
     284                 :            :  * The name is used to make sure the index really points to the name you were
     285                 :            :  * looking for.
     286                 :            :  */
     287                 :            : struct btrfs_dir_item *
     288                 :          0 : btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
     289                 :            :                             struct btrfs_root *root,
     290                 :          0 :                             struct btrfs_path *path, u64 dir,
     291                 :            :                             u64 objectid, const char *name, int name_len,
     292                 :            :                             int mod)
     293                 :            : {
     294                 :            :         int ret;
     295                 :            :         struct btrfs_key key;
     296         [ #  # ]:          0 :         int ins_len = mod < 0 ? -1 : 0;
     297                 :          0 :         int cow = mod != 0;
     298                 :            : 
     299                 :          0 :         key.objectid = dir;
     300                 :            :         btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
     301                 :          0 :         key.offset = objectid;
     302                 :            : 
     303                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
     304         [ #  # ]:          0 :         if (ret < 0)
     305                 :          0 :                 return ERR_PTR(ret);
     306         [ #  # ]:          0 :         if (ret > 0)
     307                 :            :                 return ERR_PTR(-ENOENT);
     308                 :          0 :         return btrfs_match_dir_item_name(root, path, name, name_len);
     309                 :            : }
     310                 :            : 
     311                 :            : struct btrfs_dir_item *
     312                 :          0 : btrfs_search_dir_index_item(struct btrfs_root *root,
     313                 :          0 :                             struct btrfs_path *path, u64 dirid,
     314                 :            :                             const char *name, int name_len)
     315                 :            : {
     316                 :          0 :         struct extent_buffer *leaf;
     317                 :            :         struct btrfs_dir_item *di;
     318                 :            :         struct btrfs_key key;
     319                 :            :         u32 nritems;
     320                 :            :         int ret;
     321                 :            : 
     322                 :          0 :         key.objectid = dirid;
     323                 :          0 :         key.type = BTRFS_DIR_INDEX_KEY;
     324                 :          0 :         key.offset = 0;
     325                 :            : 
     326                 :          0 :         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
     327         [ #  # ]:          0 :         if (ret < 0)
     328                 :          0 :                 return ERR_PTR(ret);
     329                 :            : 
     330                 :          0 :         leaf = path->nodes[0];
     331                 :            :         nritems = btrfs_header_nritems(leaf);
     332                 :            : 
     333                 :            :         while (1) {
     334         [ #  # ]:          0 :                 if (path->slots[0] >= nritems) {
     335                 :          0 :                         ret = btrfs_next_leaf(root, path);
     336         [ #  # ]:          0 :                         if (ret < 0)
     337                 :          0 :                                 return ERR_PTR(ret);
     338         [ #  # ]:          0 :                         if (ret > 0)
     339                 :            :                                 break;
     340                 :          0 :                         leaf = path->nodes[0];
     341                 :            :                         nritems = btrfs_header_nritems(leaf);
     342                 :          0 :                         continue;
     343                 :            :                 }
     344                 :            : 
     345                 :            :                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
     346 [ #  # ][ #  # ]:          0 :                 if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY)
     347                 :            :                         break;
     348                 :            : 
     349                 :          0 :                 di = btrfs_match_dir_item_name(root, path, name, name_len);
     350         [ #  # ]:          0 :                 if (di)
     351                 :            :                         return di;
     352                 :            : 
     353                 :          0 :                 path->slots[0]++;
     354                 :            :         }
     355                 :            :         return NULL;
     356                 :            : }
     357                 :            : 
     358                 :          0 : struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans,
     359                 :            :                                           struct btrfs_root *root,
     360                 :          0 :                                           struct btrfs_path *path, u64 dir,
     361                 :            :                                           const char *name, u16 name_len,
     362                 :            :                                           int mod)
     363                 :            : {
     364                 :            :         int ret;
     365                 :            :         struct btrfs_key key;
     366         [ #  # ]:          0 :         int ins_len = mod < 0 ? -1 : 0;
     367                 :          0 :         int cow = mod != 0;
     368                 :            : 
     369                 :          0 :         key.objectid = dir;
     370                 :            :         btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
     371                 :          0 :         key.offset = btrfs_name_hash(name, name_len);
     372                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
     373         [ #  # ]:          0 :         if (ret < 0)
     374                 :          0 :                 return ERR_PTR(ret);
     375         [ #  # ]:          0 :         if (ret > 0)
     376                 :            :                 return NULL;
     377                 :            : 
     378                 :          0 :         return btrfs_match_dir_item_name(root, path, name, name_len);
     379                 :            : }
     380                 :            : 
     381                 :            : /*
     382                 :            :  * helper function to look at the directory item pointed to by 'path'
     383                 :            :  * this walks through all the entries in a dir item and finds one
     384                 :            :  * for a specific name.
     385                 :            :  */
     386                 :          0 : static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
     387                 :            :                               struct btrfs_path *path,
     388                 :            :                               const char *name, int name_len)
     389                 :            : {
     390                 :            :         struct btrfs_dir_item *dir_item;
     391                 :            :         unsigned long name_ptr;
     392                 :            :         u32 total_len;
     393                 :            :         u32 cur = 0;
     394                 :            :         u32 this_len;
     395                 :            :         struct extent_buffer *leaf;
     396                 :            : 
     397                 :          0 :         leaf = path->nodes[0];
     398                 :          0 :         dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
     399         [ #  # ]:          0 :         if (verify_dir_item(root, leaf, dir_item))
     400                 :            :                 return NULL;
     401                 :            : 
     402                 :          0 :         total_len = btrfs_item_size_nr(leaf, path->slots[0]);
     403         [ #  # ]:          0 :         while (cur < total_len) {
     404                 :          0 :                 this_len = sizeof(*dir_item) +
     405                 :          0 :                         btrfs_dir_name_len(leaf, dir_item) +
     406                 :            :                         btrfs_dir_data_len(leaf, dir_item);
     407                 :          0 :                 name_ptr = (unsigned long)(dir_item + 1);
     408                 :            : 
     409   [ #  #  #  # ]:          0 :                 if (btrfs_dir_name_len(leaf, dir_item) == name_len &&
     410                 :          0 :                     memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)
     411                 :            :                         return dir_item;
     412                 :            : 
     413                 :          0 :                 cur += this_len;
     414                 :          0 :                 dir_item = (struct btrfs_dir_item *)((char *)dir_item +
     415                 :            :                                                      this_len);
     416                 :            :         }
     417                 :            :         return NULL;
     418                 :            : }
     419                 :            : 
     420                 :            : /*
     421                 :            :  * given a pointer into a directory item, delete it.  This
     422                 :            :  * handles items that have more than one entry in them.
     423                 :            :  */
     424                 :          0 : int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
     425                 :            :                               struct btrfs_root *root,
     426                 :            :                               struct btrfs_path *path,
     427                 :            :                               struct btrfs_dir_item *di)
     428                 :            : {
     429                 :            : 
     430                 :            :         struct extent_buffer *leaf;
     431                 :            :         u32 sub_item_len;
     432                 :            :         u32 item_len;
     433                 :            :         int ret = 0;
     434                 :            : 
     435                 :          0 :         leaf = path->nodes[0];
     436                 :          0 :         sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di) +
     437                 :            :                 btrfs_dir_data_len(leaf, di);
     438                 :          0 :         item_len = btrfs_item_size_nr(leaf, path->slots[0]);
     439         [ #  # ]:          0 :         if (sub_item_len == item_len) {
     440                 :            :                 ret = btrfs_del_item(trans, root, path);
     441                 :            :         } else {
     442                 :            :                 /* MARKER */
     443                 :          0 :                 unsigned long ptr = (unsigned long)di;
     444                 :            :                 unsigned long start;
     445                 :            : 
     446                 :          0 :                 start = btrfs_item_ptr_offset(leaf, path->slots[0]);
     447                 :          0 :                 memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
     448                 :          0 :                         item_len - (ptr + sub_item_len - start));
     449                 :          0 :                 btrfs_truncate_item(root, path, item_len - sub_item_len, 1);
     450                 :            :         }
     451                 :          0 :         return ret;
     452                 :            : }
     453                 :            : 
     454                 :          0 : int verify_dir_item(struct btrfs_root *root,
     455                 :            :                     struct extent_buffer *leaf,
     456                 :            :                     struct btrfs_dir_item *dir_item)
     457                 :            : {
     458                 :            :         u16 namelen = BTRFS_NAME_LEN;
     459                 :            :         u8 type = btrfs_dir_type(leaf, dir_item);
     460                 :            : 
     461         [ #  # ]:          0 :         if (type >= BTRFS_FT_MAX) {
     462                 :          0 :                 printk(KERN_CRIT "btrfs: invalid dir item type: %d\n",
     463                 :            :                        (int)type);
     464                 :          0 :                 return 1;
     465                 :            :         }
     466                 :            : 
     467                 :            :         if (type == BTRFS_FT_XATTR)
     468                 :            :                 namelen = XATTR_NAME_MAX;
     469                 :            : 
     470         [ #  # ]:          0 :         if (btrfs_dir_name_len(leaf, dir_item) > namelen) {
     471                 :          0 :                 printk(KERN_CRIT "btrfs: invalid dir item name len: %u\n",
     472                 :            :                        (unsigned)btrfs_dir_data_len(leaf, dir_item));
     473                 :          0 :                 return 1;
     474                 :            :         }
     475                 :            : 
     476                 :            :         /* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
     477         [ #  # ]:          0 :         if ((btrfs_dir_data_len(leaf, dir_item) +
     478                 :          0 :              btrfs_dir_name_len(leaf, dir_item)) > BTRFS_MAX_XATTR_SIZE(root)) {
     479                 :          0 :                 printk(KERN_CRIT "btrfs: invalid dir item name + data len: %u + %u\n",
     480                 :            :                        (unsigned)btrfs_dir_name_len(leaf, dir_item),
     481                 :            :                        (unsigned)btrfs_dir_data_len(leaf, dir_item));
     482                 :          0 :                 return 1;
     483                 :            :         }
     484                 :            : 
     485                 :            :         return 0;
     486                 :            : }

Generated by: LCOV version 1.9