mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 11:04:25 +00:00
\n
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEq1nRK9aeMoq1VSgcnJ2qBz9kQNkFAl2EssMACgkQnJ2qBz9k QNn+LQgApjz2kxt/0foigI5WEdzrS7aFDwyH9NMNRN8b5+cTlYcZCv/UWk8OOtKY bZL5WJetmTan7K+6iFozbIICx/FVij9eIPpqHCxVV34huyHb8pdEH5kn/K0Zos3g h+J9+6efwHuyuWDCWVYYPUAtSIRTNbdF3lCCvaiO/V2AKhqejtRt9u2/LK+eJAKv k7tnuYi0R26HmSabTZMRcMiexRBuCsmCfxvZ01z93htCucAhc4BEJvCaQCgPQKGT vnr+rb7QxrakO0zB0v5MWjv6FveDq+5IzKTYz7OHhiitWeXZz+ATYMeXFL2tjfJH 18BbnalcksQJOqq95yPxwtKZ/2tPKQ== =CNjT -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
7ce1e15d9a
13 changed files with 249 additions and 136 deletions
|
@ -490,9 +490,7 @@ void ext2_free_blocks (struct inode * inode, unsigned long block,
|
||||||
struct ext2_super_block * es = sbi->s_es;
|
struct ext2_super_block * es = sbi->s_es;
|
||||||
unsigned freed = 0, group_freed;
|
unsigned freed = 0, group_freed;
|
||||||
|
|
||||||
if (block < le32_to_cpu(es->s_first_data_block) ||
|
if (!ext2_data_block_valid(sbi, block, count)) {
|
||||||
block + count < block ||
|
|
||||||
block + count > le32_to_cpu(es->s_blocks_count)) {
|
|
||||||
ext2_error (sb, "ext2_free_blocks",
|
ext2_error (sb, "ext2_free_blocks",
|
||||||
"Freeing blocks not in datazone - "
|
"Freeing blocks not in datazone - "
|
||||||
"block = %lu, count = %lu", block, count);
|
"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,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
|
if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
|
||||||
(start_blk + count < start_blk) ||
|
(start_blk + count - 1 < start_blk) ||
|
||||||
(start_blk > le32_to_cpu(sbi->s_es->s_blocks_count)))
|
(start_blk + count - 1 >= le32_to_cpu(sbi->s_es->s_blocks_count)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Ensure we do not step over superblock */
|
/* Ensure we do not step over superblock */
|
||||||
if ((start_blk <= sbi->s_sb_block) &&
|
if ((start_blk <= sbi->s_sb_block) &&
|
||||||
(start_blk + count >= sbi->s_sb_block))
|
(start_blk + count - 1 >= sbi->s_sb_block))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -162,8 +162,7 @@ static void ext2_put_super (struct super_block * sb)
|
||||||
}
|
}
|
||||||
db_count = sbi->s_gdb_count;
|
db_count = sbi->s_gdb_count;
|
||||||
for (i = 0; i < db_count; i++)
|
for (i = 0; i < db_count; i++)
|
||||||
if (sbi->s_group_desc[i])
|
brelse(sbi->s_group_desc[i]);
|
||||||
brelse (sbi->s_group_desc[i]);
|
|
||||||
kfree(sbi->s_group_desc);
|
kfree(sbi->s_group_desc);
|
||||||
kfree(sbi->s_debts);
|
kfree(sbi->s_debts);
|
||||||
percpu_counter_destroy(&sbi->s_freeblocks_counter);
|
percpu_counter_destroy(&sbi->s_freeblocks_counter);
|
||||||
|
|
|
@ -794,7 +794,7 @@ ext2_xattr_delete_inode(struct inode *inode)
|
||||||
if (!EXT2_I(inode)->i_file_acl)
|
if (!EXT2_I(inode)->i_file_acl)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!ext2_data_block_valid(sbi, EXT2_I(inode)->i_file_acl, 0)) {
|
if (!ext2_data_block_valid(sbi, EXT2_I(inode)->i_file_acl, 1)) {
|
||||||
ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
|
ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
|
||||||
"inode %ld: xattr block %d is out of data blocks range",
|
"inode %ld: xattr block %d is out of data blocks range",
|
||||||
inode->i_ino, EXT2_I(inode)->i_file_acl);
|
inode->i_ino, EXT2_I(inode)->i_file_acl);
|
||||||
|
|
|
@ -2731,7 +2731,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
|
||||||
|
|
||||||
if (check_blim) {
|
if (check_blim) {
|
||||||
if (!dm->dqb_bsoftlimit ||
|
if (!dm->dqb_bsoftlimit ||
|
||||||
dm->dqb_curspace + dm->dqb_rsvspace < dm->dqb_bsoftlimit) {
|
dm->dqb_curspace + dm->dqb_rsvspace <= dm->dqb_bsoftlimit) {
|
||||||
dm->dqb_btime = 0;
|
dm->dqb_btime = 0;
|
||||||
clear_bit(DQ_BLKS_B, &dquot->dq_flags);
|
clear_bit(DQ_BLKS_B, &dquot->dq_flags);
|
||||||
} else if (!(di->d_fieldmask & QC_SPC_TIMER))
|
} else if (!(di->d_fieldmask & QC_SPC_TIMER))
|
||||||
|
@ -2740,7 +2740,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
|
||||||
}
|
}
|
||||||
if (check_ilim) {
|
if (check_ilim) {
|
||||||
if (!dm->dqb_isoftlimit ||
|
if (!dm->dqb_isoftlimit ||
|
||||||
dm->dqb_curinodes < dm->dqb_isoftlimit) {
|
dm->dqb_curinodes <= dm->dqb_isoftlimit) {
|
||||||
dm->dqb_itime = 0;
|
dm->dqb_itime = 0;
|
||||||
clear_bit(DQ_INODES_B, &dquot->dq_flags);
|
clear_bit(DQ_INODES_B, &dquot->dq_flags);
|
||||||
} else if (!(di->d_fieldmask & QC_INO_TIMER))
|
} else if (!(di->d_fieldmask & QC_INO_TIMER))
|
||||||
|
|
|
@ -325,6 +325,17 @@ got_block:
|
||||||
newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
|
newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
|
||||||
(sizeof(struct spaceBitmapDesc) << 3);
|
(sizeof(struct spaceBitmapDesc) << 3);
|
||||||
|
|
||||||
|
if (newblock >= sbi->s_partmaps[partition].s_partition_len) {
|
||||||
|
/*
|
||||||
|
* Ran off the end of the bitmap, and bits following are
|
||||||
|
* non-compliant (not all zero)
|
||||||
|
*/
|
||||||
|
udf_err(sb, "bitmap for partition %d corrupted (block %u marked"
|
||||||
|
" as free, partition length is %u)\n", partition,
|
||||||
|
newblock, sbi->s_partmaps[partition].s_partition_len);
|
||||||
|
goto error_return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!udf_clear_bit(bit, bh->b_data)) {
|
if (!udf_clear_bit(bit, bh->b_data)) {
|
||||||
udf_debug("bit already cleared for block %d\n", bit);
|
udf_debug("bit already cleared for block %d\n", bit);
|
||||||
goto repeat;
|
goto repeat;
|
||||||
|
|
|
@ -88,6 +88,20 @@ struct regid {
|
||||||
#define ENTITYID_FLAGS_DIRTY 0x00
|
#define ENTITYID_FLAGS_DIRTY 0x00
|
||||||
#define ENTITYID_FLAGS_PROTECTED 0x01
|
#define ENTITYID_FLAGS_PROTECTED 0x01
|
||||||
|
|
||||||
|
/* OSTA UDF 2.1.5.2 */
|
||||||
|
#define UDF_ID_COMPLIANT "*OSTA UDF Compliant"
|
||||||
|
|
||||||
|
/* OSTA UDF 2.1.5.3 */
|
||||||
|
struct domainEntityIDSuffix {
|
||||||
|
uint16_t revision;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t reserved[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OSTA UDF 2.1.5.3 */
|
||||||
|
#define ENTITYIDSUFFIX_FLAGS_HARDWRITEPROTECT 0
|
||||||
|
#define ENTITYIDSUFFIX_FLAGS_SOFTWRITEPROTECT 1
|
||||||
|
|
||||||
/* Volume Structure Descriptor (ECMA 167r3 2/9.1) */
|
/* Volume Structure Descriptor (ECMA 167r3 2/9.1) */
|
||||||
#define VSD_STD_ID_LEN 5
|
#define VSD_STD_ID_LEN 5
|
||||||
struct volStructDesc {
|
struct volStructDesc {
|
||||||
|
|
|
@ -280,6 +280,9 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attr->ia_valid & ATTR_MODE)
|
||||||
|
udf_update_extra_perms(inode, attr->ia_mode);
|
||||||
|
|
||||||
setattr_copy(inode, attr);
|
setattr_copy(inode, attr);
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -118,6 +118,9 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode)
|
||||||
iinfo->i_lenAlloc = 0;
|
iinfo->i_lenAlloc = 0;
|
||||||
iinfo->i_use = 0;
|
iinfo->i_use = 0;
|
||||||
iinfo->i_checkpoint = 1;
|
iinfo->i_checkpoint = 1;
|
||||||
|
iinfo->i_extraPerms = FE_PERM_U_CHATTR;
|
||||||
|
udf_update_extra_perms(inode, mode);
|
||||||
|
|
||||||
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
|
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
|
||||||
iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
|
iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
|
||||||
else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
|
else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
|
||||||
|
|
|
@ -45,6 +45,13 @@
|
||||||
|
|
||||||
#define EXTENT_MERGE_SIZE 5
|
#define EXTENT_MERGE_SIZE 5
|
||||||
|
|
||||||
|
#define FE_MAPPED_PERMS (FE_PERM_U_READ | FE_PERM_U_WRITE | FE_PERM_U_EXEC | \
|
||||||
|
FE_PERM_G_READ | FE_PERM_G_WRITE | FE_PERM_G_EXEC | \
|
||||||
|
FE_PERM_O_READ | FE_PERM_O_WRITE | FE_PERM_O_EXEC)
|
||||||
|
|
||||||
|
#define FE_DELETE_PERMS (FE_PERM_U_DELETE | FE_PERM_G_DELETE | \
|
||||||
|
FE_PERM_O_DELETE)
|
||||||
|
|
||||||
static umode_t udf_convert_permissions(struct fileEntry *);
|
static umode_t udf_convert_permissions(struct fileEntry *);
|
||||||
static int udf_update_inode(struct inode *, int);
|
static int udf_update_inode(struct inode *, int);
|
||||||
static int udf_sync_inode(struct inode *inode);
|
static int udf_sync_inode(struct inode *inode);
|
||||||
|
@ -1458,6 +1465,8 @@ reread:
|
||||||
else
|
else
|
||||||
inode->i_mode = udf_convert_permissions(fe);
|
inode->i_mode = udf_convert_permissions(fe);
|
||||||
inode->i_mode &= ~sbi->s_umask;
|
inode->i_mode &= ~sbi->s_umask;
|
||||||
|
iinfo->i_extraPerms = le32_to_cpu(fe->permissions) & ~FE_MAPPED_PERMS;
|
||||||
|
|
||||||
read_unlock(&sbi->s_cred_lock);
|
read_unlock(&sbi->s_cred_lock);
|
||||||
|
|
||||||
link_count = le16_to_cpu(fe->fileLinkCount);
|
link_count = le16_to_cpu(fe->fileLinkCount);
|
||||||
|
@ -1485,6 +1494,8 @@ reread:
|
||||||
iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
|
iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
|
||||||
iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
|
iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
|
||||||
iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint);
|
iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint);
|
||||||
|
iinfo->i_streamdir = 0;
|
||||||
|
iinfo->i_lenStreams = 0;
|
||||||
} else {
|
} else {
|
||||||
inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
|
inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
|
||||||
(inode->i_sb->s_blocksize_bits - 9);
|
(inode->i_sb->s_blocksize_bits - 9);
|
||||||
|
@ -1498,6 +1509,16 @@ reread:
|
||||||
iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
|
iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
|
||||||
iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
|
iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
|
||||||
iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
|
iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
|
||||||
|
|
||||||
|
/* Named streams */
|
||||||
|
iinfo->i_streamdir = (efe->streamDirectoryICB.extLength != 0);
|
||||||
|
iinfo->i_locStreamdir =
|
||||||
|
lelb_to_cpu(efe->streamDirectoryICB.extLocation);
|
||||||
|
iinfo->i_lenStreams = le64_to_cpu(efe->objectSize);
|
||||||
|
if (iinfo->i_lenStreams >= inode->i_size)
|
||||||
|
iinfo->i_lenStreams -= inode->i_size;
|
||||||
|
else
|
||||||
|
iinfo->i_lenStreams = 0;
|
||||||
}
|
}
|
||||||
inode->i_generation = iinfo->i_unique;
|
inode->i_generation = iinfo->i_unique;
|
||||||
|
|
||||||
|
@ -1619,6 +1640,23 @@ static umode_t udf_convert_permissions(struct fileEntry *fe)
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void udf_update_extra_perms(struct inode *inode, umode_t mode)
|
||||||
|
{
|
||||||
|
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UDF 2.01 sec. 3.3.3.3 Note 2:
|
||||||
|
* In Unix, delete permission tracks write
|
||||||
|
*/
|
||||||
|
iinfo->i_extraPerms &= ~FE_DELETE_PERMS;
|
||||||
|
if (mode & 0200)
|
||||||
|
iinfo->i_extraPerms |= FE_PERM_U_DELETE;
|
||||||
|
if (mode & 0020)
|
||||||
|
iinfo->i_extraPerms |= FE_PERM_G_DELETE;
|
||||||
|
if (mode & 0002)
|
||||||
|
iinfo->i_extraPerms |= FE_PERM_O_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
|
int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||||
{
|
{
|
||||||
return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
|
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)
|
||||||
((inode->i_mode & 0070) << 2) |
|
((inode->i_mode & 0070) << 2) |
|
||||||
((inode->i_mode & 0700) << 4);
|
((inode->i_mode & 0700) << 4);
|
||||||
|
|
||||||
udfperms |= (le32_to_cpu(fe->permissions) &
|
udfperms |= iinfo->i_extraPerms;
|
||||||
(FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
|
|
||||||
FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
|
|
||||||
FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
|
|
||||||
fe->permissions = cpu_to_le32(udfperms);
|
fe->permissions = cpu_to_le32(udfperms);
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0)
|
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)
|
||||||
iinfo->i_ext.i_data,
|
iinfo->i_ext.i_data,
|
||||||
inode->i_sb->s_blocksize -
|
inode->i_sb->s_blocksize -
|
||||||
sizeof(struct extendedFileEntry));
|
sizeof(struct extendedFileEntry));
|
||||||
efe->objectSize = cpu_to_le64(inode->i_size);
|
efe->objectSize =
|
||||||
|
cpu_to_le64(inode->i_size + iinfo->i_lenStreams);
|
||||||
efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
|
efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
|
||||||
|
|
||||||
|
if (iinfo->i_streamdir) {
|
||||||
|
struct long_ad *icb_lad = &efe->streamDirectoryICB;
|
||||||
|
|
||||||
|
icb_lad->extLocation =
|
||||||
|
cpu_to_lelb(iinfo->i_locStreamdir);
|
||||||
|
icb_lad->extLength =
|
||||||
|
cpu_to_le32(inode->i_sb->s_blocksize);
|
||||||
|
}
|
||||||
|
|
||||||
udf_adjust_time(iinfo, inode->i_atime);
|
udf_adjust_time(iinfo, inode->i_atime);
|
||||||
udf_adjust_time(iinfo, inode->i_mtime);
|
udf_adjust_time(iinfo, inode->i_mtime);
|
||||||
udf_adjust_time(iinfo, inode->i_ctime);
|
udf_adjust_time(iinfo, inode->i_ctime);
|
||||||
|
|
261
fs/udf/super.c
261
fs/udf/super.c
|
@ -92,10 +92,6 @@ static void udf_put_super(struct super_block *);
|
||||||
static int udf_sync_fs(struct super_block *, int);
|
static int udf_sync_fs(struct super_block *, int);
|
||||||
static int udf_remount_fs(struct super_block *, int *, char *);
|
static int udf_remount_fs(struct super_block *, int *, char *);
|
||||||
static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
|
static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
|
||||||
static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *,
|
|
||||||
struct kernel_lb_addr *);
|
|
||||||
static void udf_load_fileset(struct super_block *, struct buffer_head *,
|
|
||||||
struct kernel_lb_addr *);
|
|
||||||
static void udf_open_lvid(struct super_block *);
|
static void udf_open_lvid(struct super_block *);
|
||||||
static void udf_close_lvid(struct super_block *);
|
static void udf_close_lvid(struct super_block *);
|
||||||
static unsigned int udf_count_free(struct super_block *);
|
static unsigned int udf_count_free(struct super_block *);
|
||||||
|
@ -151,9 +147,11 @@ static struct inode *udf_alloc_inode(struct super_block *sb)
|
||||||
|
|
||||||
ei->i_unique = 0;
|
ei->i_unique = 0;
|
||||||
ei->i_lenExtents = 0;
|
ei->i_lenExtents = 0;
|
||||||
|
ei->i_lenStreams = 0;
|
||||||
ei->i_next_alloc_block = 0;
|
ei->i_next_alloc_block = 0;
|
||||||
ei->i_next_alloc_goal = 0;
|
ei->i_next_alloc_goal = 0;
|
||||||
ei->i_strat4096 = 0;
|
ei->i_strat4096 = 0;
|
||||||
|
ei->i_streamdir = 0;
|
||||||
init_rwsem(&ei->i_data_sem);
|
init_rwsem(&ei->i_data_sem);
|
||||||
ei->cached_extent.lstart = -1;
|
ei->cached_extent.lstart = -1;
|
||||||
spin_lock_init(&ei->i_extent_cache_lock);
|
spin_lock_init(&ei->i_extent_cache_lock);
|
||||||
|
@ -271,8 +269,7 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
|
||||||
int nr_groups = bitmap->s_nr_groups;
|
int nr_groups = bitmap->s_nr_groups;
|
||||||
|
|
||||||
for (i = 0; i < nr_groups; i++)
|
for (i = 0; i < nr_groups; i++)
|
||||||
if (bitmap->s_block_bitmap[i])
|
brelse(bitmap->s_block_bitmap[i]);
|
||||||
brelse(bitmap->s_block_bitmap[i]);
|
|
||||||
|
|
||||||
kvfree(bitmap);
|
kvfree(bitmap);
|
||||||
}
|
}
|
||||||
|
@ -646,16 +643,67 @@ out_unlock:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */
|
/*
|
||||||
/* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
|
* Check VSD descriptor. Returns -1 in case we are at the end of volume
|
||||||
static loff_t udf_check_vsd(struct super_block *sb)
|
* recognition area, 0 if the descriptor is valid but non-interesting, 1 if
|
||||||
|
* we found one of NSR descriptors we are looking for.
|
||||||
|
*/
|
||||||
|
static int identify_vsd(const struct volStructDesc *vsd)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!memcmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {
|
||||||
|
switch (vsd->structType) {
|
||||||
|
case 0:
|
||||||
|
udf_debug("ISO9660 Boot Record found\n");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
udf_debug("ISO9660 Primary Volume Descriptor found\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
udf_debug("ISO9660 Volume Partition Descriptor found\n");
|
||||||
|
break;
|
||||||
|
case 255:
|
||||||
|
udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
udf_debug("ISO9660 VRS (%u) found\n", vsd->structType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
|
||||||
|
; /* ret = 0 */
|
||||||
|
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
|
||||||
|
ret = 1;
|
||||||
|
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
|
||||||
|
ret = 1;
|
||||||
|
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BOOT2, VSD_STD_ID_LEN))
|
||||||
|
; /* ret = 0 */
|
||||||
|
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_CDW02, VSD_STD_ID_LEN))
|
||||||
|
; /* ret = 0 */
|
||||||
|
else {
|
||||||
|
/* TEA01 or invalid id : end of volume recognition area */
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check Volume Structure Descriptors (ECMA 167 2/9.1)
|
||||||
|
* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1)
|
||||||
|
* @return 1 if NSR02 or NSR03 found,
|
||||||
|
* -1 if first sector read error, 0 otherwise
|
||||||
|
*/
|
||||||
|
static int udf_check_vsd(struct super_block *sb)
|
||||||
{
|
{
|
||||||
struct volStructDesc *vsd = NULL;
|
struct volStructDesc *vsd = NULL;
|
||||||
loff_t sector = VSD_FIRST_SECTOR_OFFSET;
|
loff_t sector = VSD_FIRST_SECTOR_OFFSET;
|
||||||
int sectorsize;
|
int sectorsize;
|
||||||
struct buffer_head *bh = NULL;
|
struct buffer_head *bh = NULL;
|
||||||
int nsr02 = 0;
|
int nsr = 0;
|
||||||
int nsr03 = 0;
|
|
||||||
struct udf_sb_info *sbi;
|
struct udf_sb_info *sbi;
|
||||||
|
|
||||||
sbi = UDF_SB(sb);
|
sbi = UDF_SB(sb);
|
||||||
|
@ -679,71 +727,36 @@ static loff_t udf_check_vsd(struct super_block *sb)
|
||||||
* activity. This actually happened with uninitialised SSD partitions
|
* activity. This actually happened with uninitialised SSD partitions
|
||||||
* (all 0xFF) before the check for the limit and all valid IDs were
|
* (all 0xFF) before the check for the limit and all valid IDs were
|
||||||
* added */
|
* added */
|
||||||
for (; !nsr02 && !nsr03 && sector < VSD_MAX_SECTOR_OFFSET;
|
for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) {
|
||||||
sector += sectorsize) {
|
|
||||||
/* Read a block */
|
/* Read a block */
|
||||||
bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
|
bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
|
||||||
if (!bh)
|
if (!bh)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Look for ISO descriptors */
|
|
||||||
vsd = (struct volStructDesc *)(bh->b_data +
|
vsd = (struct volStructDesc *)(bh->b_data +
|
||||||
(sector & (sb->s_blocksize - 1)));
|
(sector & (sb->s_blocksize - 1)));
|
||||||
|
nsr = identify_vsd(vsd);
|
||||||
if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001,
|
/* Found NSR or end? */
|
||||||
VSD_STD_ID_LEN)) {
|
if (nsr) {
|
||||||
switch (vsd->structType) {
|
|
||||||
case 0:
|
|
||||||
udf_debug("ISO9660 Boot Record found\n");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
udf_debug("ISO9660 Primary Volume Descriptor found\n");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
udf_debug("ISO9660 Volume Partition Descriptor found\n");
|
|
||||||
break;
|
|
||||||
case 255:
|
|
||||||
udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
udf_debug("ISO9660 VRS (%u) found\n",
|
|
||||||
vsd->structType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01,
|
|
||||||
VSD_STD_ID_LEN))
|
|
||||||
; /* nothing */
|
|
||||||
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01,
|
|
||||||
VSD_STD_ID_LEN)) {
|
|
||||||
brelse(bh);
|
|
||||||
break;
|
|
||||||
} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02,
|
|
||||||
VSD_STD_ID_LEN))
|
|
||||||
nsr02 = sector;
|
|
||||||
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03,
|
|
||||||
VSD_STD_ID_LEN))
|
|
||||||
nsr03 = sector;
|
|
||||||
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BOOT2,
|
|
||||||
VSD_STD_ID_LEN))
|
|
||||||
; /* nothing */
|
|
||||||
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CDW02,
|
|
||||||
VSD_STD_ID_LEN))
|
|
||||||
; /* nothing */
|
|
||||||
else {
|
|
||||||
/* invalid id : end of volume recognition area */
|
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Special handling for improperly formatted VRS (e.g., Win10)
|
||||||
|
* where components are separated by 2048 bytes even though
|
||||||
|
* sectors are 4K
|
||||||
|
*/
|
||||||
|
if (sb->s_blocksize == 4096) {
|
||||||
|
nsr = identify_vsd(vsd + 1);
|
||||||
|
/* Ignore unknown IDs... */
|
||||||
|
if (nsr < 0)
|
||||||
|
nsr = 0;
|
||||||
|
}
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsr03)
|
if (nsr > 0)
|
||||||
return nsr03;
|
return 1;
|
||||||
else if (nsr02)
|
|
||||||
return nsr02;
|
|
||||||
else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) ==
|
else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) ==
|
||||||
VSD_FIRST_SECTOR_OFFSET)
|
VSD_FIRST_SECTOR_OFFSET)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -751,34 +764,82 @@ static loff_t udf_check_vsd(struct super_block *sb)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int udf_verify_domain_identifier(struct super_block *sb,
|
||||||
|
struct regid *ident, char *dname)
|
||||||
|
{
|
||||||
|
struct domainEntityIDSuffix *suffix;
|
||||||
|
|
||||||
|
if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) {
|
||||||
|
udf_warn(sb, "Not OSTA UDF compliant %s descriptor.\n", dname);
|
||||||
|
goto force_ro;
|
||||||
|
}
|
||||||
|
if (ident->flags & (1 << ENTITYID_FLAGS_DIRTY)) {
|
||||||
|
udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor.\n",
|
||||||
|
dname);
|
||||||
|
goto force_ro;
|
||||||
|
}
|
||||||
|
suffix = (struct domainEntityIDSuffix *)ident->identSuffix;
|
||||||
|
if (suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_HARDWRITEPROTECT) ||
|
||||||
|
suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_SOFTWRITEPROTECT)) {
|
||||||
|
if (!sb_rdonly(sb)) {
|
||||||
|
udf_warn(sb, "Descriptor for %s marked write protected."
|
||||||
|
" Forcing read only mount.\n", dname);
|
||||||
|
}
|
||||||
|
goto force_ro;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
force_ro:
|
||||||
|
if (!sb_rdonly(sb))
|
||||||
|
return -EACCES;
|
||||||
|
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int udf_load_fileset(struct super_block *sb, struct fileSetDesc *fset,
|
||||||
|
struct kernel_lb_addr *root)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = udf_verify_domain_identifier(sb, &fset->domainIdent, "file set");
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
|
||||||
|
UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum);
|
||||||
|
|
||||||
|
udf_debug("Rootdir at block=%u, partition=%u\n",
|
||||||
|
root->logicalBlockNum, root->partitionReferenceNum);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int udf_find_fileset(struct super_block *sb,
|
static int udf_find_fileset(struct super_block *sb,
|
||||||
struct kernel_lb_addr *fileset,
|
struct kernel_lb_addr *fileset,
|
||||||
struct kernel_lb_addr *root)
|
struct kernel_lb_addr *root)
|
||||||
{
|
{
|
||||||
struct buffer_head *bh = NULL;
|
struct buffer_head *bh = NULL;
|
||||||
uint16_t ident;
|
uint16_t ident;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (fileset->logicalBlockNum != 0xFFFFFFFF ||
|
if (fileset->logicalBlockNum == 0xFFFFFFFF &&
|
||||||
fileset->partitionReferenceNum != 0xFFFF) {
|
fileset->partitionReferenceNum == 0xFFFF)
|
||||||
bh = udf_read_ptagged(sb, fileset, 0, &ident);
|
return -EINVAL;
|
||||||
|
|
||||||
if (!bh) {
|
bh = udf_read_ptagged(sb, fileset, 0, &ident);
|
||||||
return 1;
|
if (!bh)
|
||||||
} else if (ident != TAG_IDENT_FSD) {
|
return -EIO;
|
||||||
brelse(bh);
|
if (ident != TAG_IDENT_FSD) {
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
udf_debug("Fileset at block=%u, partition=%u\n",
|
|
||||||
fileset->logicalBlockNum,
|
|
||||||
fileset->partitionReferenceNum);
|
|
||||||
|
|
||||||
UDF_SB(sb)->s_partition = fileset->partitionReferenceNum;
|
|
||||||
udf_load_fileset(sb, bh, root);
|
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
return 0;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
|
udf_debug("Fileset at block=%u, partition=%u\n",
|
||||||
|
fileset->logicalBlockNum, fileset->partitionReferenceNum);
|
||||||
|
|
||||||
|
UDF_SB(sb)->s_partition = fileset->partitionReferenceNum;
|
||||||
|
ret = udf_load_fileset(sb, (struct fileSetDesc *)bh->b_data, root);
|
||||||
|
brelse(bh);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -794,9 +855,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
uint16_t ident;
|
uint16_t ident;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
#ifdef UDFFS_DEBUG
|
|
||||||
struct timestamp *ts;
|
struct timestamp *ts;
|
||||||
#endif
|
|
||||||
|
|
||||||
outstr = kmalloc(128, GFP_NOFS);
|
outstr = kmalloc(128, GFP_NOFS);
|
||||||
if (!outstr)
|
if (!outstr)
|
||||||
|
@ -817,13 +876,10 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
|
||||||
|
|
||||||
udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
|
udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
|
||||||
pvoldesc->recordingDateAndTime);
|
pvoldesc->recordingDateAndTime);
|
||||||
#ifdef UDFFS_DEBUG
|
|
||||||
ts = &pvoldesc->recordingDateAndTime;
|
ts = &pvoldesc->recordingDateAndTime;
|
||||||
udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n",
|
udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n",
|
||||||
le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
|
le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
|
||||||
ts->minute, le16_to_cpu(ts->typeAndTimezone));
|
ts->minute, le16_to_cpu(ts->typeAndTimezone));
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32);
|
ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -939,21 +995,6 @@ static int udf_load_metadata_files(struct super_block *sb, int partition,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
|
|
||||||
struct kernel_lb_addr *root)
|
|
||||||
{
|
|
||||||
struct fileSetDesc *fset;
|
|
||||||
|
|
||||||
fset = (struct fileSetDesc *)bh->b_data;
|
|
||||||
|
|
||||||
*root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
|
|
||||||
|
|
||||||
UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum);
|
|
||||||
|
|
||||||
udf_debug("Rootdir at block=%u, partition=%u\n",
|
|
||||||
root->logicalBlockNum, root->partitionReferenceNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
int udf_compute_nr_groups(struct super_block *sb, u32 partition)
|
int udf_compute_nr_groups(struct super_block *sb, u32 partition)
|
||||||
{
|
{
|
||||||
struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
|
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)
|
||||||
* PHYSICAL partitions are already set up
|
* PHYSICAL partitions are already set up
|
||||||
*/
|
*/
|
||||||
type1_idx = i;
|
type1_idx = i;
|
||||||
#ifdef UDFFS_DEBUG
|
|
||||||
map = NULL; /* supress 'maybe used uninitialized' warning */
|
map = NULL; /* supress 'maybe used uninitialized' warning */
|
||||||
#endif
|
|
||||||
for (i = 0; i < sbi->s_partitions; i++) {
|
for (i = 0; i < sbi->s_partitions; i++) {
|
||||||
map = &sbi->s_partmaps[i];
|
map = &sbi->s_partmaps[i];
|
||||||
|
|
||||||
|
@ -1364,6 +1403,10 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
|
||||||
goto out_bh;
|
goto out_bh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = udf_verify_domain_identifier(sb, &lvd->domainIdent,
|
||||||
|
"logical volume");
|
||||||
|
if (ret)
|
||||||
|
goto out_bh;
|
||||||
ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
|
ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_bh;
|
goto out_bh;
|
||||||
|
@ -1915,7 +1958,7 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
|
||||||
int silent, struct kernel_lb_addr *fileset)
|
int silent, struct kernel_lb_addr *fileset)
|
||||||
{
|
{
|
||||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||||
loff_t nsr_off;
|
int nsr = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!sb_set_blocksize(sb, uopt->blocksize)) {
|
if (!sb_set_blocksize(sb, uopt->blocksize)) {
|
||||||
|
@ -1926,13 +1969,13 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
|
||||||
sbi->s_last_block = uopt->lastblock;
|
sbi->s_last_block = uopt->lastblock;
|
||||||
if (!uopt->novrs) {
|
if (!uopt->novrs) {
|
||||||
/* Check that it is NSR02 compliant */
|
/* Check that it is NSR02 compliant */
|
||||||
nsr_off = udf_check_vsd(sb);
|
nsr = udf_check_vsd(sb);
|
||||||
if (!nsr_off) {
|
if (!nsr) {
|
||||||
if (!silent)
|
if (!silent)
|
||||||
udf_warn(sb, "No VRS found\n");
|
udf_warn(sb, "No VRS found\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (nsr_off == -1)
|
if (nsr == -1)
|
||||||
udf_debug("Failed to read sector at offset %d. "
|
udf_debug("Failed to read sector at offset %d. "
|
||||||
"Assuming open disc. Skipping validity "
|
"Assuming open disc. Skipping validity "
|
||||||
"check\n", VSD_FIRST_SECTOR_OFFSET);
|
"check\n", VSD_FIRST_SECTOR_OFFSET);
|
||||||
|
@ -2216,9 +2259,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
|
||||||
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
|
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (udf_find_fileset(sb, &fileset, &rootdir)) {
|
ret = udf_find_fileset(sb, &fileset, &rootdir);
|
||||||
|
if (ret < 0) {
|
||||||
udf_warn(sb, "No fileset found\n");
|
udf_warn(sb, "No fileset found\n");
|
||||||
ret = -EINVAL;
|
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,16 +38,20 @@ struct udf_inode_info {
|
||||||
__u32 i_next_alloc_block;
|
__u32 i_next_alloc_block;
|
||||||
__u32 i_next_alloc_goal;
|
__u32 i_next_alloc_goal;
|
||||||
__u32 i_checkpoint;
|
__u32 i_checkpoint;
|
||||||
|
__u32 i_extraPerms;
|
||||||
unsigned i_alloc_type : 3;
|
unsigned i_alloc_type : 3;
|
||||||
unsigned i_efe : 1; /* extendedFileEntry */
|
unsigned i_efe : 1; /* extendedFileEntry */
|
||||||
unsigned i_use : 1; /* unallocSpaceEntry */
|
unsigned i_use : 1; /* unallocSpaceEntry */
|
||||||
unsigned i_strat4096 : 1;
|
unsigned i_strat4096 : 1;
|
||||||
unsigned reserved : 26;
|
unsigned i_streamdir : 1;
|
||||||
|
unsigned reserved : 25;
|
||||||
union {
|
union {
|
||||||
struct short_ad *i_sad;
|
struct short_ad *i_sad;
|
||||||
struct long_ad *i_lad;
|
struct long_ad *i_lad;
|
||||||
__u8 *i_data;
|
__u8 *i_data;
|
||||||
} i_ext;
|
} i_ext;
|
||||||
|
struct kernel_lb_addr i_locStreamdir;
|
||||||
|
__u64 i_lenStreams;
|
||||||
struct rw_semaphore i_data_sem;
|
struct rw_semaphore i_data_sem;
|
||||||
struct udf_ext_cache cached_extent;
|
struct udf_ext_cache cached_extent;
|
||||||
/* Spinlock for protecting extent cache */
|
/* Spinlock for protecting extent cache */
|
||||||
|
|
|
@ -31,16 +31,8 @@ extern __printf(3, 4) void _udf_warn(struct super_block *sb,
|
||||||
#define udf_info(fmt, ...) \
|
#define udf_info(fmt, ...) \
|
||||||
pr_info("INFO " fmt, ##__VA_ARGS__)
|
pr_info("INFO " fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
#undef UDFFS_DEBUG
|
|
||||||
|
|
||||||
#ifdef UDFFS_DEBUG
|
|
||||||
#define udf_debug(fmt, ...) \
|
#define udf_debug(fmt, ...) \
|
||||||
printk(KERN_DEBUG pr_fmt("%s:%d:%s: " fmt), \
|
pr_debug("%s:%d:%s: " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||||
__FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define udf_debug(fmt, ...) \
|
|
||||||
no_printk(fmt, ##__VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
|
#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
|
||||||
#define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) )
|
#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 *,
|
||||||
struct kernel_lb_addr *, uint32_t *, int);
|
struct kernel_lb_addr *, uint32_t *, int);
|
||||||
extern int8_t udf_current_aext(struct inode *, struct extent_position *,
|
extern int8_t udf_current_aext(struct inode *, struct extent_position *,
|
||||||
struct kernel_lb_addr *, uint32_t *, int);
|
struct kernel_lb_addr *, uint32_t *, int);
|
||||||
|
extern void udf_update_extra_perms(struct inode *inode, umode_t mode);
|
||||||
|
|
||||||
/* misc.c */
|
/* misc.c */
|
||||||
extern struct buffer_head *udf_tgetblk(struct super_block *sb,
|
extern struct buffer_head *udf_tgetblk(struct super_block *sb,
|
||||||
|
|
|
@ -22,7 +22,7 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
|
||||||
/* i_mutex must being held */
|
/* i_mutex must being held */
|
||||||
static inline bool is_quota_modification(struct inode *inode, struct iattr *ia)
|
static inline bool is_quota_modification(struct inode *inode, struct iattr *ia)
|
||||||
{
|
{
|
||||||
return (ia->ia_valid & ATTR_SIZE && ia->ia_size != inode->i_size) ||
|
return (ia->ia_valid & ATTR_SIZE) ||
|
||||||
(ia->ia_valid & ATTR_UID && !uid_eq(ia->ia_uid, inode->i_uid)) ||
|
(ia->ia_valid & ATTR_UID && !uid_eq(ia->ia_uid, inode->i_uid)) ||
|
||||||
(ia->ia_valid & ATTR_GID && !gid_eq(ia->ia_gid, inode->i_gid));
|
(ia->ia_valid & ATTR_GID && !gid_eq(ia->ia_gid, inode->i_gid));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue