diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 16:53:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 16:53:34 -0400 |
commit | 7ce1e15d9a85a2b589a68a04afb2b2ded109b680 (patch) | |
tree | 0f21f4f97f7ac5efc0994656a57d6489a4f05b60 | |
parent | 70cb0d02b58128db07fc39b5e87a2873e2c16bde (diff) | |
parent | 6565c182094f69e4ffdece337d395eb7ec760efc (diff) |
Merge tag 'for_v5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull ext2, quota, udf fixes and cleanups from Jan Kara:
- two small quota fixes (in grace time handling and possible missed
accounting of preallocated blocks beyond EOF).
- some ext2 cleanups
- udf fixes for better compatibility with Windows 10 generated media
(named streams, write-protection using domain-identifier, placement
of volume recognition sequence)
- some udf cleanups
* tag 'for_v5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
quota: fix wrong condition in is_quota_modification()
fs-udf: Delete an unnecessary check before brelse()
ext2: Delete an unnecessary check before brelse()
udf: Drop forward function declarations
udf: Verify domain identifier fields
udf: augment UDF permissions on new inodes
udf: Use dynamic debug infrastructure
udf: reduce leakage of blocks related to named streams
udf: prevent allocation beyond UDF partition
quota: fix condition for resetting time limit in do_set_dqblk()
ext2: code cleanup for ext2_free_blocks()
ext2: fix block range in ext2_data_block_valid()
udf: support 2048-byte spacing of VRS descriptors on 4K media
udf: refactor VRS descriptor identification
-rw-r--r-- | fs/ext2/balloc.c | 10 | ||||
-rw-r--r-- | fs/ext2/super.c | 3 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 2 | ||||
-rw-r--r-- | fs/quota/dquot.c | 4 | ||||
-rw-r--r-- | fs/udf/balloc.c | 11 | ||||
-rw-r--r-- | fs/udf/ecma_167.h | 14 | ||||
-rw-r--r-- | fs/udf/file.c | 3 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 3 | ||||
-rw-r--r-- | fs/udf/inode.c | 55 | ||||
-rw-r--r-- | fs/udf/super.c | 261 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 6 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 11 | ||||
-rw-r--r-- | include/linux/quotaops.h | 2 |
13 files changed, 249 insertions, 136 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 547c165299c0..e0cc55164505 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -490,9 +490,7 @@ void ext2_free_blocks (struct inode * inode, unsigned long block, | |||
490 | struct ext2_super_block * es = sbi->s_es; | 490 | struct ext2_super_block * es = sbi->s_es; |
491 | unsigned freed = 0, group_freed; | 491 | unsigned freed = 0, group_freed; |
492 | 492 | ||
493 | if (block < le32_to_cpu(es->s_first_data_block) || | 493 | if (!ext2_data_block_valid(sbi, block, count)) { |
494 | block + count < block || | ||
495 | block + count > le32_to_cpu(es->s_blocks_count)) { | ||
496 | ext2_error (sb, "ext2_free_blocks", | 494 | ext2_error (sb, "ext2_free_blocks", |
497 | "Freeing blocks not in datazone - " | 495 | "Freeing blocks not in datazone - " |
498 | "block = %lu, count = %lu", block, count); | 496 | "block = %lu, count = %lu", block, count); |
@@ -1203,13 +1201,13 @@ int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk, | |||
1203 | unsigned int count) | 1201 | unsigned int count) |
1204 | { | 1202 | { |
1205 | if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || | 1203 | if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || |
1206 | (start_blk + count < start_blk) || | 1204 | (start_blk + count - 1 < start_blk) || |
1207 | (start_blk > le32_to_cpu(sbi->s_es->s_blocks_count))) | 1205 | (start_blk + count - 1 >= le32_to_cpu(sbi->s_es->s_blocks_count))) |
1208 | return 0; | 1206 | return 0; |
1209 | 1207 | ||
1210 | /* Ensure we do not step over superblock */ | 1208 | /* Ensure we do not step over superblock */ |
1211 | if ((start_blk <= sbi->s_sb_block) && | 1209 | if ((start_blk <= sbi->s_sb_block) && |
1212 | (start_blk + count >= sbi->s_sb_block)) | 1210 | (start_blk + count - 1 >= sbi->s_sb_block)) |
1213 | return 0; | 1211 | return 0; |
1214 | 1212 | ||
1215 | return 1; | 1213 | return 1; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index baa36c6fb71e..30c630d73f0f 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -162,8 +162,7 @@ static void ext2_put_super (struct super_block * sb) | |||
162 | } | 162 | } |
163 | db_count = sbi->s_gdb_count; | 163 | db_count = sbi->s_gdb_count; |
164 | for (i = 0; i < db_count; i++) | 164 | for (i = 0; i < db_count; i++) |
165 | if (sbi->s_group_desc[i]) | 165 | brelse(sbi->s_group_desc[i]); |
166 | brelse (sbi->s_group_desc[i]); | ||
167 | kfree(sbi->s_group_desc); | 166 | kfree(sbi->s_group_desc); |
168 | kfree(sbi->s_debts); | 167 | kfree(sbi->s_debts); |
169 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 168 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 79369c13cc55..0456bc990b5e 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -794,7 +794,7 @@ ext2_xattr_delete_inode(struct inode *inode) | |||
794 | if (!EXT2_I(inode)->i_file_acl) | 794 | if (!EXT2_I(inode)->i_file_acl) |
795 | goto cleanup; | 795 | goto cleanup; |
796 | 796 | ||
797 | if (!ext2_data_block_valid(sbi, EXT2_I(inode)->i_file_acl, 0)) { | 797 | if (!ext2_data_block_valid(sbi, EXT2_I(inode)->i_file_acl, 1)) { |
798 | ext2_error(inode->i_sb, "ext2_xattr_delete_inode", | 798 | ext2_error(inode->i_sb, "ext2_xattr_delete_inode", |
799 | "inode %ld: xattr block %d is out of data blocks range", | 799 | "inode %ld: xattr block %d is out of data blocks range", |
800 | inode->i_ino, EXT2_I(inode)->i_file_acl); | 800 | inode->i_ino, EXT2_I(inode)->i_file_acl); |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index be9c471cdbc8..6e826b454082 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -2731,7 +2731,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |||
2731 | 2731 | ||
2732 | if (check_blim) { | 2732 | if (check_blim) { |
2733 | if (!dm->dqb_bsoftlimit || | 2733 | if (!dm->dqb_bsoftlimit || |
2734 | dm->dqb_curspace + dm->dqb_rsvspace < dm->dqb_bsoftlimit) { | 2734 | dm->dqb_curspace + dm->dqb_rsvspace <= dm->dqb_bsoftlimit) { |
2735 | dm->dqb_btime = 0; | 2735 | dm->dqb_btime = 0; |
2736 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 2736 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
2737 | } else if (!(di->d_fieldmask & QC_SPC_TIMER)) | 2737 | } else if (!(di->d_fieldmask & QC_SPC_TIMER)) |
@@ -2740,7 +2740,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |||
2740 | } | 2740 | } |
2741 | if (check_ilim) { | 2741 | if (check_ilim) { |
2742 | if (!dm->dqb_isoftlimit || | 2742 | if (!dm->dqb_isoftlimit || |
2743 | dm->dqb_curinodes < dm->dqb_isoftlimit) { | 2743 | dm->dqb_curinodes <= dm->dqb_isoftlimit) { |
2744 | dm->dqb_itime = 0; | 2744 | dm->dqb_itime = 0; |
2745 | clear_bit(DQ_INODES_B, &dquot->dq_flags); | 2745 | clear_bit(DQ_INODES_B, &dquot->dq_flags); |
2746 | } else if (!(di->d_fieldmask & QC_INO_TIMER)) | 2746 | } else if (!(di->d_fieldmask & QC_INO_TIMER)) |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index ec85aeaed54a..02f03fadb75b 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -325,6 +325,17 @@ got_block: | |||
325 | newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - | 325 | newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - |
326 | (sizeof(struct spaceBitmapDesc) << 3); | 326 | (sizeof(struct spaceBitmapDesc) << 3); |
327 | 327 | ||
328 | if (newblock >= sbi->s_partmaps[partition].s_partition_len) { | ||
329 | /* | ||
330 | * Ran off the end of the bitmap, and bits following are | ||
331 | * non-compliant (not all zero) | ||
332 | */ | ||
333 | udf_err(sb, "bitmap for partition %d corrupted (block %u marked" | ||
334 | " as free, partition length is %u)\n", partition, | ||
335 | newblock, sbi->s_partmaps[partition].s_partition_len); | ||
336 | goto error_return; | ||
337 | } | ||
338 | |||
328 | if (!udf_clear_bit(bit, bh->b_data)) { | 339 | if (!udf_clear_bit(bit, bh->b_data)) { |
329 | udf_debug("bit already cleared for block %d\n", bit); | 340 | udf_debug("bit already cleared for block %d\n", bit); |
330 | goto repeat; | 341 | goto repeat; |
diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h index 9f24bd1a9f44..fb7f2c7bec9c 100644 --- a/fs/udf/ecma_167.h +++ b/fs/udf/ecma_167.h | |||
@@ -88,6 +88,20 @@ struct regid { | |||
88 | #define ENTITYID_FLAGS_DIRTY 0x00 | 88 | #define ENTITYID_FLAGS_DIRTY 0x00 |
89 | #define ENTITYID_FLAGS_PROTECTED 0x01 | 89 | #define ENTITYID_FLAGS_PROTECTED 0x01 |
90 | 90 | ||
91 | /* OSTA UDF 2.1.5.2 */ | ||
92 | #define UDF_ID_COMPLIANT "*OSTA UDF Compliant" | ||
93 | |||
94 | /* OSTA UDF 2.1.5.3 */ | ||
95 | struct domainEntityIDSuffix { | ||
96 | uint16_t revision; | ||
97 | uint8_t flags; | ||
98 | uint8_t reserved[5]; | ||
99 | }; | ||
100 | |||
101 | /* OSTA UDF 2.1.5.3 */ | ||
102 | #define ENTITYIDSUFFIX_FLAGS_HARDWRITEPROTECT 0 | ||
103 | #define ENTITYIDSUFFIX_FLAGS_SOFTWRITEPROTECT 1 | ||
104 | |||
91 | /* Volume Structure Descriptor (ECMA 167r3 2/9.1) */ | 105 | /* Volume Structure Descriptor (ECMA 167r3 2/9.1) */ |
92 | #define VSD_STD_ID_LEN 5 | 106 | #define VSD_STD_ID_LEN 5 |
93 | struct volStructDesc { | 107 | struct volStructDesc { |
diff --git a/fs/udf/file.c b/fs/udf/file.c index cd31e4f6d6da..628941a6b79a 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -280,6 +280,9 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr) | |||
280 | return error; | 280 | return error; |
281 | } | 281 | } |
282 | 282 | ||
283 | if (attr->ia_valid & ATTR_MODE) | ||
284 | udf_update_extra_perms(inode, attr->ia_mode); | ||
285 | |||
283 | setattr_copy(inode, attr); | 286 | setattr_copy(inode, attr); |
284 | mark_inode_dirty(inode); | 287 | mark_inode_dirty(inode); |
285 | return 0; | 288 | return 0; |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index f8e5872f7cc2..0adb40718a5d 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -118,6 +118,9 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode) | |||
118 | iinfo->i_lenAlloc = 0; | 118 | iinfo->i_lenAlloc = 0; |
119 | iinfo->i_use = 0; | 119 | iinfo->i_use = 0; |
120 | iinfo->i_checkpoint = 1; | 120 | iinfo->i_checkpoint = 1; |
121 | iinfo->i_extraPerms = FE_PERM_U_CHATTR; | ||
122 | udf_update_extra_perms(inode, mode); | ||
123 | |||
121 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) | 124 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) |
122 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; | 125 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; |
123 | else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 126 | else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 9bb18311a22f..ea80036d7897 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -45,6 +45,13 @@ | |||
45 | 45 | ||
46 | #define EXTENT_MERGE_SIZE 5 | 46 | #define EXTENT_MERGE_SIZE 5 |
47 | 47 | ||
48 | #define FE_MAPPED_PERMS (FE_PERM_U_READ | FE_PERM_U_WRITE | FE_PERM_U_EXEC | \ | ||
49 | FE_PERM_G_READ | FE_PERM_G_WRITE | FE_PERM_G_EXEC | \ | ||
50 | FE_PERM_O_READ | FE_PERM_O_WRITE | FE_PERM_O_EXEC) | ||
51 | |||
52 | #define FE_DELETE_PERMS (FE_PERM_U_DELETE | FE_PERM_G_DELETE | \ | ||
53 | FE_PERM_O_DELETE) | ||
54 | |||
48 | static umode_t udf_convert_permissions(struct fileEntry *); | 55 | static umode_t udf_convert_permissions(struct fileEntry *); |
49 | static int udf_update_inode(struct inode *, int); | 56 | static int udf_update_inode(struct inode *, int); |
50 | static int udf_sync_inode(struct inode *inode); | 57 | static int udf_sync_inode(struct inode *inode); |
@@ -1458,6 +1465,8 @@ reread: | |||
1458 | else | 1465 | else |
1459 | inode->i_mode = udf_convert_permissions(fe); | 1466 | inode->i_mode = udf_convert_permissions(fe); |
1460 | inode->i_mode &= ~sbi->s_umask; | 1467 | inode->i_mode &= ~sbi->s_umask; |
1468 | iinfo->i_extraPerms = le32_to_cpu(fe->permissions) & ~FE_MAPPED_PERMS; | ||
1469 | |||
1461 | read_unlock(&sbi->s_cred_lock); | 1470 | read_unlock(&sbi->s_cred_lock); |
1462 | 1471 | ||
1463 | link_count = le16_to_cpu(fe->fileLinkCount); | 1472 | link_count = le16_to_cpu(fe->fileLinkCount); |
@@ -1485,6 +1494,8 @@ reread: | |||
1485 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); | 1494 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); |
1486 | iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); | 1495 | iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); |
1487 | iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); | 1496 | iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); |
1497 | iinfo->i_streamdir = 0; | ||
1498 | iinfo->i_lenStreams = 0; | ||
1488 | } else { | 1499 | } else { |
1489 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << | 1500 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << |
1490 | (inode->i_sb->s_blocksize_bits - 9); | 1501 | (inode->i_sb->s_blocksize_bits - 9); |
@@ -1498,6 +1509,16 @@ reread: | |||
1498 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); | 1509 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); |
1499 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); | 1510 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); |
1500 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); | 1511 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); |
1512 | |||
1513 | /* Named streams */ | ||
1514 | iinfo->i_streamdir = (efe->streamDirectoryICB.extLength != 0); | ||
1515 | iinfo->i_locStreamdir = | ||
1516 | lelb_to_cpu(efe->streamDirectoryICB.extLocation); | ||
1517 | iinfo->i_lenStreams = le64_to_cpu(efe->objectSize); | ||
1518 | if (iinfo->i_lenStreams >= inode->i_size) | ||
1519 | iinfo->i_lenStreams -= inode->i_size; | ||
1520 | else | ||
1521 | iinfo->i_lenStreams = 0; | ||
1501 | } | 1522 | } |
1502 | inode->i_generation = iinfo->i_unique; | 1523 | inode->i_generation = iinfo->i_unique; |
1503 | 1524 | ||
@@ -1619,6 +1640,23 @@ static umode_t udf_convert_permissions(struct fileEntry *fe) | |||
1619 | return mode; | 1640 | return mode; |
1620 | } | 1641 | } |
1621 | 1642 | ||
1643 | void udf_update_extra_perms(struct inode *inode, umode_t mode) | ||
1644 | { | ||
1645 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
1646 | |||
1647 | /* | ||
1648 | * UDF 2.01 sec. 3.3.3.3 Note 2: | ||
1649 | * In Unix, delete permission tracks write | ||
1650 | */ | ||
1651 | iinfo->i_extraPerms &= ~FE_DELETE_PERMS; | ||
1652 | if (mode & 0200) | ||
1653 | iinfo->i_extraPerms |= FE_PERM_U_DELETE; | ||
1654 | if (mode & 0020) | ||
1655 | iinfo->i_extraPerms |= FE_PERM_G_DELETE; | ||
1656 | if (mode & 0002) | ||
1657 | iinfo->i_extraPerms |= FE_PERM_O_DELETE; | ||
1658 | } | ||
1659 | |||
1622 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) | 1660 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1623 | { | 1661 | { |
1624 | return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | 1662 | return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
@@ -1691,10 +1729,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1691 | ((inode->i_mode & 0070) << 2) | | 1729 | ((inode->i_mode & 0070) << 2) | |
1692 | ((inode->i_mode & 0700) << 4); | 1730 | ((inode->i_mode & 0700) << 4); |
1693 | 1731 | ||
1694 | udfperms |= (le32_to_cpu(fe->permissions) & | 1732 | udfperms |= iinfo->i_extraPerms; |
1695 | (FE_PERM_O_DELETE | FE_PERM_O_CHATTR | | ||
1696 | FE_PERM_G_DELETE | FE_PERM_G_CHATTR | | ||
1697 | FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); | ||
1698 | fe->permissions = cpu_to_le32(udfperms); | 1733 | fe->permissions = cpu_to_le32(udfperms); |
1699 | 1734 | ||
1700 | if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) | 1735 | if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) |
@@ -1760,9 +1795,19 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1760 | iinfo->i_ext.i_data, | 1795 | iinfo->i_ext.i_data, |
1761 | inode->i_sb->s_blocksize - | 1796 | inode->i_sb->s_blocksize - |
1762 | sizeof(struct extendedFileEntry)); | 1797 | sizeof(struct extendedFileEntry)); |
1763 | efe->objectSize = cpu_to_le64(inode->i_size); | 1798 | efe->objectSize = |
1799 | cpu_to_le64(inode->i_size + iinfo->i_lenStreams); | ||
1764 | efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); | 1800 | efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); |
1765 | 1801 | ||
1802 | if (iinfo->i_streamdir) { | ||
1803 | struct long_ad *icb_lad = &efe->streamDirectoryICB; | ||
1804 | |||
1805 | icb_lad->extLocation = | ||
1806 | cpu_to_lelb(iinfo->i_locStreamdir); | ||
1807 | icb_lad->extLength = | ||
1808 | cpu_to_le32(inode->i_sb->s_blocksize); | ||
1809 | } | ||
1810 | |||
1766 | udf_adjust_time(iinfo, inode->i_atime); | 1811 | udf_adjust_time(iinfo, inode->i_atime); |
1767 | udf_adjust_time(iinfo, inode->i_mtime); | 1812 | udf_adjust_time(iinfo, inode->i_mtime); |
1768 | udf_adjust_time(iinfo, inode->i_ctime); | 1813 | udf_adjust_time(iinfo, inode->i_ctime); |
diff --git a/fs/udf/super.c b/fs/udf/super.c index a14346137361..8c28e93e9b73 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -92,10 +92,6 @@ static void udf_put_super(struct super_block *); | |||
92 | static int udf_sync_fs(struct super_block *, int); | 92 | static int udf_sync_fs(struct super_block *, int); |
93 | static int udf_remount_fs(struct super_block *, int *, char *); | 93 | static int udf_remount_fs(struct super_block *, int *, char *); |
94 | static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); | 94 | static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); |
95 | static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, | ||
96 | struct kernel_lb_addr *); | ||
97 | static void udf_load_fileset(struct super_block *, struct buffer_head *, | ||
98 | struct kernel_lb_addr *); | ||
99 | static void udf_open_lvid(struct super_block *); | 95 | static void udf_open_lvid(struct super_block *); |
100 | static void udf_close_lvid(struct super_block *); | 96 | static void udf_close_lvid(struct super_block *); |
101 | static unsigned int udf_count_free(struct super_block *); | 97 | static unsigned int udf_count_free(struct super_block *); |
@@ -151,9 +147,11 @@ static struct inode *udf_alloc_inode(struct super_block *sb) | |||
151 | 147 | ||
152 | ei->i_unique = 0; | 148 | ei->i_unique = 0; |
153 | ei->i_lenExtents = 0; | 149 | ei->i_lenExtents = 0; |
150 | ei->i_lenStreams = 0; | ||
154 | ei->i_next_alloc_block = 0; | 151 | ei->i_next_alloc_block = 0; |
155 | ei->i_next_alloc_goal = 0; | 152 | ei->i_next_alloc_goal = 0; |
156 | ei->i_strat4096 = 0; | 153 | ei->i_strat4096 = 0; |
154 | ei->i_streamdir = 0; | ||
157 | init_rwsem(&ei->i_data_sem); | 155 | init_rwsem(&ei->i_data_sem); |
158 | ei->cached_extent.lstart = -1; | 156 | ei->cached_extent.lstart = -1; |
159 | spin_lock_init(&ei->i_extent_cache_lock); | 157 | spin_lock_init(&ei->i_extent_cache_lock); |
@@ -271,8 +269,7 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | |||
271 | int nr_groups = bitmap->s_nr_groups; | 269 | int nr_groups = bitmap->s_nr_groups; |
272 | 270 | ||
273 | for (i = 0; i < nr_groups; i++) | 271 | for (i = 0; i < nr_groups; i++) |
274 | if (bitmap->s_block_bitmap[i]) | 272 | brelse(bitmap->s_block_bitmap[i]); |
275 | brelse(bitmap->s_block_bitmap[i]); | ||
276 | 273 | ||
277 | kvfree(bitmap); | 274 | kvfree(bitmap); |
278 | } | 275 | } |
@@ -646,16 +643,67 @@ out_unlock: | |||
646 | return error; | 643 | return error; |
647 | } | 644 | } |
648 | 645 | ||
649 | /* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ | 646 | /* |
650 | /* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ | 647 | * Check VSD descriptor. Returns -1 in case we are at the end of volume |
651 | static loff_t udf_check_vsd(struct super_block *sb) | 648 | * recognition area, 0 if the descriptor is valid but non-interesting, 1 if |
649 | * we found one of NSR descriptors we are looking for. | ||
650 | */ | ||
651 | static int identify_vsd(const struct volStructDesc *vsd) | ||
652 | { | ||
653 | int ret = 0; | ||
654 | |||
655 | if (!memcmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) { | ||
656 | switch (vsd->structType) { | ||
657 | case 0: | ||
658 | udf_debug("ISO9660 Boot Record found\n"); | ||
659 | break; | ||
660 | case 1: | ||
661 | udf_debug("ISO9660 Primary Volume Descriptor found\n"); | ||
662 | break; | ||
663 | case 2: | ||
664 | udf_debug("ISO9660 Supplementary Volume Descriptor found\n"); | ||
665 | break; | ||
666 | case 3: | ||
667 | udf_debug("ISO9660 Volume Partition Descriptor found\n"); | ||
668 | break; | ||
669 | case 255: | ||
670 | udf_debug("ISO9660 Volume Descriptor Set Terminator found\n"); | ||
671 | break; | ||
672 | default: | ||
673 | udf_debug("ISO9660 VRS (%u) found\n", vsd->structType); | ||
674 | break; | ||
675 | } | ||
676 | } else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) | ||
677 | ; /* ret = 0 */ | ||
678 | else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) | ||
679 | ret = 1; | ||
680 | else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) | ||
681 | ret = 1; | ||
682 | else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BOOT2, VSD_STD_ID_LEN)) | ||
683 | ; /* ret = 0 */ | ||
684 | else if (!memcmp(vsd->stdIdent, VSD_STD_ID_CDW02, VSD_STD_ID_LEN)) | ||
685 | ; /* ret = 0 */ | ||
686 | else { | ||
687 | /* TEA01 or invalid id : end of volume recognition area */ | ||
688 | ret = -1; | ||
689 | } | ||
690 | |||
691 | return ret; | ||
692 | } | ||
693 | |||
694 | /* | ||
695 | * Check Volume Structure Descriptors (ECMA 167 2/9.1) | ||
696 | * We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) | ||
697 | * @return 1 if NSR02 or NSR03 found, | ||
698 | * -1 if first sector read error, 0 otherwise | ||
699 | */ | ||
700 | static int udf_check_vsd(struct super_block *sb) | ||
652 | { | 701 | { |
653 | struct volStructDesc *vsd = NULL; | 702 | struct volStructDesc *vsd = NULL; |
654 | loff_t sector = VSD_FIRST_SECTOR_OFFSET; | 703 | loff_t sector = VSD_FIRST_SECTOR_OFFSET; |
655 | int sectorsize; | 704 | int sectorsize; |
656 | struct buffer_head *bh = NULL; | 705 | struct buffer_head *bh = NULL; |
657 | int nsr02 = 0; | 706 | int nsr = 0; |
658 | int nsr03 = 0; | ||
659 | struct udf_sb_info *sbi; | 707 | struct udf_sb_info *sbi; |
660 | 708 | ||
661 | sbi = UDF_SB(sb); | 709 | sbi = UDF_SB(sb); |
@@ -679,71 +727,36 @@ static loff_t udf_check_vsd(struct super_block *sb) | |||
679 | * activity. This actually happened with uninitialised SSD partitions | 727 | * activity. This actually happened with uninitialised SSD partitions |
680 | * (all 0xFF) before the check for the limit and all valid IDs were | 728 | * (all 0xFF) before the check for the limit and all valid IDs were |
681 | * added */ | 729 | * added */ |
682 | for (; !nsr02 && !nsr03 && sector < VSD_MAX_SECTOR_OFFSET; | 730 | for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) { |
683 | sector += sectorsize) { | ||
684 | /* Read a block */ | 731 | /* Read a block */ |
685 | bh = udf_tread(sb, sector >> sb->s_blocksize_bits); | 732 | bh = udf_tread(sb, sector >> sb->s_blocksize_bits); |
686 | if (!bh) | 733 | if (!bh) |
687 | break; | 734 | break; |
688 | 735 | ||
689 | /* Look for ISO descriptors */ | ||
690 | vsd = (struct volStructDesc *)(bh->b_data + | 736 | vsd = (struct volStructDesc *)(bh->b_data + |
691 | (sector & (sb->s_blocksize - 1))); | 737 | (sector & (sb->s_blocksize - 1))); |
692 | 738 | nsr = identify_vsd(vsd); | |
693 | if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, | 739 | /* Found NSR or end? */ |
694 | VSD_STD_ID_LEN)) { | 740 | if (nsr) { |
695 | switch (vsd->structType) { | ||
696 | case 0: | ||
697 | udf_debug("ISO9660 Boot Record found\n"); | ||
698 | break; | ||
699 | case 1: | ||
700 | udf_debug("ISO9660 Primary Volume Descriptor found\n"); | ||
701 | break; | ||
702 | case 2: | ||
703 | udf_debug("ISO9660 Supplementary Volume Descriptor found\n"); | ||
704 | break; | ||
705 | case 3: | ||
706 | udf_debug("ISO9660 Volume Partition Descriptor found\n"); | ||
707 | break; | ||
708 | case 255: | ||
709 | udf_debug("ISO9660 Volume Descriptor Set Terminator found\n"); | ||
710 | break; | ||
711 | default: | ||
712 | udf_debug("ISO9660 VRS (%u) found\n", | ||
713 | vsd->structType); | ||
714 | break; | ||
715 | } | ||
716 | } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, | ||
717 | VSD_STD_ID_LEN)) | ||
718 | ; /* nothing */ | ||
719 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, | ||
720 | VSD_STD_ID_LEN)) { | ||
721 | brelse(bh); | ||
722 | break; | ||
723 | } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, | ||
724 | VSD_STD_ID_LEN)) | ||
725 | nsr02 = sector; | ||
726 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, | ||
727 | VSD_STD_ID_LEN)) | ||
728 | nsr03 = sector; | ||
729 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BOOT2, | ||
730 | VSD_STD_ID_LEN)) | ||
731 | ; /* nothing */ | ||
732 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CDW02, | ||
733 | VSD_STD_ID_LEN)) | ||
734 | ; /* nothing */ | ||
735 | else { | ||
736 | /* invalid id : end of volume recognition area */ | ||
737 | brelse(bh); | 741 | brelse(bh); |
738 | break; | 742 | break; |
739 | } | 743 | } |
744 | /* | ||
745 | * Special handling for improperly formatted VRS (e.g., Win10) | ||
746 | * where components are separated by 2048 bytes even though | ||
747 | * sectors are 4K | ||
748 | */ | ||
749 | if (sb->s_blocksize == 4096) { | ||
750 | nsr = identify_vsd(vsd + 1); | ||
751 | /* Ignore unknown IDs... */ | ||
752 | if (nsr < 0) | ||
753 | nsr = 0; | ||
754 | } | ||
740 | brelse(bh); | 755 | brelse(bh); |
741 | } | 756 | } |
742 | 757 | ||
743 | if (nsr03) | 758 | if (nsr > 0) |
744 | return nsr03; | 759 | return 1; |
745 | else if (nsr02) | ||
746 | return nsr02; | ||
747 | else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == | 760 | else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == |
748 | VSD_FIRST_SECTOR_OFFSET) | 761 | VSD_FIRST_SECTOR_OFFSET) |
749 | return -1; | 762 | return -1; |
@@ -751,34 +764,82 @@ static loff_t udf_check_vsd(struct super_block *sb) | |||
751 | return 0; | 764 | return 0; |
752 | } | 765 | } |
753 | 766 | ||
767 | static int udf_verify_domain_identifier(struct super_block *sb, | ||
768 | struct regid *ident, char *dname) | ||
769 | { | ||
770 | struct domainEntityIDSuffix *suffix; | ||
771 | |||
772 | if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) { | ||
773 | udf_warn(sb, "Not OSTA UDF compliant %s descriptor.\n", dname); | ||
774 | goto force_ro; | ||
775 | } | ||
776 | if (ident->flags & (1 << ENTITYID_FLAGS_DIRTY)) { | ||
777 | udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor.\n", | ||
778 | dname); | ||
779 | goto force_ro; | ||
780 | } | ||
781 | suffix = (struct domainEntityIDSuffix *)ident->identSuffix; | ||
782 | if (suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_HARDWRITEPROTECT) || | ||
783 | suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_SOFTWRITEPROTECT)) { | ||
784 | if (!sb_rdonly(sb)) { | ||
785 | udf_warn(sb, "Descriptor for %s marked write protected." | ||
786 | " Forcing read only mount.\n", dname); | ||
787 | } | ||
788 | goto force_ro; | ||
789 | } | ||
790 | return 0; | ||
791 | |||
792 | force_ro: | ||
793 | if (!sb_rdonly(sb)) | ||
794 | return -EACCES; | ||
795 | UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); | ||
796 | return 0; | ||
797 | } | ||
798 | |||
799 | static int udf_load_fileset(struct super_block *sb, struct fileSetDesc *fset, | ||
800 | struct kernel_lb_addr *root) | ||
801 | { | ||
802 | int ret; | ||
803 | |||
804 | ret = udf_verify_domain_identifier(sb, &fset->domainIdent, "file set"); | ||
805 | if (ret < 0) | ||
806 | return ret; | ||
807 | |||
808 | *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation); | ||
809 | UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum); | ||
810 | |||
811 | udf_debug("Rootdir at block=%u, partition=%u\n", | ||
812 | root->logicalBlockNum, root->partitionReferenceNum); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
754 | static int udf_find_fileset(struct super_block *sb, | 816 | static int udf_find_fileset(struct super_block *sb, |
755 | struct kernel_lb_addr *fileset, | 817 | struct kernel_lb_addr *fileset, |
756 | struct kernel_lb_addr *root) | 818 | struct kernel_lb_addr *root) |
757 | { | 819 | { |
758 | struct buffer_head *bh = NULL; | 820 | struct buffer_head *bh = NULL; |
759 | uint16_t ident; | 821 | uint16_t ident; |
822 | int ret; | ||
760 | 823 | ||
761 | if (fileset->logicalBlockNum != 0xFFFFFFFF || | 824 | if (fileset->logicalBlockNum == 0xFFFFFFFF && |
762 | fileset->partitionReferenceNum != 0xFFFF) { | 825 | fileset->partitionReferenceNum == 0xFFFF) |
763 | bh = udf_read_ptagged(sb, fileset, 0, &ident); | 826 | return -EINVAL; |
764 | |||
765 | if (!bh) { | ||
766 | return 1; | ||
767 | } else if (ident != TAG_IDENT_FSD) { | ||
768 | brelse(bh); | ||
769 | return 1; | ||
770 | } | ||
771 | |||
772 | udf_debug("Fileset at block=%u, partition=%u\n", | ||
773 | fileset->logicalBlockNum, | ||
774 | fileset->partitionReferenceNum); | ||
775 | 827 | ||
776 | UDF_SB(sb)->s_partition = fileset->partitionReferenceNum; | 828 | bh = udf_read_ptagged(sb, fileset, 0, &ident); |
777 | udf_load_fileset(sb, bh, root); | 829 | if (!bh) |
830 | return -EIO; | ||
831 | if (ident != TAG_IDENT_FSD) { | ||
778 | brelse(bh); | 832 | brelse(bh); |
779 | return 0; | 833 | return -EINVAL; |
780 | } | 834 | } |
781 | return 1; | 835 | |
836 | udf_debug("Fileset at block=%u, partition=%u\n", | ||
837 | fileset->logicalBlockNum, fileset->partitionReferenceNum); | ||
838 | |||
839 | UDF_SB(sb)->s_partition = fileset->partitionReferenceNum; | ||
840 | ret = udf_load_fileset(sb, (struct fileSetDesc *)bh->b_data, root); | ||
841 | brelse(bh); | ||
842 | return ret; | ||
782 | } | 843 | } |
783 | 844 | ||
784 | /* | 845 | /* |
@@ -794,9 +855,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) | |||
794 | struct buffer_head *bh; | 855 | struct buffer_head *bh; |
795 | uint16_t ident; | 856 | uint16_t ident; |
796 | int ret = -ENOMEM; | 857 | int ret = -ENOMEM; |
797 | #ifdef UDFFS_DEBUG | ||
798 | struct timestamp *ts; | 858 | struct timestamp *ts; |
799 | #endif | ||
800 | 859 | ||
801 | outstr = kmalloc(128, GFP_NOFS); | 860 | outstr = kmalloc(128, GFP_NOFS); |
802 | if (!outstr) | 861 | if (!outstr) |
@@ -817,13 +876,10 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) | |||
817 | 876 | ||
818 | udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, | 877 | udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, |
819 | pvoldesc->recordingDateAndTime); | 878 | pvoldesc->recordingDateAndTime); |
820 | #ifdef UDFFS_DEBUG | ||
821 | ts = &pvoldesc->recordingDateAndTime; | 879 | ts = &pvoldesc->recordingDateAndTime; |
822 | udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n", | 880 | udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n", |
823 | le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, | 881 | le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, |
824 | ts->minute, le16_to_cpu(ts->typeAndTimezone)); | 882 | ts->minute, le16_to_cpu(ts->typeAndTimezone)); |
825 | #endif | ||
826 | |||
827 | 883 | ||
828 | ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32); | 884 | ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32); |
829 | if (ret < 0) { | 885 | if (ret < 0) { |
@@ -939,21 +995,6 @@ static int udf_load_metadata_files(struct super_block *sb, int partition, | |||
939 | return 0; | 995 | return 0; |
940 | } | 996 | } |
941 | 997 | ||
942 | static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, | ||
943 | struct kernel_lb_addr *root) | ||
944 | { | ||
945 | struct fileSetDesc *fset; | ||
946 | |||
947 | fset = (struct fileSetDesc *)bh->b_data; | ||
948 | |||
949 | *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation); | ||
950 | |||
951 | UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum); | ||
952 | |||
953 | udf_debug("Rootdir at block=%u, partition=%u\n", | ||
954 | root->logicalBlockNum, root->partitionReferenceNum); | ||
955 | } | ||
956 | |||
957 | int udf_compute_nr_groups(struct super_block *sb, u32 partition) | 998 | int udf_compute_nr_groups(struct super_block *sb, u32 partition) |
958 | { | 999 | { |
959 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; | 1000 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
@@ -1238,9 +1279,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) | |||
1238 | * PHYSICAL partitions are already set up | 1279 | * PHYSICAL partitions are already set up |
1239 | */ | 1280 | */ |
1240 | type1_idx = i; | 1281 | type1_idx = i; |
1241 | #ifdef UDFFS_DEBUG | ||
1242 | map = NULL; /* supress 'maybe used uninitialized' warning */ | 1282 | map = NULL; /* supress 'maybe used uninitialized' warning */ |
1243 | #endif | ||
1244 | for (i = 0; i < sbi->s_partitions; i++) { | 1283 | for (i = 0; i < sbi->s_partitions; i++) { |
1245 | map = &sbi->s_partmaps[i]; | 1284 | map = &sbi->s_partmaps[i]; |
1246 | 1285 | ||
@@ -1364,6 +1403,10 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1364 | goto out_bh; | 1403 | goto out_bh; |
1365 | } | 1404 | } |
1366 | 1405 | ||
1406 | ret = udf_verify_domain_identifier(sb, &lvd->domainIdent, | ||
1407 | "logical volume"); | ||
1408 | if (ret) | ||
1409 | goto out_bh; | ||
1367 | ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); | 1410 | ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); |
1368 | if (ret) | 1411 | if (ret) |
1369 | goto out_bh; | 1412 | goto out_bh; |
@@ -1915,7 +1958,7 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, | |||
1915 | int silent, struct kernel_lb_addr *fileset) | 1958 | int silent, struct kernel_lb_addr *fileset) |
1916 | { | 1959 | { |
1917 | struct udf_sb_info *sbi = UDF_SB(sb); | 1960 | struct udf_sb_info *sbi = UDF_SB(sb); |
1918 | loff_t nsr_off; | 1961 | int nsr = 0; |
1919 | int ret; | 1962 | int ret; |
1920 | 1963 | ||
1921 | if (!sb_set_blocksize(sb, uopt->blocksize)) { | 1964 | if (!sb_set_blocksize(sb, uopt->blocksize)) { |
@@ -1926,13 +1969,13 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, | |||
1926 | sbi->s_last_block = uopt->lastblock; | 1969 | sbi->s_last_block = uopt->lastblock; |
1927 | if (!uopt->novrs) { | 1970 | if (!uopt->novrs) { |
1928 | /* Check that it is NSR02 compliant */ | 1971 | /* Check that it is NSR02 compliant */ |
1929 | nsr_off = udf_check_vsd(sb); | 1972 | nsr = udf_check_vsd(sb); |
1930 | if (!nsr_off) { | 1973 | if (!nsr) { |
1931 | if (!silent) | 1974 | if (!silent) |
1932 | udf_warn(sb, "No VRS found\n"); | 1975 | udf_warn(sb, "No VRS found\n"); |
1933 | return -EINVAL; | 1976 | return -EINVAL; |
1934 | } | 1977 | } |
1935 | if (nsr_off == -1) | 1978 | if (nsr == -1) |
1936 | udf_debug("Failed to read sector at offset %d. " | 1979 | udf_debug("Failed to read sector at offset %d. " |
1937 | "Assuming open disc. Skipping validity " | 1980 | "Assuming open disc. Skipping validity " |
1938 | "check\n", VSD_FIRST_SECTOR_OFFSET); | 1981 | "check\n", VSD_FIRST_SECTOR_OFFSET); |
@@ -2216,9 +2259,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
2216 | UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); | 2259 | UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
2217 | } | 2260 | } |
2218 | 2261 | ||
2219 | if (udf_find_fileset(sb, &fileset, &rootdir)) { | 2262 | ret = udf_find_fileset(sb, &fileset, &rootdir); |
2263 | if (ret < 0) { | ||
2220 | udf_warn(sb, "No fileset found\n"); | 2264 | udf_warn(sb, "No fileset found\n"); |
2221 | ret = -EINVAL; | ||
2222 | goto error_out; | 2265 | goto error_out; |
2223 | } | 2266 | } |
2224 | 2267 | ||
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index 2ef0e212f08a..4245d1f63258 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h | |||
@@ -38,16 +38,20 @@ struct udf_inode_info { | |||
38 | __u32 i_next_alloc_block; | 38 | __u32 i_next_alloc_block; |
39 | __u32 i_next_alloc_goal; | 39 | __u32 i_next_alloc_goal; |
40 | __u32 i_checkpoint; | 40 | __u32 i_checkpoint; |
41 | __u32 i_extraPerms; | ||
41 | unsigned i_alloc_type : 3; | 42 | unsigned i_alloc_type : 3; |
42 | unsigned i_efe : 1; /* extendedFileEntry */ | 43 | unsigned i_efe : 1; /* extendedFileEntry */ |
43 | unsigned i_use : 1; /* unallocSpaceEntry */ | 44 | unsigned i_use : 1; /* unallocSpaceEntry */ |
44 | unsigned i_strat4096 : 1; | 45 | unsigned i_strat4096 : 1; |
45 | unsigned reserved : 26; | 46 | unsigned i_streamdir : 1; |
47 | unsigned reserved : 25; | ||
46 | union { | 48 | union { |
47 | struct short_ad *i_sad; | 49 | struct short_ad *i_sad; |
48 | struct long_ad *i_lad; | 50 | struct long_ad *i_lad; |
49 | __u8 *i_data; | 51 | __u8 *i_data; |
50 | } i_ext; | 52 | } i_ext; |
53 | struct kernel_lb_addr i_locStreamdir; | ||
54 | __u64 i_lenStreams; | ||
51 | struct rw_semaphore i_data_sem; | 55 | struct rw_semaphore i_data_sem; |
52 | struct udf_ext_cache cached_extent; | 56 | struct udf_ext_cache cached_extent; |
53 | /* Spinlock for protecting extent cache */ | 57 | /* Spinlock for protecting extent cache */ |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index d89ef71887fc..9dd0814f1077 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -31,16 +31,8 @@ extern __printf(3, 4) void _udf_warn(struct super_block *sb, | |||
31 | #define udf_info(fmt, ...) \ | 31 | #define udf_info(fmt, ...) \ |
32 | pr_info("INFO " fmt, ##__VA_ARGS__) | 32 | pr_info("INFO " fmt, ##__VA_ARGS__) |
33 | 33 | ||
34 | #undef UDFFS_DEBUG | ||
35 | |||
36 | #ifdef UDFFS_DEBUG | ||
37 | #define udf_debug(fmt, ...) \ | ||
38 | printk(KERN_DEBUG pr_fmt("%s:%d:%s: " fmt), \ | ||
39 | __FILE__, __LINE__, __func__, ##__VA_ARGS__) | ||
40 | #else | ||
41 | #define udf_debug(fmt, ...) \ | 34 | #define udf_debug(fmt, ...) \ |
42 | no_printk(fmt, ##__VA_ARGS__) | 35 | pr_debug("%s:%d:%s: " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
43 | #endif | ||
44 | 36 | ||
45 | #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) | 37 | #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) |
46 | #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) | 38 | #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) |
@@ -178,6 +170,7 @@ extern int8_t udf_next_aext(struct inode *, struct extent_position *, | |||
178 | struct kernel_lb_addr *, uint32_t *, int); | 170 | struct kernel_lb_addr *, uint32_t *, int); |
179 | extern int8_t udf_current_aext(struct inode *, struct extent_position *, | 171 | extern int8_t udf_current_aext(struct inode *, struct extent_position *, |
180 | struct kernel_lb_addr *, uint32_t *, int); | 172 | struct kernel_lb_addr *, uint32_t *, int); |
173 | extern void udf_update_extra_perms(struct inode *inode, umode_t mode); | ||
181 | 174 | ||
182 | /* misc.c */ | 175 | /* misc.c */ |
183 | extern struct buffer_head *udf_tgetblk(struct super_block *sb, | 176 | extern struct buffer_head *udf_tgetblk(struct super_block *sb, |
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index dc905a4ff8d7..185d94829701 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
@@ -22,7 +22,7 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb) | |||
22 | /* i_mutex must being held */ | 22 | /* i_mutex must being held */ |
23 | static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) | 23 | static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) |
24 | { | 24 | { |
25 | return (ia->ia_valid & ATTR_SIZE && ia->ia_size != inode->i_size) || | 25 | return (ia->ia_valid & ATTR_SIZE) || |
26 | (ia->ia_valid & ATTR_UID && !uid_eq(ia->ia_uid, inode->i_uid)) || | 26 | (ia->ia_valid & ATTR_UID && !uid_eq(ia->ia_uid, inode->i_uid)) || |
27 | (ia->ia_valid & ATTR_GID && !gid_eq(ia->ia_gid, inode->i_gid)); | 27 | (ia->ia_valid & ATTR_GID && !gid_eq(ia->ia_gid, inode->i_gid)); |
28 | } | 28 | } |