All of lore.kernel.org
 help / color / mirror / Atom feed
* [bug report] ext4: let ext4_truncate handle inline data correctly
@ 2020-11-02  7:22 Dan Carpenter
  0 siblings, 0 replies; only message in thread
From: Dan Carpenter @ 2020-11-02  7:22 UTC (permalink / raw)
  To: boyu.mt; +Cc: linux-ext4

[ Ancient warning.  Still looks valid though.  - dan ]

Hello Tao Ma,

The patch aef1c8513c1f: "ext4: let ext4_truncate handle inline data
correctly" from Dec 10, 2012, leads to the following static checker
warning:

fs/ext4/inline.c:1956 ext4_inline_data_truncate()
warn: inconsistent returns 'EXT4_I(inode)->xattr_sem'.
  Locked on  : 1885
  Unlocked on: 1956

fs/ext4/inline.c
  1861  int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
  1862  {
  1863          handle_t *handle;
  1864          int inline_size, value_len, needed_blocks, no_expand, err = 0;
  1865          size_t i_size;
  1866          void *value = NULL;
  1867          struct ext4_xattr_ibody_find is = {
  1868                  .s = { .not_found = -ENODATA, },
  1869          };
  1870          struct ext4_xattr_info i = {
  1871                  .name_index = EXT4_XATTR_INDEX_SYSTEM,
  1872                  .name = EXT4_XATTR_SYSTEM_DATA,
  1873          };
  1874  
  1875  
  1876          needed_blocks = ext4_writepage_trans_blocks(inode);
  1877          handle = ext4_journal_start(inode, EXT4_HT_INODE, needed_blocks);
  1878          if (IS_ERR(handle))
  1879                  return PTR_ERR(handle);
  1880  
  1881          ext4_write_lock_xattr(inode, &no_expand);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Take the lock

  1882          if (!ext4_has_inline_data(inode)) {
  1883                  *has_inline = 0;
  1884                  ext4_journal_stop(handle);
  1885                  return 0;

Not unlocked.

  1886          }
  1887  
  1888          if ((err = ext4_orphan_add(handle, inode)) != 0)
  1889                  goto out;
  1890  
  1891          if ((err = ext4_get_inode_loc(inode, &is.iloc)) != 0)
  1892                  goto out;
  1893  
  1894          down_write(&EXT4_I(inode)->i_data_sem);
  1895          i_size = inode->i_size;
  1896          inline_size = ext4_get_inline_size(inode);
  1897          EXT4_I(inode)->i_disksize = i_size;
  1898  
  1899          if (i_size < inline_size) {
  1900                  /* Clear the content in the xattr space. */
  1901                  if (inline_size > EXT4_MIN_INLINE_DATA_SIZE) {
  1902                          if ((err = ext4_xattr_ibody_find(inode, &i, &is)) != 0)
  1903                                  goto out_error;
  1904  
  1905                          BUG_ON(is.s.not_found);
  1906  
  1907                          value_len = le32_to_cpu(is.s.here->e_value_size);
  1908                          value = kmalloc(value_len, GFP_NOFS);
  1909                          if (!value) {
  1910                                  err = -ENOMEM;
  1911                                  goto out_error;
  1912                          }
  1913  
  1914                          err = ext4_xattr_ibody_get(inode, i.name_index,
  1915                                                     i.name, value, value_len);
  1916                          if (err <= 0)
  1917                                  goto out_error;
  1918  
  1919                          i.value = value;
  1920                          i.value_len = i_size > EXT4_MIN_INLINE_DATA_SIZE ?
  1921                                          i_size - EXT4_MIN_INLINE_DATA_SIZE : 0;
  1922                          err = ext4_xattr_ibody_inline_set(handle, inode,
  1923                                                            &i, &is);
  1924                          if (err)
  1925                                  goto out_error;
  1926                  }
  1927  
  1928                  /* Clear the content within i_blocks. */
  1929                  if (i_size < EXT4_MIN_INLINE_DATA_SIZE) {
  1930                          void *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
  1931                          memset(p + i_size, 0,
  1932                                 EXT4_MIN_INLINE_DATA_SIZE - i_size);
  1933                  }
  1934  
  1935                  EXT4_I(inode)->i_inline_size = i_size <
  1936                                          EXT4_MIN_INLINE_DATA_SIZE ?
  1937                                          EXT4_MIN_INLINE_DATA_SIZE : i_size;
  1938          }
  1939  
  1940  out_error:
  1941          up_write(&EXT4_I(inode)->i_data_sem);
  1942  out:
  1943          brelse(is.iloc.bh);
  1944          ext4_write_unlock_xattr(inode, &no_expand);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Unlocked here.

  1945          kfree(value);
  1946          if (inode->i_nlink)
  1947                  ext4_orphan_del(handle, inode);
  1948  
  1949          if (err == 0) {
  1950                  inode->i_mtime = inode->i_ctime = current_time(inode);
  1951                  err = ext4_mark_inode_dirty(handle, inode);
  1952                  if (IS_SYNC(inode))
  1953                          ext4_handle_sync(handle);
  1954          }
  1955          ext4_journal_stop(handle);
  1956          return err;
  1957  }

regards,
dan carpenter

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-11-02  7:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-02  7:22 [bug report] ext4: let ext4_truncate handle inline data correctly Dan Carpenter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.