* [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.