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 /fs/udf/inode.c | |
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
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r-- | fs/udf/inode.c | 55 |
1 files changed, 50 insertions, 5 deletions
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); |