[ 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