Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull reiserfs and UDF fixes from Jan Kara:
"The contains fix of an UDF oops when mounting corrupted media and a
fix of a race in reiserfs leading to oops"

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
reiserfs: fix race with flush_used_journal_lists and flush_journal_list
reiserfs: remove useless flush_old_journal_lists
udf: Fortify LVID loading

+52 -97
+4 -63
fs/reiserfs/journal.c
··· 1163 1163 return NULL; 1164 1164 } 1165 1165 1166 - static int newer_jl_done(struct reiserfs_journal_cnode *cn) 1167 - { 1168 - struct super_block *sb = cn->sb; 1169 - b_blocknr_t blocknr = cn->blocknr; 1170 - 1171 - cn = cn->hprev; 1172 - while (cn) { 1173 - if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist && 1174 - atomic_read(&cn->jlist->j_commit_left) != 0) 1175 - return 0; 1176 - cn = cn->hprev; 1177 - } 1178 - return 1; 1179 - } 1180 - 1181 1166 static void remove_journal_hash(struct super_block *, 1182 1167 struct reiserfs_journal_cnode **, 1183 1168 struct reiserfs_journal_list *, unsigned long, ··· 1338 1353 reiserfs_warning(s, "clm-2048", "called with wcount %d", 1339 1354 atomic_read(&journal->j_wcount)); 1340 1355 } 1341 - BUG_ON(jl->j_trans_id == 0); 1342 1356 1343 1357 /* if flushall == 0, the lock is already held */ 1344 1358 if (flushall) { ··· 1577 1593 return err; 1578 1594 } 1579 1595 1580 - static int test_transaction(struct super_block *s, 1581 - struct reiserfs_journal_list *jl) 1582 - { 1583 - struct reiserfs_journal_cnode *cn; 1584 - 1585 - if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0) 1586 - return 1; 1587 - 1588 - cn = jl->j_realblock; 1589 - while (cn) { 1590 - /* if the blocknr == 0, this has been cleared from the hash, 1591 - ** skip it 1592 - */ 1593 - if (cn->blocknr == 0) { 1594 - goto next; 1595 - } 1596 - if (cn->bh && !newer_jl_done(cn)) 1597 - return 0; 1598 - next: 1599 - cn = cn->next; 1600 - cond_resched(); 1601 - } 1602 - return 0; 1603 - } 1604 - 1605 1596 static int write_one_transaction(struct super_block *s, 1606 1597 struct reiserfs_journal_list *jl, 1607 1598 struct buffer_chunk *chunk) ··· 1764 1805 break; 1765 1806 tjl = JOURNAL_LIST_ENTRY(tjl->j_list.next); 1766 1807 } 1808 + get_journal_list(jl); 1809 + get_journal_list(flush_jl); 1767 1810 /* try to find a group of blocks we can flush across all the 1768 1811 ** transactions, but only bother if we've actually spanned 1769 1812 ** across multiple lists ··· 1774 1813 ret = kupdate_transactions(s, jl, &tjl, &trans_id, len, i); 1775 1814 } 1776 1815 flush_journal_list(s, flush_jl, 1); 1816 + put_journal_list(s, flush_jl); 1817 + put_journal_list(s, jl); 1777 1818 return 0; 1778 1819 } 1779 1820 ··· 3831 3868 return 1; 3832 3869 } 3833 3870 3834 - static void flush_old_journal_lists(struct super_block *s) 3835 - { 3836 - struct reiserfs_journal *journal = SB_JOURNAL(s); 3837 - struct reiserfs_journal_list *jl; 3838 - struct list_head *entry; 3839 - time_t now = get_seconds(); 3840 - 3841 - while (!list_empty(&journal->j_journal_list)) { 3842 - entry = journal->j_journal_list.next; 3843 - jl = JOURNAL_LIST_ENTRY(entry); 3844 - /* this check should always be run, to send old lists to disk */ 3845 - if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) && 3846 - atomic_read(&jl->j_commit_left) == 0 && 3847 - test_transaction(s, jl)) { 3848 - flush_used_journal_lists(s, jl); 3849 - } else { 3850 - break; 3851 - } 3852 - } 3853 - } 3854 - 3855 3871 /* 3856 3872 ** long and ugly. If flush, will not return until all commit 3857 3873 ** blocks and all real buffers in the trans are on disk. ··· 4174 4232 } 4175 4233 } 4176 4234 } 4177 - flush_old_journal_lists(sb); 4178 4235 4179 4236 journal->j_current_jl->j_list_bitmap = 4180 4237 get_list_bitmap(sb, journal->j_current_jl);
+7 -9
fs/udf/ialloc.c
··· 30 30 { 31 31 struct super_block *sb = inode->i_sb; 32 32 struct udf_sb_info *sbi = UDF_SB(sb); 33 + struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); 33 34 34 - mutex_lock(&sbi->s_alloc_mutex); 35 - if (sbi->s_lvid_bh) { 36 - struct logicalVolIntegrityDescImpUse *lvidiu = 37 - udf_sb_lvidiu(sbi); 35 + if (lvidiu) { 36 + mutex_lock(&sbi->s_alloc_mutex); 38 37 if (S_ISDIR(inode->i_mode)) 39 38 le32_add_cpu(&lvidiu->numDirs, -1); 40 39 else 41 40 le32_add_cpu(&lvidiu->numFiles, -1); 42 41 udf_updated_lvid(sb); 42 + mutex_unlock(&sbi->s_alloc_mutex); 43 43 } 44 - mutex_unlock(&sbi->s_alloc_mutex); 45 44 46 45 udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1); 47 46 } ··· 54 55 uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; 55 56 struct udf_inode_info *iinfo; 56 57 struct udf_inode_info *dinfo = UDF_I(dir); 58 + struct logicalVolIntegrityDescImpUse *lvidiu; 57 59 58 60 inode = new_inode(sb); 59 61 ··· 92 92 return NULL; 93 93 } 94 94 95 - if (sbi->s_lvid_bh) { 96 - struct logicalVolIntegrityDescImpUse *lvidiu; 97 - 95 + lvidiu = udf_sb_lvidiu(sb); 96 + if (lvidiu) { 98 97 iinfo->i_unique = lvid_get_unique_id(sb); 99 98 mutex_lock(&sbi->s_alloc_mutex); 100 - lvidiu = udf_sb_lvidiu(sbi); 101 99 if (S_ISDIR(mode)) 102 100 le32_add_cpu(&lvidiu->numDirs, 1); 103 101 else
+40 -24
fs/udf/super.c
··· 94 94 static int udf_statfs(struct dentry *, struct kstatfs *); 95 95 static int udf_show_options(struct seq_file *, struct dentry *); 96 96 97 - struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) 97 + struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb) 98 98 { 99 - struct logicalVolIntegrityDesc *lvid = 100 - (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; 101 - __u32 number_of_partitions = le32_to_cpu(lvid->numOfPartitions); 102 - __u32 offset = number_of_partitions * 2 * 103 - sizeof(uint32_t)/sizeof(uint8_t); 99 + struct logicalVolIntegrityDesc *lvid; 100 + unsigned int partnum; 101 + unsigned int offset; 102 + 103 + if (!UDF_SB(sb)->s_lvid_bh) 104 + return NULL; 105 + lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data; 106 + partnum = le32_to_cpu(lvid->numOfPartitions); 107 + if ((sb->s_blocksize - sizeof(struct logicalVolIntegrityDescImpUse) - 108 + offsetof(struct logicalVolIntegrityDesc, impUse)) / 109 + (2 * sizeof(uint32_t)) < partnum) { 110 + udf_err(sb, "Logical volume integrity descriptor corrupted " 111 + "(numOfPartitions = %u)!\n", partnum); 112 + return NULL; 113 + } 114 + /* The offset is to skip freeSpaceTable and sizeTable arrays */ 115 + offset = partnum * 2 * sizeof(uint32_t); 104 116 return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]); 105 117 } 106 118 ··· 641 629 struct udf_options uopt; 642 630 struct udf_sb_info *sbi = UDF_SB(sb); 643 631 int error = 0; 632 + struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); 644 633 645 - if (sbi->s_lvid_bh) { 646 - int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); 634 + if (lvidiu) { 635 + int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev); 647 636 if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY)) 648 637 return -EACCES; 649 638 } ··· 1918 1905 1919 1906 if (!bh) 1920 1907 return; 1908 + lvid = (struct logicalVolIntegrityDesc *)bh->b_data; 1909 + lvidiu = udf_sb_lvidiu(sb); 1910 + if (!lvidiu) 1911 + return; 1921 1912 1922 1913 mutex_lock(&sbi->s_alloc_mutex); 1923 - lvid = (struct logicalVolIntegrityDesc *)bh->b_data; 1924 - lvidiu = udf_sb_lvidiu(sbi); 1925 - 1926 1914 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1927 1915 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1928 1916 udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ··· 1951 1937 1952 1938 if (!bh) 1953 1939 return; 1940 + lvid = (struct logicalVolIntegrityDesc *)bh->b_data; 1941 + lvidiu = udf_sb_lvidiu(sb); 1942 + if (!lvidiu) 1943 + return; 1954 1944 1955 1945 mutex_lock(&sbi->s_alloc_mutex); 1956 - lvid = (struct logicalVolIntegrityDesc *)bh->b_data; 1957 - lvidiu = udf_sb_lvidiu(sbi); 1958 1946 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1959 1947 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1960 1948 udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); ··· 2109 2093 2110 2094 if (sbi->s_lvid_bh) { 2111 2095 struct logicalVolIntegrityDescImpUse *lvidiu = 2112 - udf_sb_lvidiu(sbi); 2113 - uint16_t minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); 2114 - uint16_t minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); 2115 - /* uint16_t maxUDFWriteRev = 2116 - le16_to_cpu(lvidiu->maxUDFWriteRev); */ 2096 + udf_sb_lvidiu(sb); 2097 + uint16_t minUDFReadRev; 2098 + uint16_t minUDFWriteRev; 2117 2099 2100 + if (!lvidiu) { 2101 + ret = -EINVAL; 2102 + goto error_out; 2103 + } 2104 + minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); 2105 + minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); 2118 2106 if (minUDFReadRev > UDF_MAX_READ_VERSION) { 2119 2107 udf_err(sb, "minUDFReadRev=%x (max is %x)\n", 2120 - le16_to_cpu(lvidiu->minUDFReadRev), 2108 + minUDFReadRev, 2121 2109 UDF_MAX_READ_VERSION); 2122 2110 ret = -EINVAL; 2123 2111 goto error_out; ··· 2285 2265 struct logicalVolIntegrityDescImpUse *lvidiu; 2286 2266 u64 id = huge_encode_dev(sb->s_bdev->bd_dev); 2287 2267 2288 - if (sbi->s_lvid_bh != NULL) 2289 - lvidiu = udf_sb_lvidiu(sbi); 2290 - else 2291 - lvidiu = NULL; 2292 - 2268 + lvidiu = udf_sb_lvidiu(sb); 2293 2269 buf->f_type = UDF_SUPER_MAGIC; 2294 2270 buf->f_bsize = sb->s_blocksize; 2295 2271 buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len;
+1 -1
fs/udf/udf_sb.h
··· 162 162 return sb->s_fs_info; 163 163 } 164 164 165 - struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi); 165 + struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb); 166 166 167 167 int udf_compute_nr_groups(struct super_block *sb, u32 partition); 168 168