LCOV - code coverage report
Current view: top level - fs/ext4 - inline.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 19 1093 1.7 %
Date: 2023-07-31 20:08:22 Functions: 2 37 5.4 %

          Line data    Source code
       1             : // SPDX-License-Identifier: LGPL-2.1
       2             : /*
       3             :  * Copyright (c) 2012 Taobao.
       4             :  * Written by Tao Ma <boyu.mt@taobao.com>
       5             :  */
       6             : 
       7             : #include <linux/iomap.h>
       8             : #include <linux/fiemap.h>
       9             : #include <linux/namei.h>
      10             : #include <linux/iversion.h>
      11             : #include <linux/sched/mm.h>
      12             : 
      13             : #include "ext4_jbd2.h"
      14             : #include "ext4.h"
      15             : #include "xattr.h"
      16             : #include "truncate.h"
      17             : 
      18             : #define EXT4_XATTR_SYSTEM_DATA  "data"
      19             : #define EXT4_MIN_INLINE_DATA_SIZE       ((sizeof(__le32) * EXT4_N_BLOCKS))
      20             : #define EXT4_INLINE_DOTDOT_OFFSET       2
      21             : #define EXT4_INLINE_DOTDOT_SIZE         4
      22             : 
      23             : static int ext4_get_inline_size(struct inode *inode)
      24             : {
      25           0 :         if (EXT4_I(inode)->i_inline_off)
      26           0 :                 return EXT4_I(inode)->i_inline_size;
      27             : 
      28             :         return 0;
      29             : }
      30             : 
      31           0 : static int get_max_inline_xattr_value_size(struct inode *inode,
      32             :                                            struct ext4_iloc *iloc)
      33             : {
      34           0 :         struct ext4_xattr_ibody_header *header;
      35           0 :         struct ext4_xattr_entry *entry;
      36           0 :         struct ext4_inode *raw_inode;
      37           0 :         void *end;
      38           0 :         int free, min_offs;
      39             : 
      40           0 :         if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
      41             :                 return 0;
      42             : 
      43           0 :         min_offs = EXT4_SB(inode->i_sb)->s_inode_size -
      44           0 :                         EXT4_GOOD_OLD_INODE_SIZE -
      45           0 :                         EXT4_I(inode)->i_extra_isize -
      46             :                         sizeof(struct ext4_xattr_ibody_header);
      47             : 
      48             :         /*
      49             :          * We need to subtract another sizeof(__u32) since an in-inode xattr
      50             :          * needs an empty 4 bytes to indicate the gap between the xattr entry
      51             :          * and the name/value pair.
      52             :          */
      53           0 :         if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR))
      54           0 :                 return EXT4_XATTR_SIZE(min_offs -
      55             :                         EXT4_XATTR_LEN(strlen(EXT4_XATTR_SYSTEM_DATA)) -
      56             :                         EXT4_XATTR_ROUND - sizeof(__u32));
      57             : 
      58           0 :         raw_inode = ext4_raw_inode(iloc);
      59           0 :         header = IHDR(inode, raw_inode);
      60           0 :         entry = IFIRST(header);
      61           0 :         end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
      62             : 
      63             :         /* Compute min_offs. */
      64           0 :         while (!IS_LAST_ENTRY(entry)) {
      65           0 :                 void *next = EXT4_XATTR_NEXT(entry);
      66             : 
      67           0 :                 if (next >= end) {
      68           0 :                         EXT4_ERROR_INODE(inode,
      69             :                                          "corrupt xattr in inline inode");
      70           0 :                         return 0;
      71             :                 }
      72           0 :                 if (!entry->e_value_inum && entry->e_value_size) {
      73           0 :                         size_t offs = le16_to_cpu(entry->e_value_offs);
      74           0 :                         if (offs < min_offs)
      75           0 :                                 min_offs = offs;
      76             :                 }
      77             :                 entry = next;
      78             :         }
      79           0 :         free = min_offs -
      80           0 :                 ((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);
      81             : 
      82           0 :         if (EXT4_I(inode)->i_inline_off) {
      83           0 :                 entry = (struct ext4_xattr_entry *)
      84           0 :                         ((void *)raw_inode + EXT4_I(inode)->i_inline_off);
      85             : 
      86           0 :                 free += EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
      87           0 :                 goto out;
      88             :         }
      89             : 
      90           0 :         free -= EXT4_XATTR_LEN(strlen(EXT4_XATTR_SYSTEM_DATA));
      91             : 
      92           0 :         if (free > EXT4_XATTR_ROUND)
      93           0 :                 free = EXT4_XATTR_SIZE(free - EXT4_XATTR_ROUND);
      94             :         else
      95             :                 free = 0;
      96             : 
      97             : out:
      98             :         return free;
      99             : }
     100             : 
     101             : /*
     102             :  * Get the maximum size we now can store in an inode.
     103             :  * If we can't find the space for a xattr entry, don't use the space
     104             :  * of the extents since we have no space to indicate the inline data.
     105             :  */
     106           0 : int ext4_get_max_inline_size(struct inode *inode)
     107             : {
     108           0 :         int error, max_inline_size;
     109           0 :         struct ext4_iloc iloc;
     110             : 
     111           0 :         if (EXT4_I(inode)->i_extra_isize == 0)
     112             :                 return 0;
     113             : 
     114           0 :         error = ext4_get_inode_loc(inode, &iloc);
     115           0 :         if (error) {
     116           0 :                 ext4_error_inode_err(inode, __func__, __LINE__, 0, -error,
     117             :                                      "can't get inode location %lu",
     118             :                                      inode->i_ino);
     119           0 :                 return 0;
     120             :         }
     121             : 
     122           0 :         down_read(&EXT4_I(inode)->xattr_sem);
     123           0 :         max_inline_size = get_max_inline_xattr_value_size(inode, &iloc);
     124           0 :         up_read(&EXT4_I(inode)->xattr_sem);
     125             : 
     126           0 :         brelse(iloc.bh);
     127             : 
     128           0 :         if (!max_inline_size)
     129             :                 return 0;
     130             : 
     131           0 :         return max_inline_size + EXT4_MIN_INLINE_DATA_SIZE;
     132             : }
     133             : 
     134             : /*
     135             :  * this function does not take xattr_sem, which is OK because it is
     136             :  * currently only used in a code path coming form ext4_iget, before
     137             :  * the new inode has been unlocked
     138             :  */
     139        2842 : int ext4_find_inline_data_nolock(struct inode *inode)
     140             : {
     141        2842 :         struct ext4_xattr_ibody_find is = {
     142             :                 .s = { .not_found = -ENODATA, },
     143             :         };
     144        2842 :         struct ext4_xattr_info i = {
     145             :                 .name_index = EXT4_XATTR_INDEX_SYSTEM,
     146             :                 .name = EXT4_XATTR_SYSTEM_DATA,
     147             :         };
     148        2842 :         int error;
     149             : 
     150        2842 :         if (EXT4_I(inode)->i_extra_isize == 0)
     151             :                 return 0;
     152             : 
     153        2842 :         error = ext4_get_inode_loc(inode, &is.iloc);
     154        2842 :         if (error)
     155             :                 return error;
     156             : 
     157        2842 :         error = ext4_xattr_ibody_find(inode, &i, &is);
     158        2842 :         if (error)
     159           0 :                 goto out;
     160             : 
     161        2842 :         if (!is.s.not_found) {
     162           0 :                 if (is.s.here->e_value_inum) {
     163           0 :                         EXT4_ERROR_INODE(inode, "inline data xattr refers "
     164             :                                          "to an external xattr inode");
     165           0 :                         error = -EFSCORRUPTED;
     166           0 :                         goto out;
     167             :                 }
     168           0 :                 EXT4_I(inode)->i_inline_off = (u16)((void *)is.s.here -
     169             :                                         (void *)ext4_raw_inode(&is.iloc));
     170           0 :                 EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +
     171           0 :                                 le32_to_cpu(is.s.here->e_value_size);
     172             :         }
     173        2842 : out:
     174        2842 :         brelse(is.iloc.bh);
     175             :         return error;
     176             : }
     177             : 
     178           0 : static int ext4_read_inline_data(struct inode *inode, void *buffer,
     179             :                                  unsigned int len,
     180             :                                  struct ext4_iloc *iloc)
     181             : {
     182           0 :         struct ext4_xattr_entry *entry;
     183           0 :         struct ext4_xattr_ibody_header *header;
     184           0 :         int cp_len = 0;
     185           0 :         struct ext4_inode *raw_inode;
     186             : 
     187           0 :         if (!len)
     188             :                 return 0;
     189             : 
     190           0 :         BUG_ON(len > EXT4_I(inode)->i_inline_size);
     191             : 
     192           0 :         cp_len = min_t(unsigned int, len, EXT4_MIN_INLINE_DATA_SIZE);
     193             : 
     194           0 :         raw_inode = ext4_raw_inode(iloc);
     195           0 :         memcpy(buffer, (void *)(raw_inode->i_block), cp_len);
     196             : 
     197           0 :         len -= cp_len;
     198           0 :         buffer += cp_len;
     199             : 
     200           0 :         if (!len)
     201           0 :                 goto out;
     202             : 
     203           0 :         header = IHDR(inode, raw_inode);
     204           0 :         entry = (struct ext4_xattr_entry *)((void *)raw_inode +
     205           0 :                                             EXT4_I(inode)->i_inline_off);
     206           0 :         len = min_t(unsigned int, len,
     207             :                     (unsigned int)le32_to_cpu(entry->e_value_size));
     208             : 
     209           0 :         memcpy(buffer,
     210             :                (void *)IFIRST(header) + le16_to_cpu(entry->e_value_offs), len);
     211           0 :         cp_len += len;
     212             : 
     213             : out:
     214             :         return cp_len;
     215             : }
     216             : 
     217             : /*
     218             :  * write the buffer to the inline inode.
     219             :  * If 'create' is set, we don't need to do the extra copy in the xattr
     220             :  * value since it is already handled by ext4_xattr_ibody_set.
     221             :  * That saves us one memcpy.
     222             :  */
     223           0 : static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc,
     224             :                                    void *buffer, loff_t pos, unsigned int len)
     225             : {
     226           0 :         struct ext4_xattr_entry *entry;
     227           0 :         struct ext4_xattr_ibody_header *header;
     228           0 :         struct ext4_inode *raw_inode;
     229           0 :         int cp_len = 0;
     230             : 
     231           0 :         if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
     232             :                 return;
     233             : 
     234           0 :         BUG_ON(!EXT4_I(inode)->i_inline_off);
     235           0 :         BUG_ON(pos + len > EXT4_I(inode)->i_inline_size);
     236             : 
     237           0 :         raw_inode = ext4_raw_inode(iloc);
     238           0 :         buffer += pos;
     239             : 
     240           0 :         if (pos < EXT4_MIN_INLINE_DATA_SIZE) {
     241           0 :                 cp_len = pos + len > EXT4_MIN_INLINE_DATA_SIZE ?
     242           0 :                          EXT4_MIN_INLINE_DATA_SIZE - pos : len;
     243           0 :                 memcpy((void *)raw_inode->i_block + pos, buffer, cp_len);
     244             : 
     245           0 :                 len -= cp_len;
     246           0 :                 buffer += cp_len;
     247           0 :                 pos += cp_len;
     248             :         }
     249             : 
     250           0 :         if (!len)
     251             :                 return;
     252             : 
     253           0 :         pos -= EXT4_MIN_INLINE_DATA_SIZE;
     254           0 :         header = IHDR(inode, raw_inode);
     255           0 :         entry = (struct ext4_xattr_entry *)((void *)raw_inode +
     256           0 :                                             EXT4_I(inode)->i_inline_off);
     257             : 
     258           0 :         memcpy((void *)IFIRST(header) + le16_to_cpu(entry->e_value_offs) + pos,
     259             :                buffer, len);
     260             : }
     261             : 
     262           0 : static int ext4_create_inline_data(handle_t *handle,
     263             :                                    struct inode *inode, unsigned len)
     264             : {
     265           0 :         int error;
     266           0 :         void *value = NULL;
     267           0 :         struct ext4_xattr_ibody_find is = {
     268             :                 .s = { .not_found = -ENODATA, },
     269             :         };
     270           0 :         struct ext4_xattr_info i = {
     271             :                 .name_index = EXT4_XATTR_INDEX_SYSTEM,
     272             :                 .name = EXT4_XATTR_SYSTEM_DATA,
     273             :         };
     274             : 
     275           0 :         error = ext4_get_inode_loc(inode, &is.iloc);
     276           0 :         if (error)
     277             :                 return error;
     278             : 
     279           0 :         BUFFER_TRACE(is.iloc.bh, "get_write_access");
     280           0 :         error = ext4_journal_get_write_access(handle, inode->i_sb, is.iloc.bh,
     281             :                                               EXT4_JTR_NONE);
     282           0 :         if (error)
     283           0 :                 goto out;
     284             : 
     285           0 :         if (len > EXT4_MIN_INLINE_DATA_SIZE) {
     286           0 :                 value = EXT4_ZERO_XATTR_VALUE;
     287           0 :                 len -= EXT4_MIN_INLINE_DATA_SIZE;
     288             :         } else {
     289             :                 value = "";
     290             :                 len = 0;
     291             :         }
     292             : 
     293             :         /* Insert the xttr entry. */
     294           0 :         i.value = value;
     295           0 :         i.value_len = len;
     296             : 
     297           0 :         error = ext4_xattr_ibody_find(inode, &i, &is);
     298           0 :         if (error)
     299           0 :                 goto out;
     300             : 
     301           0 :         BUG_ON(!is.s.not_found);
     302             : 
     303           0 :         error = ext4_xattr_ibody_set(handle, inode, &i, &is);
     304           0 :         if (error) {
     305           0 :                 if (error == -ENOSPC)
     306           0 :                         ext4_clear_inode_state(inode,
     307             :                                                EXT4_STATE_MAY_INLINE_DATA);
     308           0 :                 goto out;
     309             :         }
     310             : 
     311           0 :         memset((void *)ext4_raw_inode(&is.iloc)->i_block,
     312             :                 0, EXT4_MIN_INLINE_DATA_SIZE);
     313             : 
     314           0 :         EXT4_I(inode)->i_inline_off = (u16)((void *)is.s.here -
     315             :                                       (void *)ext4_raw_inode(&is.iloc));
     316           0 :         EXT4_I(inode)->i_inline_size = len + EXT4_MIN_INLINE_DATA_SIZE;
     317           0 :         ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS);
     318           0 :         ext4_set_inode_flag(inode, EXT4_INODE_INLINE_DATA);
     319           0 :         get_bh(is.iloc.bh);
     320           0 :         error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
     321             : 
     322           0 : out:
     323           0 :         brelse(is.iloc.bh);
     324             :         return error;
     325             : }
     326             : 
     327           0 : static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
     328             :                                    unsigned int len)
     329             : {
     330           0 :         int error;
     331           0 :         void *value = NULL;
     332           0 :         struct ext4_xattr_ibody_find is = {
     333             :                 .s = { .not_found = -ENODATA, },
     334             :         };
     335           0 :         struct ext4_xattr_info i = {
     336             :                 .name_index = EXT4_XATTR_INDEX_SYSTEM,
     337             :                 .name = EXT4_XATTR_SYSTEM_DATA,
     338             :         };
     339             : 
     340             :         /* If the old space is ok, write the data directly. */
     341           0 :         if (len <= EXT4_I(inode)->i_inline_size)
     342             :                 return 0;
     343             : 
     344           0 :         error = ext4_get_inode_loc(inode, &is.iloc);
     345           0 :         if (error)
     346             :                 return error;
     347             : 
     348           0 :         error = ext4_xattr_ibody_find(inode, &i, &is);
     349           0 :         if (error)
     350           0 :                 goto out;
     351             : 
     352           0 :         BUG_ON(is.s.not_found);
     353             : 
     354           0 :         len -= EXT4_MIN_INLINE_DATA_SIZE;
     355           0 :         value = kzalloc(len, GFP_NOFS);
     356           0 :         if (!value) {
     357           0 :                 error = -ENOMEM;
     358           0 :                 goto out;
     359             :         }
     360             : 
     361           0 :         error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
     362             :                                      value, len);
     363           0 :         if (error < 0)
     364           0 :                 goto out;
     365             : 
     366           0 :         BUFFER_TRACE(is.iloc.bh, "get_write_access");
     367           0 :         error = ext4_journal_get_write_access(handle, inode->i_sb, is.iloc.bh,
     368             :                                               EXT4_JTR_NONE);
     369           0 :         if (error)
     370           0 :                 goto out;
     371             : 
     372             :         /* Update the xattr entry. */
     373           0 :         i.value = value;
     374           0 :         i.value_len = len;
     375             : 
     376           0 :         error = ext4_xattr_ibody_set(handle, inode, &i, &is);
     377           0 :         if (error)
     378           0 :                 goto out;
     379             : 
     380           0 :         EXT4_I(inode)->i_inline_off = (u16)((void *)is.s.here -
     381             :                                       (void *)ext4_raw_inode(&is.iloc));
     382           0 :         EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +
     383           0 :                                 le32_to_cpu(is.s.here->e_value_size);
     384           0 :         ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
     385           0 :         get_bh(is.iloc.bh);
     386           0 :         error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
     387             : 
     388           0 : out:
     389           0 :         kfree(value);
     390           0 :         brelse(is.iloc.bh);
     391             :         return error;
     392             : }
     393             : 
     394           0 : static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode,
     395             :                                     unsigned int len)
     396             : {
     397           0 :         int ret, size, no_expand;
     398           0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     399             : 
     400           0 :         if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
     401             :                 return -ENOSPC;
     402             : 
     403           0 :         size = ext4_get_max_inline_size(inode);
     404           0 :         if (size < len)
     405             :                 return -ENOSPC;
     406             : 
     407           0 :         ext4_write_lock_xattr(inode, &no_expand);
     408             : 
     409           0 :         if (ei->i_inline_off)
     410           0 :                 ret = ext4_update_inline_data(handle, inode, len);
     411             :         else
     412           0 :                 ret = ext4_create_inline_data(handle, inode, len);
     413             : 
     414           0 :         ext4_write_unlock_xattr(inode, &no_expand);
     415           0 :         return ret;
     416             : }
     417             : 
     418           0 : static int ext4_destroy_inline_data_nolock(handle_t *handle,
     419             :                                            struct inode *inode)
     420             : {
     421           0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     422           0 :         struct ext4_xattr_ibody_find is = {
     423             :                 .s = { .not_found = 0, },
     424             :         };
     425           0 :         struct ext4_xattr_info i = {
     426             :                 .name_index = EXT4_XATTR_INDEX_SYSTEM,
     427             :                 .name = EXT4_XATTR_SYSTEM_DATA,
     428             :                 .value = NULL,
     429             :                 .value_len = 0,
     430             :         };
     431           0 :         int error;
     432             : 
     433           0 :         if (!ei->i_inline_off)
     434             :                 return 0;
     435             : 
     436           0 :         error = ext4_get_inode_loc(inode, &is.iloc);
     437           0 :         if (error)
     438             :                 return error;
     439             : 
     440           0 :         error = ext4_xattr_ibody_find(inode, &i, &is);
     441           0 :         if (error)
     442           0 :                 goto out;
     443             : 
     444           0 :         BUFFER_TRACE(is.iloc.bh, "get_write_access");
     445           0 :         error = ext4_journal_get_write_access(handle, inode->i_sb, is.iloc.bh,
     446             :                                               EXT4_JTR_NONE);
     447           0 :         if (error)
     448           0 :                 goto out;
     449             : 
     450           0 :         error = ext4_xattr_ibody_set(handle, inode, &i, &is);
     451           0 :         if (error)
     452           0 :                 goto out;
     453             : 
     454           0 :         memset((void *)ext4_raw_inode(&is.iloc)->i_block,
     455             :                 0, EXT4_MIN_INLINE_DATA_SIZE);
     456           0 :         memset(ei->i_data, 0, EXT4_MIN_INLINE_DATA_SIZE);
     457             : 
     458           0 :         if (ext4_has_feature_extents(inode->i_sb)) {
     459           0 :                 if (S_ISDIR(inode->i_mode) ||
     460           0 :                     S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) {
     461           0 :                         ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
     462           0 :                         ext4_ext_tree_init(handle, inode);
     463             :                 }
     464             :         }
     465           0 :         ext4_clear_inode_flag(inode, EXT4_INODE_INLINE_DATA);
     466             : 
     467           0 :         get_bh(is.iloc.bh);
     468           0 :         error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
     469             : 
     470           0 :         EXT4_I(inode)->i_inline_off = 0;
     471           0 :         EXT4_I(inode)->i_inline_size = 0;
     472           0 :         ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
     473           0 : out:
     474           0 :         brelse(is.iloc.bh);
     475           0 :         if (error == -ENODATA)
     476           0 :                 error = 0;
     477             :         return error;
     478             : }
     479             : 
     480           0 : static int ext4_read_inline_folio(struct inode *inode, struct folio *folio)
     481             : {
     482           0 :         void *kaddr;
     483           0 :         int ret = 0;
     484           0 :         size_t len;
     485           0 :         struct ext4_iloc iloc;
     486             : 
     487           0 :         BUG_ON(!folio_test_locked(folio));
     488           0 :         BUG_ON(!ext4_has_inline_data(inode));
     489           0 :         BUG_ON(folio->index);
     490             : 
     491           0 :         if (!EXT4_I(inode)->i_inline_off) {
     492           0 :                 ext4_warning(inode->i_sb, "inode %lu doesn't have inline data.",
     493             :                              inode->i_ino);
     494           0 :                 goto out;
     495             :         }
     496             : 
     497           0 :         ret = ext4_get_inode_loc(inode, &iloc);
     498           0 :         if (ret)
     499           0 :                 goto out;
     500             : 
     501           0 :         len = min_t(size_t, ext4_get_inline_size(inode), i_size_read(inode));
     502           0 :         BUG_ON(len > PAGE_SIZE);
     503           0 :         kaddr = kmap_local_folio(folio, 0);
     504           0 :         ret = ext4_read_inline_data(inode, kaddr, len, &iloc);
     505           0 :         flush_dcache_folio(folio);
     506           0 :         kunmap_local(kaddr);
     507           0 :         folio_zero_segment(folio, len, folio_size(folio));
     508           0 :         folio_mark_uptodate(folio);
     509           0 :         brelse(iloc.bh);
     510             : 
     511           0 : out:
     512           0 :         return ret;
     513             : }
     514             : 
     515           0 : int ext4_readpage_inline(struct inode *inode, struct folio *folio)
     516             : {
     517           0 :         int ret = 0;
     518             : 
     519           0 :         down_read(&EXT4_I(inode)->xattr_sem);
     520           0 :         if (!ext4_has_inline_data(inode)) {
     521           0 :                 up_read(&EXT4_I(inode)->xattr_sem);
     522           0 :                 return -EAGAIN;
     523             :         }
     524             : 
     525             :         /*
     526             :          * Current inline data can only exist in the 1st page,
     527             :          * So for all the other pages, just set them uptodate.
     528             :          */
     529           0 :         if (!folio->index)
     530           0 :                 ret = ext4_read_inline_folio(inode, folio);
     531           0 :         else if (!folio_test_uptodate(folio)) {
     532           0 :                 folio_zero_segment(folio, 0, folio_size(folio));
     533           0 :                 folio_mark_uptodate(folio);
     534             :         }
     535             : 
     536           0 :         up_read(&EXT4_I(inode)->xattr_sem);
     537             : 
     538           0 :         folio_unlock(folio);
     539           0 :         return ret >= 0 ? 0 : ret;
     540             : }
     541             : 
     542           0 : static int ext4_convert_inline_data_to_extent(struct address_space *mapping,
     543             :                                               struct inode *inode)
     544             : {
     545           0 :         int ret, needed_blocks, no_expand;
     546           0 :         handle_t *handle = NULL;
     547           0 :         int retries = 0, sem_held = 0;
     548           0 :         struct folio *folio = NULL;
     549           0 :         unsigned from, to;
     550           0 :         struct ext4_iloc iloc;
     551             : 
     552           0 :         if (!ext4_has_inline_data(inode)) {
     553             :                 /*
     554             :                  * clear the flag so that no new write
     555             :                  * will trap here again.
     556             :                  */
     557           0 :                 ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
     558           0 :                 return 0;
     559             :         }
     560             : 
     561           0 :         needed_blocks = ext4_writepage_trans_blocks(inode);
     562             : 
     563           0 :         ret = ext4_get_inode_loc(inode, &iloc);
     564           0 :         if (ret)
     565             :                 return ret;
     566             : 
     567           0 : retry:
     568           0 :         handle = ext4_journal_start(inode, EXT4_HT_WRITE_PAGE, needed_blocks);
     569           0 :         if (IS_ERR(handle)) {
     570           0 :                 ret = PTR_ERR(handle);
     571           0 :                 handle = NULL;
     572           0 :                 goto out;
     573             :         }
     574             : 
     575             :         /* We cannot recurse into the filesystem as the transaction is already
     576             :          * started */
     577           0 :         folio = __filemap_get_folio(mapping, 0, FGP_WRITEBEGIN | FGP_NOFS,
     578             :                         mapping_gfp_mask(mapping));
     579           0 :         if (IS_ERR(folio)) {
     580           0 :                 ret = PTR_ERR(folio);
     581           0 :                 goto out_nofolio;
     582             :         }
     583             : 
     584           0 :         ext4_write_lock_xattr(inode, &no_expand);
     585           0 :         sem_held = 1;
     586             :         /* If some one has already done this for us, just exit. */
     587           0 :         if (!ext4_has_inline_data(inode)) {
     588           0 :                 ret = 0;
     589           0 :                 goto out;
     590             :         }
     591             : 
     592           0 :         from = 0;
     593           0 :         to = ext4_get_inline_size(inode);
     594           0 :         if (!folio_test_uptodate(folio)) {
     595           0 :                 ret = ext4_read_inline_folio(inode, folio);
     596           0 :                 if (ret < 0)
     597           0 :                         goto out;
     598             :         }
     599             : 
     600           0 :         ret = ext4_destroy_inline_data_nolock(handle, inode);
     601           0 :         if (ret)
     602           0 :                 goto out;
     603             : 
     604           0 :         if (ext4_should_dioread_nolock(inode)) {
     605           0 :                 ret = __block_write_begin(&folio->page, from, to,
     606             :                                           ext4_get_block_unwritten);
     607             :         } else
     608           0 :                 ret = __block_write_begin(&folio->page, from, to, ext4_get_block);
     609             : 
     610           0 :         if (!ret && ext4_should_journal_data(inode)) {
     611           0 :                 ret = ext4_walk_page_buffers(handle, inode,
     612             :                                              folio_buffers(folio), from, to,
     613             :                                              NULL, do_journal_get_write_access);
     614             :         }
     615             : 
     616           0 :         if (ret) {
     617           0 :                 folio_unlock(folio);
     618           0 :                 folio_put(folio);
     619           0 :                 folio = NULL;
     620           0 :                 ext4_orphan_add(handle, inode);
     621           0 :                 ext4_write_unlock_xattr(inode, &no_expand);
     622           0 :                 sem_held = 0;
     623           0 :                 ext4_journal_stop(handle);
     624           0 :                 handle = NULL;
     625           0 :                 ext4_truncate_failed_write(inode);
     626             :                 /*
     627             :                  * If truncate failed early the inode might
     628             :                  * still be on the orphan list; we need to
     629             :                  * make sure the inode is removed from the
     630             :                  * orphan list in that case.
     631             :                  */
     632           0 :                 if (inode->i_nlink)
     633           0 :                         ext4_orphan_del(NULL, inode);
     634             :         }
     635             : 
     636           0 :         if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
     637           0 :                 goto retry;
     638             : 
     639           0 :         if (folio)
     640           0 :                 block_commit_write(&folio->page, from, to);
     641           0 : out:
     642           0 :         if (folio) {
     643           0 :                 folio_unlock(folio);
     644           0 :                 folio_put(folio);
     645             :         }
     646           0 : out_nofolio:
     647           0 :         if (sem_held)
     648           0 :                 ext4_write_unlock_xattr(inode, &no_expand);
     649           0 :         if (handle)
     650           0 :                 ext4_journal_stop(handle);
     651           0 :         brelse(iloc.bh);
     652             :         return ret;
     653             : }
     654             : 
     655             : /*
     656             :  * Try to write data in the inode.
     657             :  * If the inode has inline data, check whether the new write can be
     658             :  * in the inode also. If not, create the page the handle, move the data
     659             :  * to the page make it update and let the later codes create extent for it.
     660             :  */
     661           0 : int ext4_try_to_write_inline_data(struct address_space *mapping,
     662             :                                   struct inode *inode,
     663             :                                   loff_t pos, unsigned len,
     664             :                                   struct page **pagep)
     665             : {
     666           0 :         int ret;
     667           0 :         handle_t *handle;
     668           0 :         struct folio *folio;
     669           0 :         struct ext4_iloc iloc;
     670             : 
     671           0 :         if (pos + len > ext4_get_max_inline_size(inode))
     672           0 :                 goto convert;
     673             : 
     674           0 :         ret = ext4_get_inode_loc(inode, &iloc);
     675           0 :         if (ret)
     676             :                 return ret;
     677             : 
     678             :         /*
     679             :          * The possible write could happen in the inode,
     680             :          * so try to reserve the space in inode first.
     681             :          */
     682           0 :         handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
     683           0 :         if (IS_ERR(handle)) {
     684           0 :                 ret = PTR_ERR(handle);
     685           0 :                 handle = NULL;
     686           0 :                 goto out;
     687             :         }
     688             : 
     689           0 :         ret = ext4_prepare_inline_data(handle, inode, pos + len);
     690           0 :         if (ret && ret != -ENOSPC)
     691           0 :                 goto out;
     692             : 
     693             :         /* We don't have space in inline inode, so convert it to extent. */
     694           0 :         if (ret == -ENOSPC) {
     695           0 :                 ext4_journal_stop(handle);
     696           0 :                 brelse(iloc.bh);
     697           0 :                 goto convert;
     698             :         }
     699             : 
     700           0 :         ret = ext4_journal_get_write_access(handle, inode->i_sb, iloc.bh,
     701             :                                             EXT4_JTR_NONE);
     702           0 :         if (ret)
     703           0 :                 goto out;
     704             : 
     705           0 :         folio = __filemap_get_folio(mapping, 0, FGP_WRITEBEGIN | FGP_NOFS,
     706             :                                         mapping_gfp_mask(mapping));
     707           0 :         if (IS_ERR(folio)) {
     708           0 :                 ret = PTR_ERR(folio);
     709           0 :                 goto out;
     710             :         }
     711             : 
     712           0 :         *pagep = &folio->page;
     713           0 :         down_read(&EXT4_I(inode)->xattr_sem);
     714           0 :         if (!ext4_has_inline_data(inode)) {
     715           0 :                 ret = 0;
     716           0 :                 folio_unlock(folio);
     717           0 :                 folio_put(folio);
     718           0 :                 goto out_up_read;
     719             :         }
     720             : 
     721           0 :         if (!folio_test_uptodate(folio)) {
     722           0 :                 ret = ext4_read_inline_folio(inode, folio);
     723           0 :                 if (ret < 0) {
     724           0 :                         folio_unlock(folio);
     725           0 :                         folio_put(folio);
     726           0 :                         goto out_up_read;
     727             :                 }
     728             :         }
     729             : 
     730             :         ret = 1;
     731             :         handle = NULL;
     732           0 : out_up_read:
     733           0 :         up_read(&EXT4_I(inode)->xattr_sem);
     734           0 : out:
     735           0 :         if (handle && (ret != 1))
     736           0 :                 ext4_journal_stop(handle);
     737           0 :         brelse(iloc.bh);
     738             :         return ret;
     739           0 : convert:
     740           0 :         return ext4_convert_inline_data_to_extent(mapping, inode);
     741             : }
     742             : 
     743           0 : int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
     744             :                                unsigned copied, struct folio *folio)
     745             : {
     746           0 :         handle_t *handle = ext4_journal_current_handle();
     747           0 :         int no_expand;
     748           0 :         void *kaddr;
     749           0 :         struct ext4_iloc iloc;
     750           0 :         int ret = 0, ret2;
     751             : 
     752           0 :         if (unlikely(copied < len) && !folio_test_uptodate(folio))
     753           0 :                 copied = 0;
     754             : 
     755           0 :         if (likely(copied)) {
     756           0 :                 ret = ext4_get_inode_loc(inode, &iloc);
     757           0 :                 if (ret) {
     758           0 :                         folio_unlock(folio);
     759           0 :                         folio_put(folio);
     760           0 :                         ext4_std_error(inode->i_sb, ret);
     761           0 :                         goto out;
     762             :                 }
     763           0 :                 ext4_write_lock_xattr(inode, &no_expand);
     764           0 :                 BUG_ON(!ext4_has_inline_data(inode));
     765             : 
     766             :                 /*
     767             :                  * ei->i_inline_off may have changed since
     768             :                  * ext4_write_begin() called
     769             :                  * ext4_try_to_write_inline_data()
     770             :                  */
     771           0 :                 (void) ext4_find_inline_data_nolock(inode);
     772             : 
     773           0 :                 kaddr = kmap_local_folio(folio, 0);
     774           0 :                 ext4_write_inline_data(inode, &iloc, kaddr, pos, copied);
     775           0 :                 kunmap_local(kaddr);
     776           0 :                 folio_mark_uptodate(folio);
     777             :                 /* clear dirty flag so that writepages wouldn't work for us. */
     778           0 :                 folio_clear_dirty(folio);
     779             : 
     780           0 :                 ext4_write_unlock_xattr(inode, &no_expand);
     781           0 :                 brelse(iloc.bh);
     782             : 
     783             :                 /*
     784             :                  * It's important to update i_size while still holding folio
     785             :                  * lock: page writeout could otherwise come in and zero
     786             :                  * beyond i_size.
     787             :                  */
     788           0 :                 ext4_update_inode_size(inode, pos + copied);
     789             :         }
     790           0 :         folio_unlock(folio);
     791           0 :         folio_put(folio);
     792             : 
     793             :         /*
     794             :          * Don't mark the inode dirty under folio lock. First, it unnecessarily
     795             :          * makes the holding time of folio lock longer. Second, it forces lock
     796             :          * ordering of folio lock and transaction start for journaling
     797             :          * filesystems.
     798             :          */
     799           0 :         if (likely(copied))
     800           0 :                 mark_inode_dirty(inode);
     801           0 : out:
     802             :         /*
     803             :          * If we didn't copy as much data as expected, we need to trim back
     804             :          * size of xattr containing inline data.
     805             :          */
     806           0 :         if (pos + len > inode->i_size && ext4_can_truncate(inode))
     807           0 :                 ext4_orphan_add(handle, inode);
     808             : 
     809           0 :         ret2 = ext4_journal_stop(handle);
     810           0 :         if (!ret)
     811           0 :                 ret = ret2;
     812           0 :         if (pos + len > inode->i_size) {
     813           0 :                 ext4_truncate_failed_write(inode);
     814             :                 /*
     815             :                  * If truncate failed early the inode might still be
     816             :                  * on the orphan list; we need to make sure the inode
     817             :                  * is removed from the orphan list in that case.
     818             :                  */
     819           0 :                 if (inode->i_nlink)
     820           0 :                         ext4_orphan_del(NULL, inode);
     821             :         }
     822           0 :         return ret ? ret : copied;
     823             : }
     824             : 
     825             : /*
     826             :  * Try to make the page cache and handle ready for the inline data case.
     827             :  * We can call this function in 2 cases:
     828             :  * 1. The inode is created and the first write exceeds inline size. We can
     829             :  *    clear the inode state safely.
     830             :  * 2. The inode has inline data, then we need to read the data, make it
     831             :  *    update and dirty so that ext4_da_writepages can handle it. We don't
     832             :  *    need to start the journal since the file's metadata isn't changed now.
     833             :  */
     834           0 : static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
     835             :                                                  struct inode *inode,
     836             :                                                  void **fsdata)
     837             : {
     838           0 :         int ret = 0, inline_size;
     839           0 :         struct folio *folio;
     840             : 
     841           0 :         folio = __filemap_get_folio(mapping, 0, FGP_WRITEBEGIN,
     842             :                                         mapping_gfp_mask(mapping));
     843           0 :         if (IS_ERR(folio))
     844           0 :                 return PTR_ERR(folio);
     845             : 
     846           0 :         down_read(&EXT4_I(inode)->xattr_sem);
     847           0 :         if (!ext4_has_inline_data(inode)) {
     848           0 :                 ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
     849           0 :                 goto out;
     850             :         }
     851             : 
     852           0 :         inline_size = ext4_get_inline_size(inode);
     853             : 
     854           0 :         if (!folio_test_uptodate(folio)) {
     855           0 :                 ret = ext4_read_inline_folio(inode, folio);
     856           0 :                 if (ret < 0)
     857           0 :                         goto out;
     858             :         }
     859             : 
     860           0 :         ret = __block_write_begin(&folio->page, 0, inline_size,
     861             :                                   ext4_da_get_block_prep);
     862           0 :         if (ret) {
     863           0 :                 up_read(&EXT4_I(inode)->xattr_sem);
     864           0 :                 folio_unlock(folio);
     865           0 :                 folio_put(folio);
     866           0 :                 ext4_truncate_failed_write(inode);
     867           0 :                 return ret;
     868             :         }
     869             : 
     870           0 :         folio_mark_dirty(folio);
     871           0 :         folio_mark_uptodate(folio);
     872           0 :         ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
     873           0 :         *fsdata = (void *)CONVERT_INLINE_DATA;
     874             : 
     875           0 : out:
     876           0 :         up_read(&EXT4_I(inode)->xattr_sem);
     877           0 :         if (folio) {
     878           0 :                 folio_unlock(folio);
     879           0 :                 folio_put(folio);
     880             :         }
     881             :         return ret;
     882             : }
     883             : 
     884             : /*
     885             :  * Prepare the write for the inline data.
     886             :  * If the data can be written into the inode, we just read
     887             :  * the page and make it uptodate, and start the journal.
     888             :  * Otherwise read the page, makes it dirty so that it can be
     889             :  * handle in writepages(the i_disksize update is left to the
     890             :  * normal ext4_da_write_end).
     891             :  */
     892           0 : int ext4_da_write_inline_data_begin(struct address_space *mapping,
     893             :                                     struct inode *inode,
     894             :                                     loff_t pos, unsigned len,
     895             :                                     struct page **pagep,
     896             :                                     void **fsdata)
     897             : {
     898           0 :         int ret;
     899           0 :         handle_t *handle;
     900           0 :         struct folio *folio;
     901           0 :         struct ext4_iloc iloc;
     902           0 :         int retries = 0;
     903             : 
     904           0 :         ret = ext4_get_inode_loc(inode, &iloc);
     905           0 :         if (ret)
     906             :                 return ret;
     907             : 
     908           0 : retry_journal:
     909           0 :         handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
     910           0 :         if (IS_ERR(handle)) {
     911           0 :                 ret = PTR_ERR(handle);
     912           0 :                 goto out;
     913             :         }
     914             : 
     915           0 :         ret = ext4_prepare_inline_data(handle, inode, pos + len);
     916           0 :         if (ret && ret != -ENOSPC)
     917           0 :                 goto out_journal;
     918             : 
     919           0 :         if (ret == -ENOSPC) {
     920           0 :                 ext4_journal_stop(handle);
     921           0 :                 ret = ext4_da_convert_inline_data_to_extent(mapping,
     922             :                                                             inode,
     923             :                                                             fsdata);
     924           0 :                 if (ret == -ENOSPC &&
     925           0 :                     ext4_should_retry_alloc(inode->i_sb, &retries))
     926           0 :                         goto retry_journal;
     927           0 :                 goto out;
     928             :         }
     929             : 
     930             :         /*
     931             :          * We cannot recurse into the filesystem as the transaction
     932             :          * is already started.
     933             :          */
     934           0 :         folio = __filemap_get_folio(mapping, 0, FGP_WRITEBEGIN | FGP_NOFS,
     935             :                                         mapping_gfp_mask(mapping));
     936           0 :         if (IS_ERR(folio)) {
     937           0 :                 ret = PTR_ERR(folio);
     938           0 :                 goto out_journal;
     939             :         }
     940             : 
     941           0 :         down_read(&EXT4_I(inode)->xattr_sem);
     942           0 :         if (!ext4_has_inline_data(inode)) {
     943           0 :                 ret = 0;
     944           0 :                 goto out_release_page;
     945             :         }
     946             : 
     947           0 :         if (!folio_test_uptodate(folio)) {
     948           0 :                 ret = ext4_read_inline_folio(inode, folio);
     949           0 :                 if (ret < 0)
     950           0 :                         goto out_release_page;
     951             :         }
     952           0 :         ret = ext4_journal_get_write_access(handle, inode->i_sb, iloc.bh,
     953             :                                             EXT4_JTR_NONE);
     954           0 :         if (ret)
     955           0 :                 goto out_release_page;
     956             : 
     957           0 :         up_read(&EXT4_I(inode)->xattr_sem);
     958           0 :         *pagep = &folio->page;
     959           0 :         brelse(iloc.bh);
     960             :         return 1;
     961           0 : out_release_page:
     962           0 :         up_read(&EXT4_I(inode)->xattr_sem);
     963           0 :         folio_unlock(folio);
     964           0 :         folio_put(folio);
     965           0 : out_journal:
     966           0 :         ext4_journal_stop(handle);
     967           0 : out:
     968           0 :         brelse(iloc.bh);
     969             :         return ret;
     970             : }
     971             : 
     972             : #ifdef INLINE_DIR_DEBUG
     973             : void ext4_show_inline_dir(struct inode *dir, struct buffer_head *bh,
     974             :                           void *inline_start, int inline_size)
     975             : {
     976             :         int offset;
     977             :         unsigned short de_len;
     978             :         struct ext4_dir_entry_2 *de = inline_start;
     979             :         void *dlimit = inline_start + inline_size;
     980             : 
     981             :         trace_printk("inode %lu\n", dir->i_ino);
     982             :         offset = 0;
     983             :         while ((void *)de < dlimit) {
     984             :                 de_len = ext4_rec_len_from_disk(de->rec_len, inline_size);
     985             :                 trace_printk("de: off %u rlen %u name %.*s nlen %u ino %u\n",
     986             :                              offset, de_len, de->name_len, de->name,
     987             :                              de->name_len, le32_to_cpu(de->inode));
     988             :                 if (ext4_check_dir_entry(dir, NULL, de, bh,
     989             :                                          inline_start, inline_size, offset))
     990             :                         BUG();
     991             : 
     992             :                 offset += de_len;
     993             :                 de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
     994             :         }
     995             : }
     996             : #else
     997             : #define ext4_show_inline_dir(dir, bh, inline_start, inline_size)
     998             : #endif
     999             : 
    1000             : /*
    1001             :  * Add a new entry into a inline dir.
    1002             :  * It will return -ENOSPC if no space is available, and -EIO
    1003             :  * and -EEXIST if directory entry already exists.
    1004             :  */
    1005           0 : static int ext4_add_dirent_to_inline(handle_t *handle,
    1006             :                                      struct ext4_filename *fname,
    1007             :                                      struct inode *dir,
    1008             :                                      struct inode *inode,
    1009             :                                      struct ext4_iloc *iloc,
    1010             :                                      void *inline_start, int inline_size)
    1011             : {
    1012           0 :         int             err;
    1013           0 :         struct ext4_dir_entry_2 *de;
    1014             : 
    1015           0 :         err = ext4_find_dest_de(dir, inode, iloc->bh, inline_start,
    1016             :                                 inline_size, fname, &de);
    1017           0 :         if (err)
    1018             :                 return err;
    1019             : 
    1020           0 :         BUFFER_TRACE(iloc->bh, "get_write_access");
    1021           0 :         err = ext4_journal_get_write_access(handle, dir->i_sb, iloc->bh,
    1022             :                                             EXT4_JTR_NONE);
    1023           0 :         if (err)
    1024             :                 return err;
    1025           0 :         ext4_insert_dentry(dir, inode, de, inline_size, fname);
    1026             : 
    1027           0 :         ext4_show_inline_dir(dir, iloc->bh, inline_start, inline_size);
    1028             : 
    1029             :         /*
    1030             :          * XXX shouldn't update any times until successful
    1031             :          * completion of syscall, but too many callers depend
    1032             :          * on this.
    1033             :          *
    1034             :          * XXX similarly, too many callers depend on
    1035             :          * ext4_new_inode() setting the times, but error
    1036             :          * recovery deletes the inode, so the worst that can
    1037             :          * happen is that the times are slightly out of date
    1038             :          * and/or different from the directory change time.
    1039             :          */
    1040           0 :         dir->i_mtime = dir->i_ctime = current_time(dir);
    1041           0 :         ext4_update_dx_flag(dir);
    1042           0 :         inode_inc_iversion(dir);
    1043           0 :         return 1;
    1044             : }
    1045             : 
    1046           0 : static void *ext4_get_inline_xattr_pos(struct inode *inode,
    1047             :                                        struct ext4_iloc *iloc)
    1048             : {
    1049           0 :         struct ext4_xattr_entry *entry;
    1050           0 :         struct ext4_xattr_ibody_header *header;
    1051             : 
    1052           0 :         BUG_ON(!EXT4_I(inode)->i_inline_off);
    1053             : 
    1054           0 :         header = IHDR(inode, ext4_raw_inode(iloc));
    1055           0 :         entry = (struct ext4_xattr_entry *)((void *)ext4_raw_inode(iloc) +
    1056           0 :                                             EXT4_I(inode)->i_inline_off);
    1057             : 
    1058           0 :         return (void *)IFIRST(header) + le16_to_cpu(entry->e_value_offs);
    1059             : }
    1060             : 
    1061             : /* Set the final de to cover the whole block. */
    1062           0 : static void ext4_update_final_de(void *de_buf, int old_size, int new_size)
    1063             : {
    1064           0 :         struct ext4_dir_entry_2 *de, *prev_de;
    1065           0 :         void *limit;
    1066           0 :         int de_len;
    1067             : 
    1068           0 :         de = de_buf;
    1069           0 :         if (old_size) {
    1070           0 :                 limit = de_buf + old_size;
    1071           0 :                 do {
    1072           0 :                         prev_de = de;
    1073           0 :                         de_len = ext4_rec_len_from_disk(de->rec_len, old_size);
    1074           0 :                         de_buf += de_len;
    1075           0 :                         de = de_buf;
    1076           0 :                 } while (de_buf < limit);
    1077             : 
    1078           0 :                 prev_de->rec_len = ext4_rec_len_to_disk(de_len + new_size -
    1079             :                                                         old_size, new_size);
    1080             :         } else {
    1081             :                 /* this is just created, so create an empty entry. */
    1082           0 :                 de->inode = 0;
    1083           0 :                 de->rec_len = ext4_rec_len_to_disk(new_size, new_size);
    1084             :         }
    1085           0 : }
    1086             : 
    1087           0 : static int ext4_update_inline_dir(handle_t *handle, struct inode *dir,
    1088             :                                   struct ext4_iloc *iloc)
    1089             : {
    1090           0 :         int ret;
    1091           0 :         int old_size = EXT4_I(dir)->i_inline_size - EXT4_MIN_INLINE_DATA_SIZE;
    1092           0 :         int new_size = get_max_inline_xattr_value_size(dir, iloc);
    1093             : 
    1094           0 :         if (new_size - old_size <= ext4_dir_rec_len(1, NULL))
    1095             :                 return -ENOSPC;
    1096             : 
    1097           0 :         ret = ext4_update_inline_data(handle, dir,
    1098             :                                       new_size + EXT4_MIN_INLINE_DATA_SIZE);
    1099           0 :         if (ret)
    1100             :                 return ret;
    1101             : 
    1102           0 :         ext4_update_final_de(ext4_get_inline_xattr_pos(dir, iloc), old_size,
    1103           0 :                              EXT4_I(dir)->i_inline_size -
    1104             :                                                 EXT4_MIN_INLINE_DATA_SIZE);
    1105           0 :         dir->i_size = EXT4_I(dir)->i_disksize = EXT4_I(dir)->i_inline_size;
    1106           0 :         return 0;
    1107             : }
    1108             : 
    1109           0 : static void ext4_restore_inline_data(handle_t *handle, struct inode *inode,
    1110             :                                      struct ext4_iloc *iloc,
    1111             :                                      void *buf, int inline_size)
    1112             : {
    1113           0 :         int ret;
    1114             : 
    1115           0 :         ret = ext4_create_inline_data(handle, inode, inline_size);
    1116           0 :         if (ret) {
    1117           0 :                 ext4_msg(inode->i_sb, KERN_EMERG,
    1118             :                         "error restoring inline_data for inode -- potential data loss! (inode %lu, error %d)",
    1119             :                         inode->i_ino, ret);
    1120           0 :                 return;
    1121             :         }
    1122           0 :         ext4_write_inline_data(inode, iloc, buf, 0, inline_size);
    1123           0 :         ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
    1124             : }
    1125             : 
    1126           0 : static int ext4_finish_convert_inline_dir(handle_t *handle,
    1127             :                                           struct inode *inode,
    1128             :                                           struct buffer_head *dir_block,
    1129             :                                           void *buf,
    1130             :                                           int inline_size)
    1131             : {
    1132           0 :         int err, csum_size = 0, header_size = 0;
    1133           0 :         struct ext4_dir_entry_2 *de;
    1134           0 :         void *target = dir_block->b_data;
    1135             : 
    1136             :         /*
    1137             :          * First create "." and ".." and then copy the dir information
    1138             :          * back to the block.
    1139             :          */
    1140           0 :         de = target;
    1141           0 :         de = ext4_init_dot_dotdot(inode, de,
    1142           0 :                 inode->i_sb->s_blocksize, csum_size,
    1143           0 :                 le32_to_cpu(((struct ext4_dir_entry_2 *)buf)->inode), 1);
    1144           0 :         header_size = (void *)de - target;
    1145             : 
    1146           0 :         memcpy((void *)de, buf + EXT4_INLINE_DOTDOT_SIZE,
    1147             :                 inline_size - EXT4_INLINE_DOTDOT_SIZE);
    1148             : 
    1149           0 :         if (ext4_has_metadata_csum(inode->i_sb))
    1150           0 :                 csum_size = sizeof(struct ext4_dir_entry_tail);
    1151             : 
    1152           0 :         inode->i_size = inode->i_sb->s_blocksize;
    1153           0 :         i_size_write(inode, inode->i_sb->s_blocksize);
    1154           0 :         EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
    1155           0 :         ext4_update_final_de(dir_block->b_data,
    1156           0 :                         inline_size - EXT4_INLINE_DOTDOT_SIZE + header_size,
    1157           0 :                         inode->i_sb->s_blocksize - csum_size);
    1158             : 
    1159           0 :         if (csum_size)
    1160           0 :                 ext4_initialize_dirent_tail(dir_block,
    1161           0 :                                             inode->i_sb->s_blocksize);
    1162           0 :         set_buffer_uptodate(dir_block);
    1163           0 :         unlock_buffer(dir_block);
    1164           0 :         err = ext4_handle_dirty_dirblock(handle, inode, dir_block);
    1165           0 :         if (err)
    1166             :                 return err;
    1167           0 :         set_buffer_verified(dir_block);
    1168           0 :         return ext4_mark_inode_dirty(handle, inode);
    1169             : }
    1170             : 
    1171           0 : static int ext4_convert_inline_data_nolock(handle_t *handle,
    1172             :                                            struct inode *inode,
    1173             :                                            struct ext4_iloc *iloc)
    1174             : {
    1175           0 :         int error;
    1176           0 :         void *buf = NULL;
    1177           0 :         struct buffer_head *data_bh = NULL;
    1178           0 :         struct ext4_map_blocks map;
    1179           0 :         int inline_size;
    1180             : 
    1181           0 :         inline_size = ext4_get_inline_size(inode);
    1182           0 :         buf = kmalloc(inline_size, GFP_NOFS);
    1183           0 :         if (!buf) {
    1184           0 :                 error = -ENOMEM;
    1185           0 :                 goto out;
    1186             :         }
    1187             : 
    1188           0 :         error = ext4_read_inline_data(inode, buf, inline_size, iloc);
    1189           0 :         if (error < 0)
    1190           0 :                 goto out;
    1191             : 
    1192             :         /*
    1193             :          * Make sure the inline directory entries pass checks before we try to
    1194             :          * convert them, so that we avoid touching stuff that needs fsck.
    1195             :          */
    1196           0 :         if (S_ISDIR(inode->i_mode)) {
    1197           0 :                 error = ext4_check_all_de(inode, iloc->bh,
    1198             :                                         buf + EXT4_INLINE_DOTDOT_SIZE,
    1199             :                                         inline_size - EXT4_INLINE_DOTDOT_SIZE);
    1200           0 :                 if (error)
    1201           0 :                         goto out;
    1202             :         }
    1203             : 
    1204           0 :         error = ext4_destroy_inline_data_nolock(handle, inode);
    1205           0 :         if (error)
    1206           0 :                 goto out;
    1207             : 
    1208           0 :         map.m_lblk = 0;
    1209           0 :         map.m_len = 1;
    1210           0 :         map.m_flags = 0;
    1211           0 :         error = ext4_map_blocks(handle, inode, &map, EXT4_GET_BLOCKS_CREATE);
    1212           0 :         if (error < 0)
    1213           0 :                 goto out_restore;
    1214           0 :         if (!(map.m_flags & EXT4_MAP_MAPPED)) {
    1215           0 :                 error = -EIO;
    1216           0 :                 goto out_restore;
    1217             :         }
    1218             : 
    1219           0 :         data_bh = sb_getblk(inode->i_sb, map.m_pblk);
    1220           0 :         if (!data_bh) {
    1221           0 :                 error = -ENOMEM;
    1222           0 :                 goto out_restore;
    1223             :         }
    1224             : 
    1225           0 :         lock_buffer(data_bh);
    1226           0 :         error = ext4_journal_get_create_access(handle, inode->i_sb, data_bh,
    1227             :                                                EXT4_JTR_NONE);
    1228           0 :         if (error) {
    1229           0 :                 unlock_buffer(data_bh);
    1230           0 :                 error = -EIO;
    1231           0 :                 goto out_restore;
    1232             :         }
    1233           0 :         memset(data_bh->b_data, 0, inode->i_sb->s_blocksize);
    1234             : 
    1235           0 :         if (!S_ISDIR(inode->i_mode)) {
    1236           0 :                 memcpy(data_bh->b_data, buf, inline_size);
    1237           0 :                 set_buffer_uptodate(data_bh);
    1238           0 :                 unlock_buffer(data_bh);
    1239           0 :                 error = ext4_handle_dirty_metadata(handle,
    1240             :                                                    inode, data_bh);
    1241             :         } else {
    1242           0 :                 error = ext4_finish_convert_inline_dir(handle, inode, data_bh,
    1243             :                                                        buf, inline_size);
    1244             :         }
    1245             : 
    1246           0 : out_restore:
    1247           0 :         if (error)
    1248           0 :                 ext4_restore_inline_data(handle, inode, iloc, buf, inline_size);
    1249             : 
    1250           0 : out:
    1251           0 :         brelse(data_bh);
    1252           0 :         kfree(buf);
    1253           0 :         return error;
    1254             : }
    1255             : 
    1256             : /*
    1257             :  * Try to add the new entry to the inline data.
    1258             :  * If succeeds, return 0. If not, extended the inline dir and copied data to
    1259             :  * the new created block.
    1260             :  */
    1261           0 : int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
    1262             :                               struct inode *dir, struct inode *inode)
    1263             : {
    1264           0 :         int ret, ret2, inline_size, no_expand;
    1265           0 :         void *inline_start;
    1266           0 :         struct ext4_iloc iloc;
    1267             : 
    1268           0 :         ret = ext4_get_inode_loc(dir, &iloc);
    1269           0 :         if (ret)
    1270             :                 return ret;
    1271             : 
    1272           0 :         ext4_write_lock_xattr(dir, &no_expand);
    1273           0 :         if (!ext4_has_inline_data(dir))
    1274           0 :                 goto out;
    1275             : 
    1276           0 :         inline_start = (void *)ext4_raw_inode(&iloc)->i_block +
    1277             :                                                  EXT4_INLINE_DOTDOT_SIZE;
    1278           0 :         inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE;
    1279             : 
    1280           0 :         ret = ext4_add_dirent_to_inline(handle, fname, dir, inode, &iloc,
    1281             :                                         inline_start, inline_size);
    1282           0 :         if (ret != -ENOSPC)
    1283           0 :                 goto out;
    1284             : 
    1285             :         /* check whether it can be inserted to inline xattr space. */
    1286           0 :         inline_size = EXT4_I(dir)->i_inline_size -
    1287             :                         EXT4_MIN_INLINE_DATA_SIZE;
    1288           0 :         if (!inline_size) {
    1289             :                 /* Try to use the xattr space.*/
    1290           0 :                 ret = ext4_update_inline_dir(handle, dir, &iloc);
    1291           0 :                 if (ret && ret != -ENOSPC)
    1292           0 :                         goto out;
    1293             : 
    1294           0 :                 inline_size = EXT4_I(dir)->i_inline_size -
    1295             :                                 EXT4_MIN_INLINE_DATA_SIZE;
    1296             :         }
    1297             : 
    1298           0 :         if (inline_size) {
    1299           0 :                 inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
    1300             : 
    1301           0 :                 ret = ext4_add_dirent_to_inline(handle, fname, dir,
    1302             :                                                 inode, &iloc, inline_start,
    1303             :                                                 inline_size);
    1304             : 
    1305           0 :                 if (ret != -ENOSPC)
    1306           0 :                         goto out;
    1307             :         }
    1308             : 
    1309             :         /*
    1310             :          * The inline space is filled up, so create a new block for it.
    1311             :          * As the extent tree will be created, we have to save the inline
    1312             :          * dir first.
    1313             :          */
    1314           0 :         ret = ext4_convert_inline_data_nolock(handle, dir, &iloc);
    1315             : 
    1316           0 : out:
    1317           0 :         ext4_write_unlock_xattr(dir, &no_expand);
    1318           0 :         ret2 = ext4_mark_inode_dirty(handle, dir);
    1319           0 :         if (unlikely(ret2 && !ret))
    1320           0 :                 ret = ret2;
    1321           0 :         brelse(iloc.bh);
    1322             :         return ret;
    1323             : }
    1324             : 
    1325             : /*
    1326             :  * This function fills a red-black tree with information from an
    1327             :  * inlined dir.  It returns the number directory entries loaded
    1328             :  * into the tree.  If there is an error it is returned in err.
    1329             :  */
    1330           0 : int ext4_inlinedir_to_tree(struct file *dir_file,
    1331             :                            struct inode *dir, ext4_lblk_t block,
    1332             :                            struct dx_hash_info *hinfo,
    1333             :                            __u32 start_hash, __u32 start_minor_hash,
    1334             :                            int *has_inline_data)
    1335             : {
    1336           0 :         int err = 0, count = 0;
    1337           0 :         unsigned int parent_ino;
    1338           0 :         int pos;
    1339           0 :         struct ext4_dir_entry_2 *de;
    1340           0 :         struct inode *inode = file_inode(dir_file);
    1341           0 :         int ret, inline_size = 0;
    1342           0 :         struct ext4_iloc iloc;
    1343           0 :         void *dir_buf = NULL;
    1344           0 :         struct ext4_dir_entry_2 fake;
    1345           0 :         struct fscrypt_str tmp_str;
    1346             : 
    1347           0 :         ret = ext4_get_inode_loc(inode, &iloc);
    1348           0 :         if (ret)
    1349             :                 return ret;
    1350             : 
    1351           0 :         down_read(&EXT4_I(inode)->xattr_sem);
    1352           0 :         if (!ext4_has_inline_data(inode)) {
    1353           0 :                 up_read(&EXT4_I(inode)->xattr_sem);
    1354           0 :                 *has_inline_data = 0;
    1355           0 :                 goto out;
    1356             :         }
    1357             : 
    1358           0 :         inline_size = ext4_get_inline_size(inode);
    1359           0 :         dir_buf = kmalloc(inline_size, GFP_NOFS);
    1360           0 :         if (!dir_buf) {
    1361           0 :                 ret = -ENOMEM;
    1362           0 :                 up_read(&EXT4_I(inode)->xattr_sem);
    1363           0 :                 goto out;
    1364             :         }
    1365             : 
    1366           0 :         ret = ext4_read_inline_data(inode, dir_buf, inline_size, &iloc);
    1367           0 :         up_read(&EXT4_I(inode)->xattr_sem);
    1368           0 :         if (ret < 0)
    1369           0 :                 goto out;
    1370             : 
    1371           0 :         pos = 0;
    1372           0 :         parent_ino = le32_to_cpu(((struct ext4_dir_entry_2 *)dir_buf)->inode);
    1373           0 :         while (pos < inline_size) {
    1374             :                 /*
    1375             :                  * As inlined dir doesn't store any information about '.' and
    1376             :                  * only the inode number of '..' is stored, we have to handle
    1377             :                  * them differently.
    1378             :                  */
    1379           0 :                 if (pos == 0) {
    1380           0 :                         fake.inode = cpu_to_le32(inode->i_ino);
    1381           0 :                         fake.name_len = 1;
    1382           0 :                         strcpy(fake.name, ".");
    1383           0 :                         fake.rec_len = ext4_rec_len_to_disk(
    1384             :                                           ext4_dir_rec_len(fake.name_len, NULL),
    1385             :                                           inline_size);
    1386           0 :                         ext4_set_de_type(inode->i_sb, &fake, S_IFDIR);
    1387             :                         de = &fake;
    1388             :                         pos = EXT4_INLINE_DOTDOT_OFFSET;
    1389           0 :                 } else if (pos == EXT4_INLINE_DOTDOT_OFFSET) {
    1390           0 :                         fake.inode = cpu_to_le32(parent_ino);
    1391           0 :                         fake.name_len = 2;
    1392           0 :                         strcpy(fake.name, "..");
    1393           0 :                         fake.rec_len = ext4_rec_len_to_disk(
    1394             :                                           ext4_dir_rec_len(fake.name_len, NULL),
    1395             :                                           inline_size);
    1396           0 :                         ext4_set_de_type(inode->i_sb, &fake, S_IFDIR);
    1397             :                         de = &fake;
    1398             :                         pos = EXT4_INLINE_DOTDOT_SIZE;
    1399             :                 } else {
    1400           0 :                         de = (struct ext4_dir_entry_2 *)(dir_buf + pos);
    1401           0 :                         pos += ext4_rec_len_from_disk(de->rec_len, inline_size);
    1402           0 :                         if (ext4_check_dir_entry(inode, dir_file, de,
    1403             :                                          iloc.bh, dir_buf,
    1404             :                                          inline_size, pos)) {
    1405           0 :                                 ret = count;
    1406           0 :                                 goto out;
    1407             :                         }
    1408             :                 }
    1409             : 
    1410           0 :                 if (ext4_hash_in_dirent(dir)) {
    1411           0 :                         hinfo->hash = EXT4_DIRENT_HASH(de);
    1412           0 :                         hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de);
    1413             :                 } else {
    1414           0 :                         ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
    1415             :                 }
    1416           0 :                 if ((hinfo->hash < start_hash) ||
    1417           0 :                     ((hinfo->hash == start_hash) &&
    1418           0 :                      (hinfo->minor_hash < start_minor_hash)))
    1419           0 :                         continue;
    1420           0 :                 if (de->inode == 0)
    1421           0 :                         continue;
    1422           0 :                 tmp_str.name = de->name;
    1423           0 :                 tmp_str.len = de->name_len;
    1424           0 :                 err = ext4_htree_store_dirent(dir_file, hinfo->hash,
    1425             :                                               hinfo->minor_hash, de, &tmp_str);
    1426           0 :                 if (err) {
    1427           0 :                         ret = err;
    1428           0 :                         goto out;
    1429             :                 }
    1430           0 :                 count++;
    1431             :         }
    1432             :         ret = count;
    1433           0 : out:
    1434           0 :         kfree(dir_buf);
    1435           0 :         brelse(iloc.bh);
    1436             :         return ret;
    1437             : }
    1438             : 
    1439             : /*
    1440             :  * So this function is called when the volume is mkfsed with
    1441             :  * dir_index disabled. In order to keep f_pos persistent
    1442             :  * after we convert from an inlined dir to a blocked based,
    1443             :  * we just pretend that we are a normal dir and return the
    1444             :  * offset as if '.' and '..' really take place.
    1445             :  *
    1446             :  */
    1447           0 : int ext4_read_inline_dir(struct file *file,
    1448             :                          struct dir_context *ctx,
    1449             :                          int *has_inline_data)
    1450             : {
    1451           0 :         unsigned int offset, parent_ino;
    1452           0 :         int i;
    1453           0 :         struct ext4_dir_entry_2 *de;
    1454           0 :         struct super_block *sb;
    1455           0 :         struct inode *inode = file_inode(file);
    1456           0 :         int ret, inline_size = 0;
    1457           0 :         struct ext4_iloc iloc;
    1458           0 :         void *dir_buf = NULL;
    1459           0 :         int dotdot_offset, dotdot_size, extra_offset, extra_size;
    1460             : 
    1461           0 :         ret = ext4_get_inode_loc(inode, &iloc);
    1462           0 :         if (ret)
    1463             :                 return ret;
    1464             : 
    1465           0 :         down_read(&EXT4_I(inode)->xattr_sem);
    1466           0 :         if (!ext4_has_inline_data(inode)) {
    1467           0 :                 up_read(&EXT4_I(inode)->xattr_sem);
    1468           0 :                 *has_inline_data = 0;
    1469           0 :                 goto out;
    1470             :         }
    1471             : 
    1472           0 :         inline_size = ext4_get_inline_size(inode);
    1473           0 :         dir_buf = kmalloc(inline_size, GFP_NOFS);
    1474           0 :         if (!dir_buf) {
    1475           0 :                 ret = -ENOMEM;
    1476           0 :                 up_read(&EXT4_I(inode)->xattr_sem);
    1477           0 :                 goto out;
    1478             :         }
    1479             : 
    1480           0 :         ret = ext4_read_inline_data(inode, dir_buf, inline_size, &iloc);
    1481           0 :         up_read(&EXT4_I(inode)->xattr_sem);
    1482           0 :         if (ret < 0)
    1483           0 :                 goto out;
    1484             : 
    1485           0 :         ret = 0;
    1486           0 :         sb = inode->i_sb;
    1487           0 :         parent_ino = le32_to_cpu(((struct ext4_dir_entry_2 *)dir_buf)->inode);
    1488           0 :         offset = ctx->pos;
    1489             : 
    1490             :         /*
    1491             :          * dotdot_offset and dotdot_size is the real offset and
    1492             :          * size for ".." and "." if the dir is block based while
    1493             :          * the real size for them are only EXT4_INLINE_DOTDOT_SIZE.
    1494             :          * So we will use extra_offset and extra_size to indicate them
    1495             :          * during the inline dir iteration.
    1496             :          */
    1497           0 :         dotdot_offset = ext4_dir_rec_len(1, NULL);
    1498           0 :         dotdot_size = dotdot_offset + ext4_dir_rec_len(2, NULL);
    1499           0 :         extra_offset = dotdot_size - EXT4_INLINE_DOTDOT_SIZE;
    1500           0 :         extra_size = extra_offset + inline_size;
    1501             : 
    1502             :         /*
    1503             :          * If the version has changed since the last call to
    1504             :          * readdir(2), then we might be pointing to an invalid
    1505             :          * dirent right now.  Scan from the start of the inline
    1506             :          * dir to make sure.
    1507             :          */
    1508           0 :         if (!inode_eq_iversion(inode, file->f_version)) {
    1509           0 :                 for (i = 0; i < extra_size && i < offset;) {
    1510             :                         /*
    1511             :                          * "." is with offset 0 and
    1512             :                          * ".." is dotdot_offset.
    1513             :                          */
    1514           0 :                         if (!i) {
    1515           0 :                                 i = dotdot_offset;
    1516           0 :                                 continue;
    1517           0 :                         } else if (i == dotdot_offset) {
    1518           0 :                                 i = dotdot_size;
    1519           0 :                                 continue;
    1520             :                         }
    1521             :                         /* for other entry, the real offset in
    1522             :                          * the buf has to be tuned accordingly.
    1523             :                          */
    1524           0 :                         de = (struct ext4_dir_entry_2 *)
    1525           0 :                                 (dir_buf + i - extra_offset);
    1526             :                         /* It's too expensive to do a full
    1527             :                          * dirent test each time round this
    1528             :                          * loop, but we do have to test at
    1529             :                          * least that it is non-zero.  A
    1530             :                          * failure will be detected in the
    1531             :                          * dirent test below. */
    1532           0 :                         if (ext4_rec_len_from_disk(de->rec_len, extra_size)
    1533             :                                 < ext4_dir_rec_len(1, NULL))
    1534             :                                 break;
    1535           0 :                         i += ext4_rec_len_from_disk(de->rec_len,
    1536             :                                                     extra_size);
    1537             :                 }
    1538           0 :                 offset = i;
    1539           0 :                 ctx->pos = offset;
    1540           0 :                 file->f_version = inode_query_iversion(inode);
    1541             :         }
    1542             : 
    1543           0 :         while (ctx->pos < extra_size) {
    1544           0 :                 if (ctx->pos == 0) {
    1545           0 :                         if (!dir_emit(ctx, ".", 1, inode->i_ino, DT_DIR))
    1546           0 :                                 goto out;
    1547           0 :                         ctx->pos = dotdot_offset;
    1548           0 :                         continue;
    1549             :                 }
    1550             : 
    1551           0 :                 if (ctx->pos == dotdot_offset) {
    1552           0 :                         if (!dir_emit(ctx, "..", 2, parent_ino, DT_DIR))
    1553           0 :                                 goto out;
    1554           0 :                         ctx->pos = dotdot_size;
    1555           0 :                         continue;
    1556             :                 }
    1557             : 
    1558           0 :                 de = (struct ext4_dir_entry_2 *)
    1559           0 :                         (dir_buf + ctx->pos - extra_offset);
    1560           0 :                 if (ext4_check_dir_entry(inode, file, de, iloc.bh, dir_buf,
    1561             :                                          extra_size, ctx->pos))
    1562           0 :                         goto out;
    1563           0 :                 if (le32_to_cpu(de->inode)) {
    1564           0 :                         if (!dir_emit(ctx, de->name, de->name_len,
    1565             :                                       le32_to_cpu(de->inode),
    1566           0 :                                       get_dtype(sb, de->file_type)))
    1567           0 :                                 goto out;
    1568             :                 }
    1569           0 :                 ctx->pos += ext4_rec_len_from_disk(de->rec_len, extra_size);
    1570             :         }
    1571           0 : out:
    1572           0 :         kfree(dir_buf);
    1573           0 :         brelse(iloc.bh);
    1574             :         return ret;
    1575             : }
    1576             : 
    1577           0 : void *ext4_read_inline_link(struct inode *inode)
    1578             : {
    1579           0 :         struct ext4_iloc iloc;
    1580           0 :         int ret, inline_size;
    1581           0 :         void *link;
    1582             : 
    1583           0 :         ret = ext4_get_inode_loc(inode, &iloc);
    1584           0 :         if (ret)
    1585           0 :                 return ERR_PTR(ret);
    1586             : 
    1587           0 :         ret = -ENOMEM;
    1588           0 :         inline_size = ext4_get_inline_size(inode);
    1589           0 :         link = kmalloc(inline_size + 1, GFP_NOFS);
    1590           0 :         if (!link)
    1591           0 :                 goto out;
    1592             : 
    1593           0 :         ret = ext4_read_inline_data(inode, link, inline_size, &iloc);
    1594           0 :         if (ret < 0) {
    1595           0 :                 kfree(link);
    1596           0 :                 goto out;
    1597             :         }
    1598           0 :         nd_terminate_link(link, inode->i_size, ret);
    1599           0 : out:
    1600           0 :         if (ret < 0)
    1601           0 :                 link = ERR_PTR(ret);
    1602           0 :         brelse(iloc.bh);
    1603             :         return link;
    1604             : }
    1605             : 
    1606           0 : struct buffer_head *ext4_get_first_inline_block(struct inode *inode,
    1607             :                                         struct ext4_dir_entry_2 **parent_de,
    1608             :                                         int *retval)
    1609             : {
    1610           0 :         struct ext4_iloc iloc;
    1611             : 
    1612           0 :         *retval = ext4_get_inode_loc(inode, &iloc);
    1613           0 :         if (*retval)
    1614             :                 return NULL;
    1615             : 
    1616           0 :         *parent_de = (struct ext4_dir_entry_2 *)ext4_raw_inode(&iloc)->i_block;
    1617             : 
    1618           0 :         return iloc.bh;
    1619             : }
    1620             : 
    1621             : /*
    1622             :  * Try to create the inline data for the new dir.
    1623             :  * If it succeeds, return 0, otherwise return the error.
    1624             :  * In case of ENOSPC, the caller should create the normal disk layout dir.
    1625             :  */
    1626           0 : int ext4_try_create_inline_dir(handle_t *handle, struct inode *parent,
    1627             :                                struct inode *inode)
    1628             : {
    1629           0 :         int ret, inline_size = EXT4_MIN_INLINE_DATA_SIZE;
    1630           0 :         struct ext4_iloc iloc;
    1631           0 :         struct ext4_dir_entry_2 *de;
    1632             : 
    1633           0 :         ret = ext4_get_inode_loc(inode, &iloc);
    1634           0 :         if (ret)
    1635             :                 return ret;
    1636             : 
    1637           0 :         ret = ext4_prepare_inline_data(handle, inode, inline_size);
    1638           0 :         if (ret)
    1639           0 :                 goto out;
    1640             : 
    1641             :         /*
    1642             :          * For inline dir, we only save the inode information for the ".."
    1643             :          * and create a fake dentry to cover the left space.
    1644             :          */
    1645           0 :         de = (struct ext4_dir_entry_2 *)ext4_raw_inode(&iloc)->i_block;
    1646           0 :         de->inode = cpu_to_le32(parent->i_ino);
    1647           0 :         de = (struct ext4_dir_entry_2 *)((void *)de + EXT4_INLINE_DOTDOT_SIZE);
    1648           0 :         de->inode = 0;
    1649           0 :         de->rec_len = ext4_rec_len_to_disk(
    1650             :                                 inline_size - EXT4_INLINE_DOTDOT_SIZE,
    1651             :                                 inline_size);
    1652           0 :         set_nlink(inode, 2);
    1653           0 :         inode->i_size = EXT4_I(inode)->i_disksize = inline_size;
    1654           0 : out:
    1655           0 :         brelse(iloc.bh);
    1656             :         return ret;
    1657             : }
    1658             : 
    1659           0 : struct buffer_head *ext4_find_inline_entry(struct inode *dir,
    1660             :                                         struct ext4_filename *fname,
    1661             :                                         struct ext4_dir_entry_2 **res_dir,
    1662             :                                         int *has_inline_data)
    1663             : {
    1664           0 :         int ret;
    1665           0 :         struct ext4_iloc iloc;
    1666           0 :         void *inline_start;
    1667           0 :         int inline_size;
    1668             : 
    1669           0 :         if (ext4_get_inode_loc(dir, &iloc))
    1670             :                 return NULL;
    1671             : 
    1672           0 :         down_read(&EXT4_I(dir)->xattr_sem);
    1673           0 :         if (!ext4_has_inline_data(dir)) {
    1674           0 :                 *has_inline_data = 0;
    1675           0 :                 goto out;
    1676             :         }
    1677             : 
    1678           0 :         inline_start = (void *)ext4_raw_inode(&iloc)->i_block +
    1679             :                                                 EXT4_INLINE_DOTDOT_SIZE;
    1680           0 :         inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE;
    1681           0 :         ret = ext4_search_dir(iloc.bh, inline_start, inline_size,
    1682             :                               dir, fname, 0, res_dir);
    1683           0 :         if (ret == 1)
    1684           0 :                 goto out_find;
    1685           0 :         if (ret < 0)
    1686           0 :                 goto out;
    1687             : 
    1688           0 :         if (ext4_get_inline_size(dir) == EXT4_MIN_INLINE_DATA_SIZE)
    1689           0 :                 goto out;
    1690             : 
    1691           0 :         inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
    1692           0 :         inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE;
    1693             : 
    1694           0 :         ret = ext4_search_dir(iloc.bh, inline_start, inline_size,
    1695             :                               dir, fname, 0, res_dir);
    1696           0 :         if (ret == 1)
    1697           0 :                 goto out_find;
    1698             : 
    1699           0 : out:
    1700           0 :         brelse(iloc.bh);
    1701           0 :         iloc.bh = NULL;
    1702           0 : out_find:
    1703           0 :         up_read(&EXT4_I(dir)->xattr_sem);
    1704           0 :         return iloc.bh;
    1705             : }
    1706             : 
    1707           0 : int ext4_delete_inline_entry(handle_t *handle,
    1708             :                              struct inode *dir,
    1709             :                              struct ext4_dir_entry_2 *de_del,
    1710             :                              struct buffer_head *bh,
    1711             :                              int *has_inline_data)
    1712             : {
    1713           0 :         int err, inline_size, no_expand;
    1714           0 :         struct ext4_iloc iloc;
    1715           0 :         void *inline_start;
    1716             : 
    1717           0 :         err = ext4_get_inode_loc(dir, &iloc);
    1718           0 :         if (err)
    1719             :                 return err;
    1720             : 
    1721           0 :         ext4_write_lock_xattr(dir, &no_expand);
    1722           0 :         if (!ext4_has_inline_data(dir)) {
    1723           0 :                 *has_inline_data = 0;
    1724           0 :                 goto out;
    1725             :         }
    1726             : 
    1727           0 :         if ((void *)de_del - ((void *)ext4_raw_inode(&iloc)->i_block) <
    1728             :                 EXT4_MIN_INLINE_DATA_SIZE) {
    1729           0 :                 inline_start = (void *)ext4_raw_inode(&iloc)->i_block +
    1730             :                                         EXT4_INLINE_DOTDOT_SIZE;
    1731           0 :                 inline_size = EXT4_MIN_INLINE_DATA_SIZE -
    1732             :                                 EXT4_INLINE_DOTDOT_SIZE;
    1733             :         } else {
    1734           0 :                 inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
    1735           0 :                 inline_size = ext4_get_inline_size(dir) -
    1736             :                                 EXT4_MIN_INLINE_DATA_SIZE;
    1737             :         }
    1738             : 
    1739           0 :         BUFFER_TRACE(bh, "get_write_access");
    1740           0 :         err = ext4_journal_get_write_access(handle, dir->i_sb, bh,
    1741             :                                             EXT4_JTR_NONE);
    1742           0 :         if (err)
    1743           0 :                 goto out;
    1744             : 
    1745           0 :         err = ext4_generic_delete_entry(dir, de_del, bh,
    1746             :                                         inline_start, inline_size, 0);
    1747           0 :         if (err)
    1748           0 :                 goto out;
    1749             : 
    1750           0 :         ext4_show_inline_dir(dir, iloc.bh, inline_start, inline_size);
    1751           0 : out:
    1752           0 :         ext4_write_unlock_xattr(dir, &no_expand);
    1753           0 :         if (likely(err == 0))
    1754           0 :                 err = ext4_mark_inode_dirty(handle, dir);
    1755           0 :         brelse(iloc.bh);
    1756           0 :         if (err != -ENOENT)
    1757           0 :                 ext4_std_error(dir->i_sb, err);
    1758             :         return err;
    1759             : }
    1760             : 
    1761             : /*
    1762             :  * Get the inline dentry at offset.
    1763             :  */
    1764             : static inline struct ext4_dir_entry_2 *
    1765           0 : ext4_get_inline_entry(struct inode *inode,
    1766             :                       struct ext4_iloc *iloc,
    1767             :                       unsigned int offset,
    1768             :                       void **inline_start,
    1769             :                       int *inline_size)
    1770             : {
    1771           0 :         void *inline_pos;
    1772             : 
    1773           0 :         BUG_ON(offset > ext4_get_inline_size(inode));
    1774             : 
    1775           0 :         if (offset < EXT4_MIN_INLINE_DATA_SIZE) {
    1776           0 :                 inline_pos = (void *)ext4_raw_inode(iloc)->i_block;
    1777           0 :                 *inline_size = EXT4_MIN_INLINE_DATA_SIZE;
    1778             :         } else {
    1779           0 :                 inline_pos = ext4_get_inline_xattr_pos(inode, iloc);
    1780           0 :                 offset -= EXT4_MIN_INLINE_DATA_SIZE;
    1781           0 :                 *inline_size = ext4_get_inline_size(inode) -
    1782             :                                 EXT4_MIN_INLINE_DATA_SIZE;
    1783             :         }
    1784             : 
    1785           0 :         if (inline_start)
    1786           0 :                 *inline_start = inline_pos;
    1787           0 :         return (struct ext4_dir_entry_2 *)(inline_pos + offset);
    1788             : }
    1789             : 
    1790           0 : bool empty_inline_dir(struct inode *dir, int *has_inline_data)
    1791             : {
    1792           0 :         int err, inline_size;
    1793           0 :         struct ext4_iloc iloc;
    1794           0 :         size_t inline_len;
    1795           0 :         void *inline_pos;
    1796           0 :         unsigned int offset;
    1797           0 :         struct ext4_dir_entry_2 *de;
    1798           0 :         bool ret = false;
    1799             : 
    1800           0 :         err = ext4_get_inode_loc(dir, &iloc);
    1801           0 :         if (err) {
    1802           0 :                 EXT4_ERROR_INODE_ERR(dir, -err,
    1803             :                                      "error %d getting inode %lu block",
    1804             :                                      err, dir->i_ino);
    1805           0 :                 return false;
    1806             :         }
    1807             : 
    1808           0 :         down_read(&EXT4_I(dir)->xattr_sem);
    1809           0 :         if (!ext4_has_inline_data(dir)) {
    1810           0 :                 *has_inline_data = 0;
    1811           0 :                 ret = true;
    1812           0 :                 goto out;
    1813             :         }
    1814             : 
    1815           0 :         de = (struct ext4_dir_entry_2 *)ext4_raw_inode(&iloc)->i_block;
    1816           0 :         if (!le32_to_cpu(de->inode)) {
    1817           0 :                 ext4_warning(dir->i_sb,
    1818             :                              "bad inline directory (dir #%lu) - no `..'",
    1819             :                              dir->i_ino);
    1820           0 :                 goto out;
    1821             :         }
    1822             : 
    1823           0 :         inline_len = ext4_get_inline_size(dir);
    1824           0 :         offset = EXT4_INLINE_DOTDOT_SIZE;
    1825           0 :         while (offset < inline_len) {
    1826           0 :                 de = ext4_get_inline_entry(dir, &iloc, offset,
    1827             :                                            &inline_pos, &inline_size);
    1828           0 :                 if (ext4_check_dir_entry(dir, NULL, de,
    1829             :                                          iloc.bh, inline_pos,
    1830             :                                          inline_size, offset)) {
    1831           0 :                         ext4_warning(dir->i_sb,
    1832             :                                      "bad inline directory (dir #%lu) - "
    1833             :                                      "inode %u, rec_len %u, name_len %d"
    1834             :                                      "inline size %d",
    1835             :                                      dir->i_ino, le32_to_cpu(de->inode),
    1836             :                                      le16_to_cpu(de->rec_len), de->name_len,
    1837             :                                      inline_size);
    1838           0 :                         goto out;
    1839             :                 }
    1840           0 :                 if (le32_to_cpu(de->inode)) {
    1841           0 :                         goto out;
    1842             :                 }
    1843           0 :                 offset += ext4_rec_len_from_disk(de->rec_len, inline_size);
    1844             :         }
    1845             : 
    1846             :         ret = true;
    1847           0 : out:
    1848           0 :         up_read(&EXT4_I(dir)->xattr_sem);
    1849           0 :         brelse(iloc.bh);
    1850             :         return ret;
    1851             : }
    1852             : 
    1853           0 : int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
    1854             : {
    1855           0 :         int ret, no_expand;
    1856             : 
    1857           0 :         ext4_write_lock_xattr(inode, &no_expand);
    1858           0 :         ret = ext4_destroy_inline_data_nolock(handle, inode);
    1859           0 :         ext4_write_unlock_xattr(inode, &no_expand);
    1860             : 
    1861           0 :         return ret;
    1862             : }
    1863             : 
    1864           0 : int ext4_inline_data_iomap(struct inode *inode, struct iomap *iomap)
    1865             : {
    1866           0 :         __u64 addr;
    1867           0 :         int error = -EAGAIN;
    1868           0 :         struct ext4_iloc iloc;
    1869             : 
    1870           0 :         down_read(&EXT4_I(inode)->xattr_sem);
    1871           0 :         if (!ext4_has_inline_data(inode))
    1872           0 :                 goto out;
    1873             : 
    1874           0 :         error = ext4_get_inode_loc(inode, &iloc);
    1875           0 :         if (error)
    1876           0 :                 goto out;
    1877             : 
    1878           0 :         addr = (__u64)iloc.bh->b_blocknr << inode->i_sb->s_blocksize_bits;
    1879           0 :         addr += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data;
    1880           0 :         addr += offsetof(struct ext4_inode, i_block);
    1881             : 
    1882           0 :         brelse(iloc.bh);
    1883             : 
    1884           0 :         iomap->addr = addr;
    1885           0 :         iomap->offset = 0;
    1886           0 :         iomap->length = min_t(loff_t, ext4_get_inline_size(inode),
    1887             :                               i_size_read(inode));
    1888           0 :         iomap->type = IOMAP_INLINE;
    1889           0 :         iomap->flags = 0;
    1890             : 
    1891           0 : out:
    1892           0 :         up_read(&EXT4_I(inode)->xattr_sem);
    1893           0 :         return error;
    1894             : }
    1895             : 
    1896           0 : int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
    1897             : {
    1898           0 :         handle_t *handle;
    1899           0 :         int inline_size, value_len, needed_blocks, no_expand, err = 0;
    1900           0 :         size_t i_size;
    1901           0 :         void *value = NULL;
    1902           0 :         struct ext4_xattr_ibody_find is = {
    1903             :                 .s = { .not_found = -ENODATA, },
    1904             :         };
    1905           0 :         struct ext4_xattr_info i = {
    1906             :                 .name_index = EXT4_XATTR_INDEX_SYSTEM,
    1907             :                 .name = EXT4_XATTR_SYSTEM_DATA,
    1908             :         };
    1909             : 
    1910             : 
    1911           0 :         needed_blocks = ext4_writepage_trans_blocks(inode);
    1912           0 :         handle = ext4_journal_start(inode, EXT4_HT_INODE, needed_blocks);
    1913           0 :         if (IS_ERR(handle))
    1914           0 :                 return PTR_ERR(handle);
    1915             : 
    1916           0 :         ext4_write_lock_xattr(inode, &no_expand);
    1917           0 :         if (!ext4_has_inline_data(inode)) {
    1918           0 :                 ext4_write_unlock_xattr(inode, &no_expand);
    1919           0 :                 *has_inline = 0;
    1920           0 :                 ext4_journal_stop(handle);
    1921           0 :                 return 0;
    1922             :         }
    1923             : 
    1924           0 :         if ((err = ext4_orphan_add(handle, inode)) != 0)
    1925           0 :                 goto out;
    1926             : 
    1927           0 :         if ((err = ext4_get_inode_loc(inode, &is.iloc)) != 0)
    1928           0 :                 goto out;
    1929             : 
    1930           0 :         down_write(&EXT4_I(inode)->i_data_sem);
    1931           0 :         i_size = inode->i_size;
    1932           0 :         inline_size = ext4_get_inline_size(inode);
    1933           0 :         EXT4_I(inode)->i_disksize = i_size;
    1934             : 
    1935           0 :         if (i_size < inline_size) {
    1936             :                 /*
    1937             :                  * if there's inline data to truncate and this file was
    1938             :                  * converted to extents after that inline data was written,
    1939             :                  * the extent status cache must be cleared to avoid leaving
    1940             :                  * behind stale delayed allocated extent entries
    1941             :                  */
    1942           0 :                 if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
    1943           0 :                         ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
    1944             : 
    1945             :                 /* Clear the content in the xattr space. */
    1946           0 :                 if (inline_size > EXT4_MIN_INLINE_DATA_SIZE) {
    1947           0 :                         if ((err = ext4_xattr_ibody_find(inode, &i, &is)) != 0)
    1948           0 :                                 goto out_error;
    1949             : 
    1950           0 :                         BUG_ON(is.s.not_found);
    1951             : 
    1952           0 :                         value_len = le32_to_cpu(is.s.here->e_value_size);
    1953           0 :                         value = kmalloc(value_len, GFP_NOFS);
    1954           0 :                         if (!value) {
    1955           0 :                                 err = -ENOMEM;
    1956           0 :                                 goto out_error;
    1957             :                         }
    1958             : 
    1959           0 :                         err = ext4_xattr_ibody_get(inode, i.name_index,
    1960             :                                                    i.name, value, value_len);
    1961           0 :                         if (err <= 0)
    1962           0 :                                 goto out_error;
    1963             : 
    1964           0 :                         i.value = value;
    1965           0 :                         i.value_len = i_size > EXT4_MIN_INLINE_DATA_SIZE ?
    1966           0 :                                         i_size - EXT4_MIN_INLINE_DATA_SIZE : 0;
    1967           0 :                         err = ext4_xattr_ibody_set(handle, inode, &i, &is);
    1968           0 :                         if (err)
    1969           0 :                                 goto out_error;
    1970             :                 }
    1971             : 
    1972             :                 /* Clear the content within i_blocks. */
    1973           0 :                 if (i_size < EXT4_MIN_INLINE_DATA_SIZE) {
    1974           0 :                         void *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
    1975           0 :                         memset(p + i_size, 0,
    1976             :                                EXT4_MIN_INLINE_DATA_SIZE - i_size);
    1977             :                 }
    1978             : 
    1979           0 :                 EXT4_I(inode)->i_inline_size = i_size <
    1980             :                                         EXT4_MIN_INLINE_DATA_SIZE ?
    1981           0 :                                         EXT4_MIN_INLINE_DATA_SIZE : i_size;
    1982             :         }
    1983             : 
    1984           0 : out_error:
    1985           0 :         up_write(&EXT4_I(inode)->i_data_sem);
    1986           0 : out:
    1987           0 :         brelse(is.iloc.bh);
    1988           0 :         ext4_write_unlock_xattr(inode, &no_expand);
    1989           0 :         kfree(value);
    1990           0 :         if (inode->i_nlink)
    1991           0 :                 ext4_orphan_del(handle, inode);
    1992             : 
    1993           0 :         if (err == 0) {
    1994           0 :                 inode->i_mtime = inode->i_ctime = current_time(inode);
    1995           0 :                 err = ext4_mark_inode_dirty(handle, inode);
    1996           0 :                 if (IS_SYNC(inode))
    1997           0 :                         ext4_handle_sync(handle);
    1998             :         }
    1999           0 :         ext4_journal_stop(handle);
    2000           0 :         return err;
    2001             : }
    2002             : 
    2003     9495722 : int ext4_convert_inline_data(struct inode *inode)
    2004             : {
    2005     9495722 :         int error, needed_blocks, no_expand;
    2006     9495722 :         handle_t *handle;
    2007     9495722 :         struct ext4_iloc iloc;
    2008             : 
    2009     9495722 :         if (!ext4_has_inline_data(inode)) {
    2010     9495722 :                 ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
    2011     9495722 :                 return 0;
    2012           0 :         } else if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
    2013             :                 /*
    2014             :                  * Inode has inline data but EXT4_STATE_MAY_INLINE_DATA is
    2015             :                  * cleared. This means we are in the middle of moving of
    2016             :                  * inline data to delay allocated block. Just force writeout
    2017             :                  * here to finish conversion.
    2018             :                  */
    2019           0 :                 error = filemap_flush(inode->i_mapping);
    2020           0 :                 if (error)
    2021             :                         return error;
    2022           0 :                 if (!ext4_has_inline_data(inode))
    2023             :                         return 0;
    2024             :         }
    2025             : 
    2026           0 :         needed_blocks = ext4_writepage_trans_blocks(inode);
    2027             : 
    2028           0 :         iloc.bh = NULL;
    2029           0 :         error = ext4_get_inode_loc(inode, &iloc);
    2030           0 :         if (error)
    2031             :                 return error;
    2032             : 
    2033           0 :         handle = ext4_journal_start(inode, EXT4_HT_WRITE_PAGE, needed_blocks);
    2034           0 :         if (IS_ERR(handle)) {
    2035           0 :                 error = PTR_ERR(handle);
    2036           0 :                 goto out_free;
    2037             :         }
    2038             : 
    2039           0 :         ext4_write_lock_xattr(inode, &no_expand);
    2040           0 :         if (ext4_has_inline_data(inode))
    2041           0 :                 error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
    2042           0 :         ext4_write_unlock_xattr(inode, &no_expand);
    2043           0 :         ext4_journal_stop(handle);
    2044           0 : out_free:
    2045           0 :         brelse(iloc.bh);
    2046             :         return error;
    2047             : }

Generated by: LCOV version 1.14