LCOV - code coverage report
Current view: top level - fs/ext3 - xattr.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 490 0.0 %
Date: 2014-02-18 Functions: 0 27 0.0 %
Branches: 0 398 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * linux/fs/ext3/xattr.c
       3                 :            :  *
       4                 :            :  * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de>
       5                 :            :  *
       6                 :            :  * Fix by Harrison Xing <harrison@mountainviewdata.com>.
       7                 :            :  * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
       8                 :            :  * Extended attributes for symlinks and special files added per
       9                 :            :  *  suggestion of Luka Renko <luka.renko@hermes.si>.
      10                 :            :  * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
      11                 :            :  *  Red Hat Inc.
      12                 :            :  * ea-in-inode support by Alex Tomas <alex@clusterfs.com> aka bzzz
      13                 :            :  *  and Andreas Gruenbacher <agruen@suse.de>.
      14                 :            :  */
      15                 :            : 
      16                 :            : /*
      17                 :            :  * Extended attributes are stored directly in inodes (on file systems with
      18                 :            :  * inodes bigger than 128 bytes) and on additional disk blocks. The i_file_acl
      19                 :            :  * field contains the block number if an inode uses an additional block. All
      20                 :            :  * attributes must fit in the inode and one additional block. Blocks that
      21                 :            :  * contain the identical set of attributes may be shared among several inodes.
      22                 :            :  * Identical blocks are detected by keeping a cache of blocks that have
      23                 :            :  * recently been accessed.
      24                 :            :  *
      25                 :            :  * The attributes in inodes and on blocks have a different header; the entries
      26                 :            :  * are stored in the same format:
      27                 :            :  *
      28                 :            :  *   +------------------+
      29                 :            :  *   | header           |
      30                 :            :  *   | entry 1          | |
      31                 :            :  *   | entry 2          | | growing downwards
      32                 :            :  *   | entry 3          | v
      33                 :            :  *   | four null bytes  |
      34                 :            :  *   | . . .            |
      35                 :            :  *   | value 1          | ^
      36                 :            :  *   | value 3          | | growing upwards
      37                 :            :  *   | value 2          | |
      38                 :            :  *   +------------------+
      39                 :            :  *
      40                 :            :  * The header is followed by multiple entry descriptors. In disk blocks, the
      41                 :            :  * entry descriptors are kept sorted. In inodes, they are unsorted. The
      42                 :            :  * attribute values are aligned to the end of the block in no specific order.
      43                 :            :  *
      44                 :            :  * Locking strategy
      45                 :            :  * ----------------
      46                 :            :  * EXT3_I(inode)->i_file_acl is protected by EXT3_I(inode)->xattr_sem.
      47                 :            :  * EA blocks are only changed if they are exclusive to an inode, so
      48                 :            :  * holding xattr_sem also means that nothing but the EA block's reference
      49                 :            :  * count can change. Multiple writers to the same block are synchronized
      50                 :            :  * by the buffer lock.
      51                 :            :  */
      52                 :            : 
      53                 :            : #include "ext3.h"
      54                 :            : #include <linux/mbcache.h>
      55                 :            : #include <linux/quotaops.h>
      56                 :            : #include "xattr.h"
      57                 :            : #include "acl.h"
      58                 :            : 
      59                 :            : #define BHDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
      60                 :            : #define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
      61                 :            : #define BFIRST(bh) ENTRY(BHDR(bh)+1)
      62                 :            : #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
      63                 :            : 
      64                 :            : #define IHDR(inode, raw_inode) \
      65                 :            :         ((struct ext3_xattr_ibody_header *) \
      66                 :            :                 ((void *)raw_inode + \
      67                 :            :                  EXT3_GOOD_OLD_INODE_SIZE + \
      68                 :            :                  EXT3_I(inode)->i_extra_isize))
      69                 :            : #define IFIRST(hdr) ((struct ext3_xattr_entry *)((hdr)+1))
      70                 :            : 
      71                 :            : #ifdef EXT3_XATTR_DEBUG
      72                 :            : # define ea_idebug(inode, f...) do { \
      73                 :            :                 printk(KERN_DEBUG "inode %s:%lu: ", \
      74                 :            :                         inode->i_sb->s_id, inode->i_ino); \
      75                 :            :                 printk(f); \
      76                 :            :                 printk("\n"); \
      77                 :            :         } while (0)
      78                 :            : # define ea_bdebug(bh, f...) do { \
      79                 :            :                 char b[BDEVNAME_SIZE]; \
      80                 :            :                 printk(KERN_DEBUG "block %s:%lu: ", \
      81                 :            :                         bdevname(bh->b_bdev, b), \
      82                 :            :                         (unsigned long) bh->b_blocknr); \
      83                 :            :                 printk(f); \
      84                 :            :                 printk("\n"); \
      85                 :            :         } while (0)
      86                 :            : #else
      87                 :            : # define ea_idebug(f...)
      88                 :            : # define ea_bdebug(f...)
      89                 :            : #endif
      90                 :            : 
      91                 :            : static void ext3_xattr_cache_insert(struct buffer_head *);
      92                 :            : static struct buffer_head *ext3_xattr_cache_find(struct inode *,
      93                 :            :                                                  struct ext3_xattr_header *,
      94                 :            :                                                  struct mb_cache_entry **);
      95                 :            : static void ext3_xattr_rehash(struct ext3_xattr_header *,
      96                 :            :                               struct ext3_xattr_entry *);
      97                 :            : static int ext3_xattr_list(struct dentry *dentry, char *buffer,
      98                 :            :                            size_t buffer_size);
      99                 :            : 
     100                 :            : static struct mb_cache *ext3_xattr_cache;
     101                 :            : 
     102                 :            : static const struct xattr_handler *ext3_xattr_handler_map[] = {
     103                 :            :         [EXT3_XATTR_INDEX_USER]              = &ext3_xattr_user_handler,
     104                 :            : #ifdef CONFIG_EXT3_FS_POSIX_ACL
     105                 :            :         [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS]  = &ext3_xattr_acl_access_handler,
     106                 :            :         [EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext3_xattr_acl_default_handler,
     107                 :            : #endif
     108                 :            :         [EXT3_XATTR_INDEX_TRUSTED]           = &ext3_xattr_trusted_handler,
     109                 :            : #ifdef CONFIG_EXT3_FS_SECURITY
     110                 :            :         [EXT3_XATTR_INDEX_SECURITY]          = &ext3_xattr_security_handler,
     111                 :            : #endif
     112                 :            : };
     113                 :            : 
     114                 :            : const struct xattr_handler *ext3_xattr_handlers[] = {
     115                 :            :         &ext3_xattr_user_handler,
     116                 :            :         &ext3_xattr_trusted_handler,
     117                 :            : #ifdef CONFIG_EXT3_FS_POSIX_ACL
     118                 :            :         &ext3_xattr_acl_access_handler,
     119                 :            :         &ext3_xattr_acl_default_handler,
     120                 :            : #endif
     121                 :            : #ifdef CONFIG_EXT3_FS_SECURITY
     122                 :            :         &ext3_xattr_security_handler,
     123                 :            : #endif
     124                 :            :         NULL
     125                 :            : };
     126                 :            : 
     127                 :            : static inline const struct xattr_handler *
     128                 :            : ext3_xattr_handler(int name_index)
     129                 :            : {
     130                 :            :         const struct xattr_handler *handler = NULL;
     131                 :            : 
     132         [ #  # ]:          0 :         if (name_index > 0 && name_index < ARRAY_SIZE(ext3_xattr_handler_map))
     133                 :          0 :                 handler = ext3_xattr_handler_map[name_index];
     134                 :            :         return handler;
     135                 :            : }
     136                 :            : 
     137                 :            : /*
     138                 :            :  * Inode operation listxattr()
     139                 :            :  *
     140                 :            :  * dentry->d_inode->i_mutex: don't care
     141                 :            :  */
     142                 :            : ssize_t
     143                 :          0 : ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
     144                 :            : {
     145                 :          0 :         return ext3_xattr_list(dentry, buffer, size);
     146                 :            : }
     147                 :            : 
     148                 :            : static int
     149                 :          0 : ext3_xattr_check_names(struct ext3_xattr_entry *entry, void *end)
     150                 :            : {
     151 [ #  # ][ #  # ]:          0 :         while (!IS_LAST_ENTRY(entry)) {
         [ #  # ][ #  # ]
     152                 :          0 :                 struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(entry);
     153 [ #  # ][ #  # ]:          0 :                 if ((void *)next >= end)
         [ #  # ][ #  # ]
     154                 :            :                         return -EIO;
     155                 :            :                 entry = next;
     156                 :            :         }
     157                 :            :         return 0;
     158                 :            : }
     159                 :            : 
     160                 :            : static inline int
     161                 :            : ext3_xattr_check_block(struct buffer_head *bh)
     162                 :            : {
     163                 :            :         int error;
     164                 :            : 
     165 [ #  # ][ #  # ]:          0 :         if (BHDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     166                 :          0 :             BHDR(bh)->h_blocks != cpu_to_le32(1))
     167                 :            :                 return -EIO;
     168                 :          0 :         error = ext3_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
     169                 :            :         return error;
     170                 :            : }
     171                 :            : 
     172                 :            : static inline int
     173                 :            : ext3_xattr_check_entry(struct ext3_xattr_entry *entry, size_t size)
     174                 :            : {
     175                 :          0 :         size_t value_size = le32_to_cpu(entry->e_value_size);
     176                 :            : 
     177 [ #  # ][ #  # ]:          0 :         if (entry->e_value_block != 0 || value_size > size ||
                 [ #  # ]
     178                 :          0 :             le16_to_cpu(entry->e_value_offs) + value_size > size)
     179                 :            :                 return -EIO;
     180                 :            :         return 0;
     181                 :            : }
     182                 :            : 
     183                 :            : static int
     184                 :          0 : ext3_xattr_find_entry(struct ext3_xattr_entry **pentry, int name_index,
     185                 :            :                       const char *name, size_t size, int sorted)
     186                 :            : {
     187                 :            :         struct ext3_xattr_entry *entry;
     188                 :            :         size_t name_len;
     189                 :            :         int cmp = 1;
     190                 :            : 
     191         [ #  # ]:          0 :         if (name == NULL)
     192                 :            :                 return -EINVAL;
     193                 :          0 :         name_len = strlen(name);
     194                 :          0 :         entry = *pentry;
     195         [ #  # ]:          0 :         for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) {
     196                 :          0 :                 cmp = name_index - entry->e_name_index;
     197         [ #  # ]:          0 :                 if (!cmp)
     198                 :          0 :                         cmp = name_len - entry->e_name_len;
     199         [ #  # ]:          0 :                 if (!cmp)
     200                 :          0 :                         cmp = memcmp(name, entry->e_name, name_len);
     201 [ #  # ][ #  # ]:          0 :                 if (cmp <= 0 && (sorted || cmp == 0))
     202                 :            :                         break;
     203                 :            :         }
     204                 :          0 :         *pentry = entry;
     205 [ #  # ][ #  # ]:          0 :         if (!cmp && ext3_xattr_check_entry(entry, size))
     206                 :            :                         return -EIO;
     207         [ #  # ]:          0 :         return cmp ? -ENODATA : 0;
     208                 :            : }
     209                 :            : 
     210                 :            : static int
     211                 :          0 : ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
     212                 :            :                      void *buffer, size_t buffer_size)
     213                 :            : {
     214                 :          0 :         struct buffer_head *bh = NULL;
     215                 :            :         struct ext3_xattr_entry *entry;
     216                 :            :         size_t size;
     217                 :            :         int error;
     218                 :            : 
     219                 :            :         ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
     220                 :            :                   name_index, name, buffer, (long)buffer_size);
     221                 :            : 
     222                 :            :         error = -ENODATA;
     223         [ #  # ]:          0 :         if (!EXT3_I(inode)->i_file_acl)
     224                 :            :                 goto cleanup;
     225                 :            :         ea_idebug(inode, "reading block %u", EXT3_I(inode)->i_file_acl);
     226                 :          0 :         bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
     227         [ #  # ]:          0 :         if (!bh)
     228                 :            :                 goto cleanup;
     229                 :            :         ea_bdebug(bh, "b_count=%d, refcount=%d",
     230                 :            :                 atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
     231         [ #  # ]:          0 :         if (ext3_xattr_check_block(bh)) {
     232                 :          0 : bad_block:      ext3_error(inode->i_sb, __func__,
     233                 :            :                            "inode %lu: bad block "E3FSBLK, inode->i_ino,
     234                 :            :                            EXT3_I(inode)->i_file_acl);
     235                 :            :                 error = -EIO;
     236                 :          0 :                 goto cleanup;
     237                 :            :         }
     238                 :          0 :         ext3_xattr_cache_insert(bh);
     239                 :          0 :         entry = BFIRST(bh);
     240                 :          0 :         error = ext3_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
     241         [ #  # ]:          0 :         if (error == -EIO)
     242                 :            :                 goto bad_block;
     243         [ #  # ]:          0 :         if (error)
     244                 :            :                 goto cleanup;
     245                 :          0 :         size = le32_to_cpu(entry->e_value_size);
     246         [ #  # ]:          0 :         if (buffer) {
     247                 :            :                 error = -ERANGE;
     248         [ #  # ]:          0 :                 if (size > buffer_size)
     249                 :            :                         goto cleanup;
     250                 :          0 :                 memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
     251                 :            :                        size);
     252                 :            :         }
     253                 :          0 :         error = size;
     254                 :            : 
     255                 :            : cleanup:
     256                 :            :         brelse(bh);
     257                 :          0 :         return error;
     258                 :            : }
     259                 :            : 
     260                 :            : static int
     261                 :          0 : ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
     262                 :            :                      void *buffer, size_t buffer_size)
     263                 :            : {
     264                 :            :         struct ext3_xattr_ibody_header *header;
     265                 :            :         struct ext3_xattr_entry *entry;
     266                 :            :         struct ext3_inode *raw_inode;
     267                 :            :         struct ext3_iloc iloc;
     268                 :            :         size_t size;
     269                 :            :         void *end;
     270                 :            :         int error;
     271                 :            : 
     272         [ #  # ]:          0 :         if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR))
     273                 :            :                 return -ENODATA;
     274                 :          0 :         error = ext3_get_inode_loc(inode, &iloc);
     275         [ #  # ]:          0 :         if (error)
     276                 :            :                 return error;
     277                 :          0 :         raw_inode = ext3_raw_inode(&iloc);
     278                 :          0 :         header = IHDR(inode, raw_inode);
     279                 :          0 :         entry = IFIRST(header);
     280                 :          0 :         end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
     281                 :            :         error = ext3_xattr_check_names(entry, end);
     282         [ #  # ]:          0 :         if (error)
     283                 :            :                 goto cleanup;
     284                 :          0 :         error = ext3_xattr_find_entry(&entry, name_index, name,
     285                 :          0 :                                       end - (void *)entry, 0);
     286         [ #  # ]:          0 :         if (error)
     287                 :            :                 goto cleanup;
     288                 :          0 :         size = le32_to_cpu(entry->e_value_size);
     289         [ #  # ]:          0 :         if (buffer) {
     290                 :            :                 error = -ERANGE;
     291         [ #  # ]:          0 :                 if (size > buffer_size)
     292                 :            :                         goto cleanup;
     293                 :          0 :                 memcpy(buffer, (void *)IFIRST(header) +
     294                 :          0 :                        le16_to_cpu(entry->e_value_offs), size);
     295                 :            :         }
     296                 :          0 :         error = size;
     297                 :            : 
     298                 :            : cleanup:
     299                 :          0 :         brelse(iloc.bh);
     300                 :          0 :         return error;
     301                 :            : }
     302                 :            : 
     303                 :            : /*
     304                 :            :  * ext3_xattr_get()
     305                 :            :  *
     306                 :            :  * Copy an extended attribute into the buffer
     307                 :            :  * provided, or compute the buffer size required.
     308                 :            :  * Buffer is NULL to compute the size of the buffer required.
     309                 :            :  *
     310                 :            :  * Returns a negative error number on failure, or the number of bytes
     311                 :            :  * used / required on success.
     312                 :            :  */
     313                 :            : int
     314                 :          0 : ext3_xattr_get(struct inode *inode, int name_index, const char *name,
     315                 :            :                void *buffer, size_t buffer_size)
     316                 :            : {
     317                 :            :         int error;
     318                 :            : 
     319                 :          0 :         down_read(&EXT3_I(inode)->xattr_sem);
     320                 :          0 :         error = ext3_xattr_ibody_get(inode, name_index, name, buffer,
     321                 :            :                                      buffer_size);
     322         [ #  # ]:          0 :         if (error == -ENODATA)
     323                 :          0 :                 error = ext3_xattr_block_get(inode, name_index, name, buffer,
     324                 :            :                                              buffer_size);
     325                 :          0 :         up_read(&EXT3_I(inode)->xattr_sem);
     326                 :          0 :         return error;
     327                 :            : }
     328                 :            : 
     329                 :            : static int
     330                 :          0 : ext3_xattr_list_entries(struct dentry *dentry, struct ext3_xattr_entry *entry,
     331                 :            :                         char *buffer, size_t buffer_size)
     332                 :            : {
     333                 :            :         size_t rest = buffer_size;
     334                 :            : 
     335         [ #  # ]:          0 :         for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) {
     336                 :            :                 const struct xattr_handler *handler =
     337                 :          0 :                         ext3_xattr_handler(entry->e_name_index);
     338                 :            : 
     339         [ #  # ]:          0 :                 if (handler) {
     340                 :          0 :                         size_t size = handler->list(dentry, buffer, rest,
     341                 :          0 :                                                     entry->e_name,
     342                 :          0 :                                                     entry->e_name_len,
     343                 :            :                                                     handler->flags);
     344         [ #  # ]:          0 :                         if (buffer) {
     345         [ #  # ]:          0 :                                 if (size > rest)
     346                 :            :                                         return -ERANGE;
     347                 :          0 :                                 buffer += size;
     348                 :            :                         }
     349                 :          0 :                         rest -= size;
     350                 :            :                 }
     351                 :            :         }
     352                 :          0 :         return buffer_size - rest;
     353                 :            : }
     354                 :            : 
     355                 :            : static int
     356                 :          0 : ext3_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
     357                 :            : {
     358                 :          0 :         struct inode *inode = dentry->d_inode;
     359                 :          0 :         struct buffer_head *bh = NULL;
     360                 :            :         int error;
     361                 :            : 
     362                 :            :         ea_idebug(inode, "buffer=%p, buffer_size=%ld",
     363                 :            :                   buffer, (long)buffer_size);
     364                 :            : 
     365                 :            :         error = 0;
     366         [ #  # ]:          0 :         if (!EXT3_I(inode)->i_file_acl)
     367                 :            :                 goto cleanup;
     368                 :            :         ea_idebug(inode, "reading block %u", EXT3_I(inode)->i_file_acl);
     369                 :          0 :         bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
     370                 :            :         error = -EIO;
     371         [ #  # ]:          0 :         if (!bh)
     372                 :            :                 goto cleanup;
     373                 :            :         ea_bdebug(bh, "b_count=%d, refcount=%d",
     374                 :            :                 atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
     375         [ #  # ]:          0 :         if (ext3_xattr_check_block(bh)) {
     376                 :          0 :                 ext3_error(inode->i_sb, __func__,
     377                 :            :                            "inode %lu: bad block "E3FSBLK, inode->i_ino,
     378                 :            :                            EXT3_I(inode)->i_file_acl);
     379                 :            :                 error = -EIO;
     380                 :          0 :                 goto cleanup;
     381                 :            :         }
     382                 :          0 :         ext3_xattr_cache_insert(bh);
     383                 :          0 :         error = ext3_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);
     384                 :            : 
     385                 :            : cleanup:
     386                 :            :         brelse(bh);
     387                 :            : 
     388                 :          0 :         return error;
     389                 :            : }
     390                 :            : 
     391                 :            : static int
     392                 :          0 : ext3_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
     393                 :            : {
     394                 :          0 :         struct inode *inode = dentry->d_inode;
     395                 :            :         struct ext3_xattr_ibody_header *header;
     396                 :            :         struct ext3_inode *raw_inode;
     397                 :            :         struct ext3_iloc iloc;
     398                 :            :         void *end;
     399                 :            :         int error;
     400                 :            : 
     401         [ #  # ]:          0 :         if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR))
     402                 :            :                 return 0;
     403                 :          0 :         error = ext3_get_inode_loc(inode, &iloc);
     404         [ #  # ]:          0 :         if (error)
     405                 :            :                 return error;
     406                 :          0 :         raw_inode = ext3_raw_inode(&iloc);
     407                 :          0 :         header = IHDR(inode, raw_inode);
     408                 :          0 :         end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
     409                 :          0 :         error = ext3_xattr_check_names(IFIRST(header), end);
     410         [ #  # ]:          0 :         if (error)
     411                 :            :                 goto cleanup;
     412                 :          0 :         error = ext3_xattr_list_entries(dentry, IFIRST(header),
     413                 :            :                                         buffer, buffer_size);
     414                 :            : 
     415                 :            : cleanup:
     416                 :          0 :         brelse(iloc.bh);
     417                 :          0 :         return error;
     418                 :            : }
     419                 :            : 
     420                 :            : /*
     421                 :            :  * ext3_xattr_list()
     422                 :            :  *
     423                 :            :  * Copy a list of attribute names into the buffer
     424                 :            :  * provided, or compute the buffer size required.
     425                 :            :  * Buffer is NULL to compute the size of the buffer required.
     426                 :            :  *
     427                 :            :  * Returns a negative error number on failure, or the number of bytes
     428                 :            :  * used / required on success.
     429                 :            :  */
     430                 :            : static int
     431                 :          0 : ext3_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
     432                 :            : {
     433                 :            :         int i_error, b_error;
     434                 :            : 
     435                 :          0 :         down_read(&EXT3_I(dentry->d_inode)->xattr_sem);
     436                 :          0 :         i_error = ext3_xattr_ibody_list(dentry, buffer, buffer_size);
     437         [ #  # ]:          0 :         if (i_error < 0) {
     438                 :            :                 b_error = 0;
     439                 :            :         } else {
     440         [ #  # ]:          0 :                 if (buffer) {
     441                 :          0 :                         buffer += i_error;
     442                 :          0 :                         buffer_size -= i_error;
     443                 :            :                 }
     444                 :          0 :                 b_error = ext3_xattr_block_list(dentry, buffer, buffer_size);
     445         [ #  # ]:          0 :                 if (b_error < 0)
     446                 :            :                         i_error = 0;
     447                 :            :         }
     448                 :          0 :         up_read(&EXT3_I(dentry->d_inode)->xattr_sem);
     449                 :          0 :         return i_error + b_error;
     450                 :            : }
     451                 :            : 
     452                 :            : /*
     453                 :            :  * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
     454                 :            :  * not set, set it.
     455                 :            :  */
     456                 :          0 : static void ext3_xattr_update_super_block(handle_t *handle,
     457                 :          0 :                                           struct super_block *sb)
     458                 :            : {
     459         [ #  # ]:          0 :         if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
     460                 :          0 :                 return;
     461                 :            : 
     462         [ #  # ]:          0 :         if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) {
     463                 :          0 :                 EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR);
     464                 :          0 :                 ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
     465                 :            :         }
     466                 :            : }
     467                 :            : 
     468                 :            : /*
     469                 :            :  * Release the xattr block BH: If the reference count is > 1, decrement
     470                 :            :  * it; otherwise free the block.
     471                 :            :  */
     472                 :            : static void
     473                 :          0 : ext3_xattr_release_block(handle_t *handle, struct inode *inode,
     474                 :            :                          struct buffer_head *bh)
     475                 :            : {
     476                 :            :         struct mb_cache_entry *ce = NULL;
     477                 :            :         int error = 0;
     478                 :            : 
     479                 :          0 :         ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr);
     480                 :          0 :         error = ext3_journal_get_write_access(handle, bh);
     481         [ #  # ]:          0 :         if (error)
     482                 :            :                  goto out;
     483                 :            : 
     484                 :            :         lock_buffer(bh);
     485                 :            : 
     486         [ #  # ]:          0 :         if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
     487                 :            :                 ea_bdebug(bh, "refcount now=0; freeing");
     488         [ #  # ]:          0 :                 if (ce)
     489                 :          0 :                         mb_cache_entry_free(ce);
     490                 :          0 :                 ext3_free_blocks(handle, inode, bh->b_blocknr, 1);
     491                 :            :                 get_bh(bh);
     492                 :          0 :                 ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
     493                 :            :         } else {
     494                 :            :                 le32_add_cpu(&BHDR(bh)->h_refcount, -1);
     495                 :          0 :                 error = ext3_journal_dirty_metadata(handle, bh);
     496 [ #  # ][ #  # ]:          0 :                 if (IS_SYNC(inode))
     497                 :          0 :                         handle->h_sync = 1;
     498                 :            :                 dquot_free_block(inode, 1);
     499                 :            :                 ea_bdebug(bh, "refcount now=%d; releasing",
     500                 :            :                           le32_to_cpu(BHDR(bh)->h_refcount));
     501         [ #  # ]:          0 :                 if (ce)
     502                 :          0 :                         mb_cache_entry_release(ce);
     503                 :            :         }
     504                 :          0 :         unlock_buffer(bh);
     505                 :            : out:
     506         [ #  # ]:          0 :         ext3_std_error(inode->i_sb, error);
     507                 :          0 :         return;
     508                 :            : }
     509                 :            : 
     510                 :            : struct ext3_xattr_info {
     511                 :            :         int name_index;
     512                 :            :         const char *name;
     513                 :            :         const void *value;
     514                 :            :         size_t value_len;
     515                 :            : };
     516                 :            : 
     517                 :            : struct ext3_xattr_search {
     518                 :            :         struct ext3_xattr_entry *first;
     519                 :            :         void *base;
     520                 :            :         void *end;
     521                 :            :         struct ext3_xattr_entry *here;
     522                 :            :         int not_found;
     523                 :            : };
     524                 :            : 
     525                 :            : static int
     526                 :          0 : ext3_xattr_set_entry(struct ext3_xattr_info *i, struct ext3_xattr_search *s)
     527                 :            : {
     528                 :            :         struct ext3_xattr_entry *last;
     529                 :          0 :         size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
     530                 :            : 
     531                 :            :         /* Compute min_offs and last. */
     532                 :          0 :         last = s->first;
     533         [ #  # ]:          0 :         for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {
     534 [ #  # ][ #  # ]:          0 :                 if (!last->e_value_block && last->e_value_size) {
     535                 :          0 :                         size_t offs = le16_to_cpu(last->e_value_offs);
     536         [ #  # ]:          0 :                         if (offs < min_offs)
     537                 :            :                                 min_offs = offs;
     538                 :            :                 }
     539                 :            :         }
     540                 :          0 :         free = min_offs - ((void *)last - s->base) - sizeof(__u32);
     541         [ #  # ]:          0 :         if (!s->not_found) {
     542 [ #  # ][ #  # ]:          0 :                 if (!s->here->e_value_block && s->here->e_value_size) {
     543                 :            :                         size_t size = le32_to_cpu(s->here->e_value_size);
     544                 :          0 :                         free += EXT3_XATTR_SIZE(size);
     545                 :            :                 }
     546                 :          0 :                 free += EXT3_XATTR_LEN(name_len);
     547                 :            :         }
     548         [ #  # ]:          0 :         if (i->value) {
     549 [ #  # ][ #  # ]:          0 :                 if (free < EXT3_XATTR_SIZE(i->value_len) ||
     550                 :          0 :                     free < EXT3_XATTR_LEN(name_len) +
     551                 :            :                            EXT3_XATTR_SIZE(i->value_len))
     552                 :            :                         return -ENOSPC;
     553                 :            :         }
     554                 :            : 
     555 [ #  # ][ #  # ]:          0 :         if (i->value && s->not_found) {
     556                 :            :                 /* Insert the new name. */
     557                 :          0 :                 size_t size = EXT3_XATTR_LEN(name_len);
     558                 :          0 :                 size_t rest = (void *)last - (void *)s->here + sizeof(__u32);
     559                 :          0 :                 memmove((void *)s->here + size, s->here, rest);
     560         [ #  # ]:          0 :                 memset(s->here, 0, size);
     561                 :          0 :                 s->here->e_name_index = i->name_index;
     562                 :          0 :                 s->here->e_name_len = name_len;
     563                 :          0 :                 memcpy(s->here->e_name, i->name, name_len);
     564                 :            :         } else {
     565 [ #  # ][ #  # ]:          0 :                 if (!s->here->e_value_block && s->here->e_value_size) {
     566                 :          0 :                         void *first_val = s->base + min_offs;
     567                 :          0 :                         size_t offs = le16_to_cpu(s->here->e_value_offs);
     568                 :          0 :                         void *val = s->base + offs;
     569                 :          0 :                         size_t size = EXT3_XATTR_SIZE(
     570                 :            :                                 le32_to_cpu(s->here->e_value_size));
     571                 :            : 
     572 [ #  # ][ #  # ]:          0 :                         if (i->value && size == EXT3_XATTR_SIZE(i->value_len)) {
     573                 :            :                                 /* The old and the new value have the same
     574                 :            :                                    size. Just replace. */
     575                 :          0 :                                 s->here->e_value_size =
     576                 :            :                                         cpu_to_le32(i->value_len);
     577                 :          0 :                                 memset(val + size - EXT3_XATTR_PAD, 0,
     578                 :            :                                        EXT3_XATTR_PAD); /* Clear pad bytes. */
     579                 :          0 :                                 memcpy(val, i->value, i->value_len);
     580                 :          0 :                                 return 0;
     581                 :            :                         }
     582                 :            : 
     583                 :            :                         /* Remove the old value. */
     584                 :          0 :                         memmove(first_val + size, first_val, val - first_val);
     585         [ #  # ]:          0 :                         memset(first_val, 0, size);
     586                 :          0 :                         s->here->e_value_size = 0;
     587                 :          0 :                         s->here->e_value_offs = 0;
     588                 :          0 :                         min_offs += size;
     589                 :            : 
     590                 :            :                         /* Adjust all value offsets. */
     591                 :          0 :                         last = s->first;
     592         [ #  # ]:          0 :                         while (!IS_LAST_ENTRY(last)) {
     593                 :          0 :                                 size_t o = le16_to_cpu(last->e_value_offs);
     594 [ #  # ][ #  # ]:          0 :                                 if (!last->e_value_block &&
     595         [ #  # ]:          0 :                                     last->e_value_size && o < offs)
     596                 :          0 :                                         last->e_value_offs =
     597                 :          0 :                                                 cpu_to_le16(o + size);
     598                 :          0 :                                 last = EXT3_XATTR_NEXT(last);
     599                 :            :                         }
     600                 :            :                 }
     601         [ #  # ]:          0 :                 if (!i->value) {
     602                 :            :                         /* Remove the old name. */
     603                 :          0 :                         size_t size = EXT3_XATTR_LEN(name_len);
     604                 :          0 :                         last = ENTRY((void *)last - size);
     605                 :          0 :                         memmove(s->here, (void *)s->here + size,
     606                 :          0 :                                 (void *)last - (void *)s->here + sizeof(__u32));
     607         [ #  # ]:          0 :                         memset(last, 0, size);
     608                 :            :                 }
     609                 :            :         }
     610                 :            : 
     611         [ #  # ]:          0 :         if (i->value) {
     612                 :            :                 /* Insert the new value. */
     613                 :          0 :                 s->here->e_value_size = cpu_to_le32(i->value_len);
     614         [ #  # ]:          0 :                 if (i->value_len) {
     615                 :          0 :                         size_t size = EXT3_XATTR_SIZE(i->value_len);
     616                 :          0 :                         void *val = s->base + min_offs - size;
     617                 :          0 :                         s->here->e_value_offs = cpu_to_le16(min_offs - size);
     618                 :          0 :                         memset(val + size - EXT3_XATTR_PAD, 0,
     619                 :            :                                EXT3_XATTR_PAD); /* Clear the pad bytes. */
     620                 :          0 :                         memcpy(val, i->value, i->value_len);
     621                 :            :                 }
     622                 :            :         }
     623                 :            :         return 0;
     624                 :            : }
     625                 :            : 
     626                 :            : struct ext3_xattr_block_find {
     627                 :            :         struct ext3_xattr_search s;
     628                 :            :         struct buffer_head *bh;
     629                 :            : };
     630                 :            : 
     631                 :            : static int
     632                 :          0 : ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i,
     633                 :            :                       struct ext3_xattr_block_find *bs)
     634                 :            : {
     635                 :          0 :         struct super_block *sb = inode->i_sb;
     636                 :            :         int error;
     637                 :            : 
     638                 :            :         ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
     639                 :            :                   i->name_index, i->name, i->value, (long)i->value_len);
     640                 :            : 
     641         [ #  # ]:          0 :         if (EXT3_I(inode)->i_file_acl) {
     642                 :            :                 /* The inode already has an extended attribute block. */
     643                 :          0 :                 bs->bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
     644                 :            :                 error = -EIO;
     645         [ #  # ]:          0 :                 if (!bs->bh)
     646                 :            :                         goto cleanup;
     647                 :            :                 ea_bdebug(bs->bh, "b_count=%d, refcount=%d",
     648                 :            :                         atomic_read(&(bs->bh->b_count)),
     649                 :            :                         le32_to_cpu(BHDR(bs->bh)->h_refcount));
     650         [ #  # ]:          0 :                 if (ext3_xattr_check_block(bs->bh)) {
     651                 :          0 :                         ext3_error(sb, __func__,
     652                 :            :                                 "inode %lu: bad block "E3FSBLK, inode->i_ino,
     653                 :            :                                 EXT3_I(inode)->i_file_acl);
     654                 :            :                         error = -EIO;
     655                 :            :                         goto cleanup;
     656                 :            :                 }
     657                 :            :                 /* Find the named attribute. */
     658                 :          0 :                 bs->s.base = BHDR(bs->bh);
     659                 :          0 :                 bs->s.first = BFIRST(bs->bh);
     660                 :          0 :                 bs->s.end = bs->bh->b_data + bs->bh->b_size;
     661                 :          0 :                 bs->s.here = bs->s.first;
     662                 :          0 :                 error = ext3_xattr_find_entry(&bs->s.here, i->name_index,
     663                 :            :                                               i->name, bs->bh->b_size, 1);
     664         [ #  # ]:          0 :                 if (error && error != -ENODATA)
     665                 :            :                         goto cleanup;
     666                 :          0 :                 bs->s.not_found = error;
     667                 :            :         }
     668                 :            :         error = 0;
     669                 :            : 
     670                 :            : cleanup:
     671                 :          0 :         return error;
     672                 :            : }
     673                 :            : 
     674                 :            : static int
     675                 :          0 : ext3_xattr_block_set(handle_t *handle, struct inode *inode,
     676                 :            :                      struct ext3_xattr_info *i,
     677                 :            :                      struct ext3_xattr_block_find *bs)
     678                 :            : {
     679                 :          0 :         struct super_block *sb = inode->i_sb;
     680                 :            :         struct buffer_head *new_bh = NULL;
     681                 :          0 :         struct ext3_xattr_search *s = &bs->s;
     682                 :          0 :         struct mb_cache_entry *ce = NULL;
     683                 :          0 :         int error = 0;
     684                 :            : 
     685                 :            : #define header(x) ((struct ext3_xattr_header *)(x))
     686                 :            : 
     687 [ #  # ][ #  # ]:          0 :         if (i->value && i->value_len > sb->s_blocksize)
     688                 :            :                 return -ENOSPC;
     689         [ #  # ]:          0 :         if (s->base) {
     690                 :          0 :                 ce = mb_cache_entry_get(ext3_xattr_cache, bs->bh->b_bdev,
     691                 :            :                                         bs->bh->b_blocknr);
     692                 :          0 :                 error = ext3_journal_get_write_access(handle, bs->bh);
     693         [ #  # ]:          0 :                 if (error)
     694                 :            :                         goto cleanup;
     695                 :          0 :                 lock_buffer(bs->bh);
     696                 :            : 
     697         [ #  # ]:          0 :                 if (header(s->base)->h_refcount == cpu_to_le32(1)) {
     698         [ #  # ]:          0 :                         if (ce) {
     699                 :          0 :                                 mb_cache_entry_free(ce);
     700                 :          0 :                                 ce = NULL;
     701                 :            :                         }
     702                 :            :                         ea_bdebug(bs->bh, "modifying in-place");
     703                 :          0 :                         error = ext3_xattr_set_entry(i, s);
     704         [ #  # ]:          0 :                         if (!error) {
     705         [ #  # ]:          0 :                                 if (!IS_LAST_ENTRY(s->first))
     706                 :          0 :                                         ext3_xattr_rehash(header(s->base),
     707                 :            :                                                           s->here);
     708                 :          0 :                                 ext3_xattr_cache_insert(bs->bh);
     709                 :            :                         }
     710                 :          0 :                         unlock_buffer(bs->bh);
     711         [ #  # ]:          0 :                         if (error == -EIO)
     712                 :            :                                 goto bad_block;
     713         [ #  # ]:          0 :                         if (!error)
     714                 :          0 :                                 error = ext3_journal_dirty_metadata(handle,
     715                 :            :                                                                     bs->bh);
     716         [ #  # ]:          0 :                         if (error)
     717                 :            :                                 goto cleanup;
     718                 :            :                         goto inserted;
     719                 :            :                 } else {
     720                 :          0 :                         int offset = (char *)s->here - bs->bh->b_data;
     721                 :            : 
     722                 :          0 :                         unlock_buffer(bs->bh);
     723                 :          0 :                         journal_release_buffer(handle, bs->bh);
     724                 :            : 
     725         [ #  # ]:          0 :                         if (ce) {
     726                 :          0 :                                 mb_cache_entry_release(ce);
     727                 :          0 :                                 ce = NULL;
     728                 :            :                         }
     729                 :            :                         ea_bdebug(bs->bh, "cloning");
     730                 :          0 :                         s->base = kmalloc(bs->bh->b_size, GFP_NOFS);
     731                 :          0 :                         error = -ENOMEM;
     732         [ #  # ]:          0 :                         if (s->base == NULL)
     733                 :            :                                 goto cleanup;
     734                 :          0 :                         memcpy(s->base, BHDR(bs->bh), bs->bh->b_size);
     735                 :          0 :                         s->first = ENTRY(header(s->base)+1);
     736                 :          0 :                         header(s->base)->h_refcount = cpu_to_le32(1);
     737                 :          0 :                         s->here = ENTRY(s->base + offset);
     738                 :          0 :                         s->end = s->base + bs->bh->b_size;
     739                 :            :                 }
     740                 :            :         } else {
     741                 :            :                 /* Allocate a buffer where we construct the new block. */
     742                 :          0 :                 s->base = kzalloc(sb->s_blocksize, GFP_NOFS);
     743                 :            :                 /* assert(header == s->base) */
     744                 :          0 :                 error = -ENOMEM;
     745         [ #  # ]:          0 :                 if (s->base == NULL)
     746                 :            :                         goto cleanup;
     747                 :          0 :                 header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
     748                 :          0 :                 header(s->base)->h_blocks = cpu_to_le32(1);
     749                 :          0 :                 header(s->base)->h_refcount = cpu_to_le32(1);
     750                 :          0 :                 s->first = ENTRY(header(s->base)+1);
     751                 :          0 :                 s->here = ENTRY(header(s->base)+1);
     752                 :          0 :                 s->end = s->base + sb->s_blocksize;
     753                 :            :         }
     754                 :            : 
     755                 :          0 :         error = ext3_xattr_set_entry(i, s);
     756         [ #  # ]:          0 :         if (error == -EIO)
     757                 :            :                 goto bad_block;
     758         [ #  # ]:          0 :         if (error)
     759                 :            :                 goto cleanup;
     760         [ #  # ]:          0 :         if (!IS_LAST_ENTRY(s->first))
     761                 :          0 :                 ext3_xattr_rehash(header(s->base), s->here);
     762                 :            : 
     763                 :            : inserted:
     764         [ #  # ]:          0 :         if (!IS_LAST_ENTRY(s->first)) {
     765                 :          0 :                 new_bh = ext3_xattr_cache_find(inode, header(s->base), &ce);
     766         [ #  # ]:          0 :                 if (new_bh) {
     767                 :            :                         /* We found an identical block in the cache. */
     768         [ #  # ]:          0 :                         if (new_bh == bs->bh)
     769                 :            :                                 ea_bdebug(new_bh, "keeping");
     770                 :            :                         else {
     771                 :            :                                 /* The old block is released after updating
     772                 :            :                                    the inode. */
     773                 :          0 :                                 error = dquot_alloc_block(inode, 1);
     774         [ #  # ]:          0 :                                 if (error)
     775                 :            :                                         goto cleanup;
     776                 :          0 :                                 error = ext3_journal_get_write_access(handle,
     777                 :            :                                                                       new_bh);
     778         [ #  # ]:          0 :                                 if (error)
     779                 :            :                                         goto cleanup_dquot;
     780                 :            :                                 lock_buffer(new_bh);
     781                 :          0 :                                 le32_add_cpu(&BHDR(new_bh)->h_refcount, 1);
     782                 :            :                                 ea_bdebug(new_bh, "reusing; refcount now=%d",
     783                 :            :                                         le32_to_cpu(BHDR(new_bh)->h_refcount));
     784                 :          0 :                                 unlock_buffer(new_bh);
     785                 :          0 :                                 error = ext3_journal_dirty_metadata(handle,
     786                 :            :                                                                     new_bh);
     787         [ #  # ]:          0 :                                 if (error)
     788                 :            :                                         goto cleanup_dquot;
     789                 :            :                         }
     790                 :          0 :                         mb_cache_entry_release(ce);
     791                 :          0 :                         ce = NULL;
     792 [ #  # ][ #  # ]:          0 :                 } else if (bs->bh && s->base == bs->bh->b_data) {
     793                 :            :                         /* We were modifying this block in-place. */
     794                 :            :                         ea_bdebug(bs->bh, "keeping this block");
     795                 :            :                         new_bh = bs->bh;
     796                 :            :                         get_bh(new_bh);
     797                 :            :                 } else {
     798                 :            :                         /* We need to allocate a new block */
     799                 :            :                         ext3_fsblk_t goal = ext3_group_first_block_no(sb,
     800                 :          0 :                                                 EXT3_I(inode)->i_block_group);
     801                 :            :                         ext3_fsblk_t block;
     802                 :            : 
     803                 :            :                         /*
     804                 :            :                          * Protect us agaist concurrent allocations to the
     805                 :            :                          * same inode from ext3_..._writepage(). Reservation
     806                 :            :                          * code does not expect racing allocations.
     807                 :            :                          */
     808                 :          0 :                         mutex_lock(&EXT3_I(inode)->truncate_mutex);
     809                 :          0 :                         block = ext3_new_block(handle, inode, goal, &error);
     810                 :          0 :                         mutex_unlock(&EXT3_I(inode)->truncate_mutex);
     811         [ #  # ]:          0 :                         if (error)
     812                 :            :                                 goto cleanup;
     813                 :            :                         ea_idebug(inode, "creating block %d", block);
     814                 :            : 
     815                 :          0 :                         new_bh = sb_getblk(sb, block);
     816         [ #  # ]:          0 :                         if (unlikely(!new_bh)) {
     817                 :            : getblk_failed:
     818                 :          0 :                                 ext3_free_blocks(handle, inode, block, 1);
     819                 :          0 :                                 error = -ENOMEM;
     820                 :          0 :                                 goto cleanup;
     821                 :            :                         }
     822                 :            :                         lock_buffer(new_bh);
     823                 :          0 :                         error = ext3_journal_get_create_access(handle, new_bh);
     824         [ #  # ]:          0 :                         if (error) {
     825                 :          0 :                                 unlock_buffer(new_bh);
     826                 :          0 :                                 goto getblk_failed;
     827                 :            :                         }
     828                 :          0 :                         memcpy(new_bh->b_data, s->base, new_bh->b_size);
     829                 :            :                         set_buffer_uptodate(new_bh);
     830                 :          0 :                         unlock_buffer(new_bh);
     831                 :          0 :                         ext3_xattr_cache_insert(new_bh);
     832                 :          0 :                         error = ext3_journal_dirty_metadata(handle, new_bh);
     833         [ #  # ]:          0 :                         if (error)
     834                 :            :                                 goto cleanup;
     835                 :            :                 }
     836                 :            :         }
     837                 :            : 
     838                 :            :         /* Update the inode. */
     839         [ #  # ]:          0 :         EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
     840                 :            : 
     841                 :            :         /* Drop the previous xattr block. */
     842 [ #  # ][ #  # ]:          0 :         if (bs->bh && bs->bh != new_bh)
     843                 :          0 :                 ext3_xattr_release_block(handle, inode, bs->bh);
     844                 :          0 :         error = 0;
     845                 :            : 
     846                 :            : cleanup:
     847         [ #  # ]:          0 :         if (ce)
     848                 :          0 :                 mb_cache_entry_release(ce);
     849                 :            :         brelse(new_bh);
     850 [ #  # ][ #  # ]:          0 :         if (!(bs->bh && s->base == bs->bh->b_data))
     851                 :          0 :                 kfree(s->base);
     852                 :            : 
     853                 :          0 :         return error;
     854                 :            : 
     855                 :            : cleanup_dquot:
     856                 :            :         dquot_free_block(inode, 1);
     857                 :            :         goto cleanup;
     858                 :            : 
     859                 :            : bad_block:
     860                 :          0 :         ext3_error(inode->i_sb, __func__,
     861                 :            :                    "inode %lu: bad block "E3FSBLK, inode->i_ino,
     862                 :            :                    EXT3_I(inode)->i_file_acl);
     863                 :          0 :         goto cleanup;
     864                 :            : 
     865                 :            : #undef header
     866                 :            : }
     867                 :            : 
     868                 :            : struct ext3_xattr_ibody_find {
     869                 :            :         struct ext3_xattr_search s;
     870                 :            :         struct ext3_iloc iloc;
     871                 :            : };
     872                 :            : 
     873                 :            : static int
     874                 :          0 : ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
     875                 :            :                       struct ext3_xattr_ibody_find *is)
     876                 :            : {
     877                 :            :         struct ext3_xattr_ibody_header *header;
     878                 :            :         struct ext3_inode *raw_inode;
     879                 :            :         int error;
     880                 :            : 
     881         [ #  # ]:          0 :         if (EXT3_I(inode)->i_extra_isize == 0)
     882                 :            :                 return 0;
     883                 :          0 :         raw_inode = ext3_raw_inode(&is->iloc);
     884                 :          0 :         header = IHDR(inode, raw_inode);
     885                 :          0 :         is->s.base = is->s.first = IFIRST(header);
     886                 :          0 :         is->s.here = is->s.first;
     887                 :          0 :         is->s.end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
     888         [ #  # ]:          0 :         if (ext3_test_inode_state(inode, EXT3_STATE_XATTR)) {
     889                 :            :                 error = ext3_xattr_check_names(IFIRST(header), is->s.end);
     890         [ #  # ]:          0 :                 if (error)
     891                 :            :                         return error;
     892                 :            :                 /* Find the named attribute. */
     893                 :          0 :                 error = ext3_xattr_find_entry(&is->s.here, i->name_index,
     894                 :          0 :                                               i->name, is->s.end -
     895                 :            :                                               (void *)is->s.base, 0);
     896         [ #  # ]:          0 :                 if (error && error != -ENODATA)
     897                 :            :                         return error;
     898                 :          0 :                 is->s.not_found = error;
     899                 :            :         }
     900                 :            :         return 0;
     901                 :            : }
     902                 :            : 
     903                 :            : static int
     904                 :          0 : ext3_xattr_ibody_set(handle_t *handle, struct inode *inode,
     905                 :            :                      struct ext3_xattr_info *i,
     906                 :            :                      struct ext3_xattr_ibody_find *is)
     907                 :            : {
     908                 :            :         struct ext3_xattr_ibody_header *header;
     909                 :          0 :         struct ext3_xattr_search *s = &is->s;
     910                 :            :         int error;
     911                 :            : 
     912         [ #  # ]:          0 :         if (EXT3_I(inode)->i_extra_isize == 0)
     913                 :            :                 return -ENOSPC;
     914                 :          0 :         error = ext3_xattr_set_entry(i, s);
     915         [ #  # ]:          0 :         if (error)
     916                 :            :                 return error;
     917                 :          0 :         header = IHDR(inode, ext3_raw_inode(&is->iloc));
     918         [ #  # ]:          0 :         if (!IS_LAST_ENTRY(s->first)) {
     919                 :          0 :                 header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
     920                 :            :                 ext3_set_inode_state(inode, EXT3_STATE_XATTR);
     921                 :            :         } else {
     922                 :          0 :                 header->h_magic = cpu_to_le32(0);
     923                 :            :                 ext3_clear_inode_state(inode, EXT3_STATE_XATTR);
     924                 :            :         }
     925                 :            :         return 0;
     926                 :            : }
     927                 :            : 
     928                 :            : /*
     929                 :            :  * ext3_xattr_set_handle()
     930                 :            :  *
     931                 :            :  * Create, replace or remove an extended attribute for this inode.  Value
     932                 :            :  * is NULL to remove an existing extended attribute, and non-NULL to
     933                 :            :  * either replace an existing extended attribute, or create a new extended
     934                 :            :  * attribute. The flags XATTR_REPLACE and XATTR_CREATE
     935                 :            :  * specify that an extended attribute must exist and must not exist
     936                 :            :  * previous to the call, respectively.
     937                 :            :  *
     938                 :            :  * Returns 0, or a negative error number on failure.
     939                 :            :  */
     940                 :            : int
     941                 :          0 : ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
     942                 :            :                       const char *name, const void *value, size_t value_len,
     943                 :            :                       int flags)
     944                 :            : {
     945                 :          0 :         struct ext3_xattr_info i = {
     946                 :            :                 .name_index = name_index,
     947                 :            :                 .name = name,
     948                 :            :                 .value = value,
     949                 :            :                 .value_len = value_len,
     950                 :            : 
     951                 :            :         };
     952                 :          0 :         struct ext3_xattr_ibody_find is = {
     953                 :            :                 .s = { .not_found = -ENODATA, },
     954                 :            :         };
     955                 :          0 :         struct ext3_xattr_block_find bs = {
     956                 :            :                 .s = { .not_found = -ENODATA, },
     957                 :            :         };
     958                 :            :         int error;
     959                 :            : 
     960         [ #  # ]:          0 :         if (!name)
     961                 :            :                 return -EINVAL;
     962         [ #  # ]:          0 :         if (strlen(name) > 255)
     963                 :            :                 return -ERANGE;
     964                 :          0 :         down_write(&EXT3_I(inode)->xattr_sem);
     965                 :          0 :         error = ext3_get_inode_loc(inode, &is.iloc);
     966         [ #  # ]:          0 :         if (error)
     967                 :            :                 goto cleanup;
     968                 :            : 
     969                 :          0 :         error = ext3_journal_get_write_access(handle, is.iloc.bh);
     970         [ #  # ]:          0 :         if (error)
     971                 :            :                 goto cleanup;
     972                 :            : 
     973         [ #  # ]:          0 :         if (ext3_test_inode_state(inode, EXT3_STATE_NEW)) {
     974                 :          0 :                 struct ext3_inode *raw_inode = ext3_raw_inode(&is.iloc);
     975         [ #  # ]:          0 :                 memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
     976                 :            :                 ext3_clear_inode_state(inode, EXT3_STATE_NEW);
     977                 :            :         }
     978                 :            : 
     979                 :          0 :         error = ext3_xattr_ibody_find(inode, &i, &is);
     980         [ #  # ]:          0 :         if (error)
     981                 :            :                 goto cleanup;
     982         [ #  # ]:          0 :         if (is.s.not_found)
     983                 :          0 :                 error = ext3_xattr_block_find(inode, &i, &bs);
     984         [ #  # ]:          0 :         if (error)
     985                 :            :                 goto cleanup;
     986 [ #  # ][ #  # ]:          0 :         if (is.s.not_found && bs.s.not_found) {
     987                 :            :                 error = -ENODATA;
     988         [ #  # ]:          0 :                 if (flags & XATTR_REPLACE)
     989                 :            :                         goto cleanup;
     990                 :            :                 error = 0;
     991         [ #  # ]:          0 :                 if (!value)
     992                 :            :                         goto cleanup;
     993                 :            :         } else {
     994                 :            :                 error = -EEXIST;
     995         [ #  # ]:          0 :                 if (flags & XATTR_CREATE)
     996                 :            :                         goto cleanup;
     997                 :            :         }
     998         [ #  # ]:          0 :         if (!value) {
     999         [ #  # ]:          0 :                 if (!is.s.not_found)
    1000                 :          0 :                         error = ext3_xattr_ibody_set(handle, inode, &i, &is);
    1001         [ #  # ]:          0 :                 else if (!bs.s.not_found)
    1002                 :          0 :                         error = ext3_xattr_block_set(handle, inode, &i, &bs);
    1003                 :            :         } else {
    1004                 :          0 :                 error = ext3_xattr_ibody_set(handle, inode, &i, &is);
    1005 [ #  # ][ #  # ]:          0 :                 if (!error && !bs.s.not_found) {
    1006                 :          0 :                         i.value = NULL;
    1007                 :          0 :                         error = ext3_xattr_block_set(handle, inode, &i, &bs);
    1008         [ #  # ]:          0 :                 } else if (error == -ENOSPC) {
    1009 [ #  # ][ #  # ]:          0 :                         if (EXT3_I(inode)->i_file_acl && !bs.s.base) {
    1010                 :          0 :                                 error = ext3_xattr_block_find(inode, &i, &bs);
    1011         [ #  # ]:          0 :                                 if (error)
    1012                 :            :                                         goto cleanup;
    1013                 :            :                         }
    1014                 :          0 :                         error = ext3_xattr_block_set(handle, inode, &i, &bs);
    1015         [ #  # ]:          0 :                         if (error)
    1016                 :            :                                 goto cleanup;
    1017         [ #  # ]:          0 :                         if (!is.s.not_found) {
    1018                 :          0 :                                 i.value = NULL;
    1019                 :          0 :                                 error = ext3_xattr_ibody_set(handle, inode, &i,
    1020                 :            :                                                              &is);
    1021                 :            :                         }
    1022                 :            :                 }
    1023                 :            :         }
    1024         [ #  # ]:          0 :         if (!error) {
    1025                 :          0 :                 ext3_xattr_update_super_block(handle, inode->i_sb);
    1026                 :          0 :                 inode->i_ctime = CURRENT_TIME_SEC;
    1027                 :          0 :                 error = ext3_mark_iloc_dirty(handle, inode, &is.iloc);
    1028                 :            :                 /*
    1029                 :            :                  * The bh is consumed by ext3_mark_iloc_dirty, even with
    1030                 :            :                  * error != 0.
    1031                 :            :                  */
    1032                 :          0 :                 is.iloc.bh = NULL;
    1033 [ #  # ][ #  # ]:          0 :                 if (IS_SYNC(inode))
    1034                 :          0 :                         handle->h_sync = 1;
    1035                 :            :         }
    1036                 :            : 
    1037                 :            : cleanup:
    1038                 :          0 :         brelse(is.iloc.bh);
    1039                 :          0 :         brelse(bs.bh);
    1040                 :          0 :         up_write(&EXT3_I(inode)->xattr_sem);
    1041                 :          0 :         return error;
    1042                 :            : }
    1043                 :            : 
    1044                 :            : /*
    1045                 :            :  * ext3_xattr_set()
    1046                 :            :  *
    1047                 :            :  * Like ext3_xattr_set_handle, but start from an inode. This extended
    1048                 :            :  * attribute modification is a filesystem transaction by itself.
    1049                 :            :  *
    1050                 :            :  * Returns 0, or a negative error number on failure.
    1051                 :            :  */
    1052                 :            : int
    1053                 :          0 : ext3_xattr_set(struct inode *inode, int name_index, const char *name,
    1054                 :            :                const void *value, size_t value_len, int flags)
    1055                 :            : {
    1056                 :            :         handle_t *handle;
    1057                 :          0 :         int error, retries = 0;
    1058                 :            : 
    1059                 :            : retry:
    1060         [ #  # ]:          0 :         handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
    1061         [ #  # ]:          0 :         if (IS_ERR(handle)) {
    1062                 :            :                 error = PTR_ERR(handle);
    1063                 :            :         } else {
    1064                 :            :                 int error2;
    1065                 :            : 
    1066                 :          0 :                 error = ext3_xattr_set_handle(handle, inode, name_index, name,
    1067                 :            :                                               value, value_len, flags);
    1068                 :          0 :                 error2 = ext3_journal_stop(handle);
    1069   [ #  #  #  # ]:          0 :                 if (error == -ENOSPC &&
    1070                 :          0 :                     ext3_should_retry_alloc(inode->i_sb, &retries))
    1071                 :            :                         goto retry;
    1072         [ #  # ]:          0 :                 if (error == 0)
    1073                 :            :                         error = error2;
    1074                 :            :         }
    1075                 :            : 
    1076                 :          0 :         return error;
    1077                 :            : }
    1078                 :            : 
    1079                 :            : /*
    1080                 :            :  * ext3_xattr_delete_inode()
    1081                 :            :  *
    1082                 :            :  * Free extended attribute resources associated with this inode. This
    1083                 :            :  * is called immediately before an inode is freed. We have exclusive
    1084                 :            :  * access to the inode.
    1085                 :            :  */
    1086                 :            : void
    1087                 :          0 : ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
    1088                 :            : {
    1089                 :            :         struct buffer_head *bh = NULL;
    1090                 :            : 
    1091         [ #  # ]:          0 :         if (!EXT3_I(inode)->i_file_acl)
    1092                 :            :                 goto cleanup;
    1093                 :          0 :         bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
    1094         [ #  # ]:          0 :         if (!bh) {
    1095                 :          0 :                 ext3_error(inode->i_sb, __func__,
    1096                 :            :                         "inode %lu: block "E3FSBLK" read error", inode->i_ino,
    1097                 :            :                         EXT3_I(inode)->i_file_acl);
    1098                 :          0 :                 goto cleanup;
    1099                 :            :         }
    1100 [ #  # ][ #  # ]:          0 :         if (BHDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
    1101                 :          0 :             BHDR(bh)->h_blocks != cpu_to_le32(1)) {
    1102                 :          0 :                 ext3_error(inode->i_sb, __func__,
    1103                 :            :                         "inode %lu: bad block "E3FSBLK, inode->i_ino,
    1104                 :            :                         EXT3_I(inode)->i_file_acl);
    1105                 :          0 :                 goto cleanup;
    1106                 :            :         }
    1107                 :          0 :         ext3_xattr_release_block(handle, inode, bh);
    1108                 :          0 :         EXT3_I(inode)->i_file_acl = 0;
    1109                 :            : 
    1110                 :            : cleanup:
    1111                 :            :         brelse(bh);
    1112                 :          0 : }
    1113                 :            : 
    1114                 :            : /*
    1115                 :            :  * ext3_xattr_put_super()
    1116                 :            :  *
    1117                 :            :  * This is called when a file system is unmounted.
    1118                 :            :  */
    1119                 :            : void
    1120                 :          0 : ext3_xattr_put_super(struct super_block *sb)
    1121                 :            : {
    1122                 :          0 :         mb_cache_shrink(sb->s_bdev);
    1123                 :          0 : }
    1124                 :            : 
    1125                 :            : /*
    1126                 :            :  * ext3_xattr_cache_insert()
    1127                 :            :  *
    1128                 :            :  * Create a new entry in the extended attribute cache, and insert
    1129                 :            :  * it unless such an entry is already in the cache.
    1130                 :            :  *
    1131                 :            :  * Returns 0, or a negative error number on failure.
    1132                 :            :  */
    1133                 :            : static void
    1134                 :          0 : ext3_xattr_cache_insert(struct buffer_head *bh)
    1135                 :            : {
    1136                 :          0 :         __u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
    1137                 :            :         struct mb_cache_entry *ce;
    1138                 :            :         int error;
    1139                 :            : 
    1140                 :          0 :         ce = mb_cache_entry_alloc(ext3_xattr_cache, GFP_NOFS);
    1141         [ #  # ]:          0 :         if (!ce) {
    1142                 :            :                 ea_bdebug(bh, "out of memory");
    1143                 :          0 :                 return;
    1144                 :            :         }
    1145                 :          0 :         error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, hash);
    1146         [ #  # ]:          0 :         if (error) {
    1147                 :          0 :                 mb_cache_entry_free(ce);
    1148                 :            :                 if (error == -EBUSY) {
    1149                 :            :                         ea_bdebug(bh, "already in cache");
    1150                 :            :                         error = 0;
    1151                 :            :                 }
    1152                 :            :         } else {
    1153                 :            :                 ea_bdebug(bh, "inserting [%x]", (int)hash);
    1154                 :          0 :                 mb_cache_entry_release(ce);
    1155                 :            :         }
    1156                 :            : }
    1157                 :            : 
    1158                 :            : /*
    1159                 :            :  * ext3_xattr_cmp()
    1160                 :            :  *
    1161                 :            :  * Compare two extended attribute blocks for equality.
    1162                 :            :  *
    1163                 :            :  * Returns 0 if the blocks are equal, 1 if they differ, and
    1164                 :            :  * a negative error number on errors.
    1165                 :            :  */
    1166                 :            : static int
    1167                 :          0 : ext3_xattr_cmp(struct ext3_xattr_header *header1,
    1168                 :            :                struct ext3_xattr_header *header2)
    1169                 :            : {
    1170                 :            :         struct ext3_xattr_entry *entry1, *entry2;
    1171                 :            : 
    1172                 :          0 :         entry1 = ENTRY(header1+1);
    1173                 :          0 :         entry2 = ENTRY(header2+1);
    1174         [ #  # ]:          0 :         while (!IS_LAST_ENTRY(entry1)) {
    1175         [ #  # ]:          0 :                 if (IS_LAST_ENTRY(entry2))
    1176                 :            :                         return 1;
    1177         [ #  # ]:          0 :                 if (entry1->e_hash != entry2->e_hash ||
    1178         [ #  # ]:          0 :                     entry1->e_name_index != entry2->e_name_index ||
    1179         [ #  # ]:          0 :                     entry1->e_name_len != entry2->e_name_len ||
    1180         [ #  # ]:          0 :                     entry1->e_value_size != entry2->e_value_size ||
    1181                 :          0 :                     memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
    1182                 :            :                         return 1;
    1183 [ #  # ][ #  # ]:          0 :                 if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
    1184                 :            :                         return -EIO;
    1185         [ #  # ]:          0 :                 if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
    1186                 :          0 :                            (char *)header2 + le16_to_cpu(entry2->e_value_offs),
    1187                 :            :                            le32_to_cpu(entry1->e_value_size)))
    1188                 :            :                         return 1;
    1189                 :            : 
    1190                 :          0 :                 entry1 = EXT3_XATTR_NEXT(entry1);
    1191                 :          0 :                 entry2 = EXT3_XATTR_NEXT(entry2);
    1192                 :            :         }
    1193         [ #  # ]:          0 :         if (!IS_LAST_ENTRY(entry2))
    1194                 :            :                 return 1;
    1195                 :          0 :         return 0;
    1196                 :            : }
    1197                 :            : 
    1198                 :            : /*
    1199                 :            :  * ext3_xattr_cache_find()
    1200                 :            :  *
    1201                 :            :  * Find an identical extended attribute block.
    1202                 :            :  *
    1203                 :            :  * Returns a pointer to the block found, or NULL if such a block was
    1204                 :            :  * not found or an error occurred.
    1205                 :            :  */
    1206                 :            : static struct buffer_head *
    1207                 :          0 : ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header,
    1208                 :            :                       struct mb_cache_entry **pce)
    1209                 :            : {
    1210                 :          0 :         __u32 hash = le32_to_cpu(header->h_hash);
    1211                 :            :         struct mb_cache_entry *ce;
    1212                 :            : 
    1213         [ #  # ]:          0 :         if (!header->h_hash)
    1214                 :            :                 return NULL;  /* never share */
    1215                 :            :         ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
    1216                 :            : again:
    1217                 :          0 :         ce = mb_cache_entry_find_first(ext3_xattr_cache, inode->i_sb->s_bdev,
    1218                 :            :                                        hash);
    1219         [ #  # ]:          0 :         while (ce) {
    1220                 :            :                 struct buffer_head *bh;
    1221                 :            : 
    1222         [ #  # ]:          0 :                 if (IS_ERR(ce)) {
    1223         [ #  # ]:          0 :                         if (PTR_ERR(ce) == -EAGAIN)
    1224                 :            :                                 goto again;
    1225                 :            :                         break;
    1226                 :            :                 }
    1227                 :          0 :                 bh = sb_bread(inode->i_sb, ce->e_block);
    1228         [ #  # ]:          0 :                 if (!bh) {
    1229                 :          0 :                         ext3_error(inode->i_sb, __func__,
    1230                 :            :                                 "inode %lu: block %lu read error",
    1231                 :          0 :                                 inode->i_ino, (unsigned long) ce->e_block);
    1232         [ #  # ]:          0 :                 } else if (le32_to_cpu(BHDR(bh)->h_refcount) >=
    1233                 :            :                                 EXT3_XATTR_REFCOUNT_MAX) {
    1234                 :            :                         ea_idebug(inode, "block %lu refcount %d>=%d",
    1235                 :            :                                   (unsigned long) ce->e_block,
    1236                 :            :                                   le32_to_cpu(BHDR(bh)->h_refcount),
    1237                 :            :                                           EXT3_XATTR_REFCOUNT_MAX);
    1238         [ #  # ]:          0 :                 } else if (ext3_xattr_cmp(header, BHDR(bh)) == 0) {
    1239                 :          0 :                         *pce = ce;
    1240                 :            :                         return bh;
    1241                 :            :                 }
    1242                 :            :                 brelse(bh);
    1243                 :          0 :                 ce = mb_cache_entry_find_next(ce, inode->i_sb->s_bdev, hash);
    1244                 :            :         }
    1245                 :            :         return NULL;
    1246                 :            : }
    1247                 :            : 
    1248                 :            : #define NAME_HASH_SHIFT 5
    1249                 :            : #define VALUE_HASH_SHIFT 16
    1250                 :            : 
    1251                 :            : /*
    1252                 :            :  * ext3_xattr_hash_entry()
    1253                 :            :  *
    1254                 :            :  * Compute the hash of an extended attribute.
    1255                 :            :  */
    1256                 :            : static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
    1257                 :            :                                          struct ext3_xattr_entry *entry)
    1258                 :            : {
    1259                 :            :         __u32 hash = 0;
    1260                 :          0 :         char *name = entry->e_name;
    1261                 :            :         int n;
    1262                 :            : 
    1263         [ #  # ]:          0 :         for (n=0; n < entry->e_name_len; n++) {
    1264                 :          0 :                 hash = (hash << NAME_HASH_SHIFT) ^
    1265                 :          0 :                        (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
    1266                 :          0 :                        *name++;
    1267                 :            :         }
    1268                 :            : 
    1269 [ #  # ][ #  # ]:          0 :         if (entry->e_value_block == 0 && entry->e_value_size != 0) {
    1270                 :          0 :                 __le32 *value = (__le32 *)((char *)header +
    1271                 :          0 :                         le16_to_cpu(entry->e_value_offs));
    1272         [ #  # ]:          0 :                 for (n = (le32_to_cpu(entry->e_value_size) +
    1273                 :          0 :                      EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
    1274                 :          0 :                         hash = (hash << VALUE_HASH_SHIFT) ^
    1275                 :            :                                (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
    1276                 :          0 :                                le32_to_cpu(*value++);
    1277                 :            :                 }
    1278                 :            :         }
    1279                 :          0 :         entry->e_hash = cpu_to_le32(hash);
    1280                 :            : }
    1281                 :            : 
    1282                 :            : #undef NAME_HASH_SHIFT
    1283                 :            : #undef VALUE_HASH_SHIFT
    1284                 :            : 
    1285                 :            : #define BLOCK_HASH_SHIFT 16
    1286                 :            : 
    1287                 :            : /*
    1288                 :            :  * ext3_xattr_rehash()
    1289                 :            :  *
    1290                 :            :  * Re-compute the extended attribute hash value after an entry has changed.
    1291                 :            :  */
    1292                 :          0 : static void ext3_xattr_rehash(struct ext3_xattr_header *header,
    1293                 :            :                               struct ext3_xattr_entry *entry)
    1294                 :            : {
    1295                 :            :         struct ext3_xattr_entry *here;
    1296                 :            :         __u32 hash = 0;
    1297                 :            : 
    1298                 :            :         ext3_xattr_hash_entry(header, entry);
    1299                 :          0 :         here = ENTRY(header+1);
    1300         [ #  # ]:          0 :         while (!IS_LAST_ENTRY(here)) {
    1301         [ #  # ]:          0 :                 if (!here->e_hash) {
    1302                 :            :                         /* Block is not shared if an entry's hash value == 0 */
    1303                 :            :                         hash = 0;
    1304                 :            :                         break;
    1305                 :            :                 }
    1306                 :          0 :                 hash = (hash << BLOCK_HASH_SHIFT) ^
    1307                 :            :                        (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
    1308                 :            :                        le32_to_cpu(here->e_hash);
    1309                 :          0 :                 here = EXT3_XATTR_NEXT(here);
    1310                 :            :         }
    1311                 :          0 :         header->h_hash = cpu_to_le32(hash);
    1312                 :          0 : }
    1313                 :            : 
    1314                 :            : #undef BLOCK_HASH_SHIFT
    1315                 :            : 
    1316                 :            : int __init
    1317                 :          0 : init_ext3_xattr(void)
    1318                 :            : {
    1319                 :          0 :         ext3_xattr_cache = mb_cache_create("ext3_xattr", 6);
    1320         [ #  # ]:          0 :         if (!ext3_xattr_cache)
    1321                 :            :                 return -ENOMEM;
    1322                 :          0 :         return 0;
    1323                 :            : }
    1324                 :            : 
    1325                 :            : void
    1326                 :          0 : exit_ext3_xattr(void)
    1327                 :            : {
    1328         [ #  # ]:          0 :         if (ext3_xattr_cache)
    1329                 :          0 :                 mb_cache_destroy(ext3_xattr_cache);
    1330                 :          0 :         ext3_xattr_cache = NULL;
    1331                 :          0 : }

Generated by: LCOV version 1.9