Commit e64433d5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'filesystems_for_v4.20-rc1' of...

Merge tag 'filesystems_for_v4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull ext2 and udf updates from Jan Kara:
 "Small ext2 cleanups and a couple of udf fixes"

* tag 'filesystems_for_v4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  ext2: remove redundant building macro check
  udf: Drop pack pragma from udf_sb.h
  udf: Drop freed bitmap / table support
  udf: Fix crash during mount
  udf: Prevent write-unsupported filesystem to be remounted read-write
  ext2: cache NULL when both default_acl and acl are NULL
  udf: remove unused variables group_start and nr_groups
parents 79257514 2aad26fa
......@@ -256,11 +256,15 @@ ext2_init_acl(struct inode *inode, struct inode *dir)
if (default_acl) {
error = __ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
posix_acl_release(default_acl);
} else {
inode->i_default_acl = NULL;
}
if (acl) {
if (!error)
error = __ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
posix_acl_release(acl);
} else {
inode->i_acl = NULL;
}
return error;
}
......@@ -390,11 +390,7 @@ struct ext2_inode {
#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
#define EXT2_MOUNT_RESERVATION 0x080000 /* Preallocation */
#ifdef CONFIG_FS_DAX
#define EXT2_MOUNT_DAX 0x100000 /* Direct Access */
#else
#define EXT2_MOUNT_DAX 0
#endif
#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
......
......@@ -309,20 +309,17 @@ static int ext2_show_options(struct seq_file *seq, struct dentry *root)
if (test_opt(sb, NOBH))
seq_puts(seq, ",nobh");
#if defined(CONFIG_QUOTA)
if (sbi->s_mount_opt & EXT2_MOUNT_USRQUOTA)
seq_puts(seq, ",usrquota");
if (sbi->s_mount_opt & EXT2_MOUNT_GRPQUOTA)
seq_puts(seq, ",grpquota");
#endif
#ifdef CONFIG_FS_DAX
if (sbi->s_mount_opt & EXT2_MOUNT_XIP)
seq_puts(seq, ",xip");
if (sbi->s_mount_opt & EXT2_MOUNT_DAX)
seq_puts(seq, ",dax");
#endif
if (!test_opt(sb, RESERVATION))
seq_puts(seq, ",noreservation");
......
......@@ -175,8 +175,8 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
{
struct udf_sb_info *sbi = UDF_SB(sb);
int alloc_count = 0;
int bit, block, block_group, group_start;
int nr_groups, bitmap_nr;
int bit, block, block_group;
int bitmap_nr;
struct buffer_head *bh;
__u32 part_len;
......@@ -189,10 +189,8 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
block_count = part_len - first_block;
do {
nr_groups = udf_compute_nr_groups(sb, partition);
block = first_block + (sizeof(struct spaceBitmapDesc) << 3);
block_group = block >> (sb->s_blocksize_bits + 3);
group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
if (bitmap_nr < 0)
......@@ -652,12 +650,6 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,
} else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
udf_table_free_blocks(sb, map->s_uspace.s_table,
bloc, offset, count);
} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) {
udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap,
bloc, offset, count);
} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) {
udf_table_free_blocks(sb, map->s_fspace.s_table,
bloc, offset, count);
}
if (inode) {
......@@ -684,16 +676,6 @@ inline int udf_prealloc_blocks(struct super_block *sb,
map->s_uspace.s_table,
partition, first_block,
block_count);
else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
allocated = udf_bitmap_prealloc_blocks(sb,
map->s_fspace.s_bitmap,
partition, first_block,
block_count);
else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
allocated = udf_table_prealloc_blocks(sb,
map->s_fspace.s_table,
partition, first_block,
block_count);
else
return 0;
......@@ -717,14 +699,6 @@ inline udf_pblk_t udf_new_block(struct super_block *sb,
block = udf_table_new_block(sb,
map->s_uspace.s_table,
partition, goal, err);
else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
block = udf_bitmap_new_block(sb,
map->s_fspace.s_bitmap,
partition, goal, err);
else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
block = udf_table_new_block(sb,
map->s_fspace.s_table,
partition, goal, err);
else {
*err = -EIO;
return 0;
......
......@@ -290,12 +290,8 @@ static void udf_free_partition(struct udf_part_map *map)
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
iput(map->s_uspace.s_table);
if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
iput(map->s_fspace.s_table);
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
udf_sb_free_bitmap(map->s_uspace.s_bitmap);
if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
udf_sb_free_bitmap(map->s_fspace.s_bitmap);
if (map->s_partition_type == UDF_SPARABLE_MAP15)
for (i = 0; i < 4; i++)
brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
......@@ -613,14 +609,11 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
struct udf_options uopt;
struct udf_sb_info *sbi = UDF_SB(sb);
int error = 0;
struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb);
if (!(*flags & SB_RDONLY) && UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
return -EACCES;
sync_filesystem(sb);
if (lvidiu) {
int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & SB_RDONLY))
return -EACCES;
}
uopt.flags = sbi->s_flags;
uopt.uid = sbi->s_uid;
......@@ -988,12 +981,62 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
return bitmap;
}
static int check_partition_desc(struct super_block *sb,
struct partitionDesc *p,
struct udf_part_map *map)
{
bool umap, utable, fmap, ftable;
struct partitionHeaderDesc *phd;
switch (le32_to_cpu(p->accessType)) {
case PD_ACCESS_TYPE_READ_ONLY:
case PD_ACCESS_TYPE_WRITE_ONCE:
case PD_ACCESS_TYPE_REWRITABLE:
case PD_ACCESS_TYPE_NONE:
goto force_ro;
}
/* No Partition Header Descriptor? */
if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) &&
strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
goto force_ro;
phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
utable = phd->unallocSpaceTable.extLength;
umap = phd->unallocSpaceBitmap.extLength;
ftable = phd->freedSpaceTable.extLength;
fmap = phd->freedSpaceBitmap.extLength;
/* No allocation info? */
if (!utable && !umap && !ftable && !fmap)
goto force_ro;
/* We don't support blocks that require erasing before overwrite */
if (ftable || fmap)
goto force_ro;
/* UDF 2.60: 2.3.3 - no mixing of tables & bitmaps, no VAT. */
if (utable && umap)
goto force_ro;
if (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
map->s_partition_type == UDF_VIRTUAL_MAP20)
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_fill_partdesc_info(struct super_block *sb,
struct partitionDesc *p, int p_index)
{
struct udf_part_map *map;
struct udf_sb_info *sbi = UDF_SB(sb);
struct partitionHeaderDesc *phd;
int err;
map = &sbi->s_partmaps[p_index];
......@@ -1013,8 +1056,16 @@ static int udf_fill_partdesc_info(struct super_block *sb,
p_index, map->s_partition_type,
map->s_partition_root, map->s_partition_len);
if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) &&
strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
err = check_partition_desc(sb, p, map);
if (err)
return err;
/*
* Skip loading allocation info it we cannot ever write to the fs.
* This is a correctness thing as we may have decided to force ro mount
* to avoid allocation info we don't support.
*/
if (UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
return 0;
phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
......@@ -1050,40 +1101,6 @@ static int udf_fill_partdesc_info(struct super_block *sb,
p_index, bitmap->s_extPosition);
}
if (phd->partitionIntegrityTable.extLength)
udf_debug("partitionIntegrityTable (part %d)\n", p_index);
if (phd->freedSpaceTable.extLength) {
struct kernel_lb_addr loc = {
.logicalBlockNum = le32_to_cpu(
phd->freedSpaceTable.extPosition),
.partitionReferenceNum = p_index,
};
struct inode *inode;
inode = udf_iget_special(sb, &loc);
if (IS_ERR(inode)) {
udf_debug("cannot load freedSpaceTable (part %d)\n",
p_index);
return PTR_ERR(inode);
}
map->s_fspace.s_table = inode;
map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE;
udf_debug("freedSpaceTable (part %d) @ %lu\n",
p_index, map->s_fspace.s_table->i_ino);
}
if (phd->freedSpaceBitmap.extLength) {
struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
if (!bitmap)
return -ENOMEM;
map->s_fspace.s_bitmap = bitmap;
bitmap->s_extPosition = le32_to_cpu(
phd->freedSpaceBitmap.extPosition);
map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP;
udf_debug("freedSpaceBitmap (part %d) @ %u\n",
p_index, bitmap->s_extPosition);
}
return 0;
}
......@@ -1257,6 +1274,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
ret = -EACCES;
goto out_bh;
}
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
ret = udf_load_vat(sb, i, type1_idx);
if (ret < 0)
goto out_bh;
......@@ -2155,10 +2173,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
UDF_MAX_READ_VERSION);
ret = -EINVAL;
goto error_out;
} else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION &&
!sb_rdonly(sb)) {
ret = -EACCES;
goto error_out;
} else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) {
if (!sb_rdonly(sb)) {
ret = -EACCES;
goto error_out;
}
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
}
sbi->s_udfrev = minUDFWriteRev;
......@@ -2176,10 +2196,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
}
if (sbi->s_partmaps[sbi->s_partition].s_partition_flags &
UDF_PART_FLAG_READ_ONLY &&
!sb_rdonly(sb)) {
ret = -EACCES;
goto error_out;
UDF_PART_FLAG_READ_ONLY) {
if (!sb_rdonly(sb)) {
ret = -EACCES;
goto error_out;
}
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
}
if (udf_find_fileset(sb, &fileset, &rootdir)) {
......@@ -2433,10 +2455,6 @@ static unsigned int udf_count_free(struct super_block *sb)
accum += udf_count_free_bitmap(sb,
map->s_uspace.s_bitmap);
}
if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) {
accum += udf_count_free_bitmap(sb,
map->s_fspace.s_bitmap);
}
if (accum)
return accum;
......@@ -2444,11 +2462,6 @@ static unsigned int udf_count_free(struct super_block *sb)
accum += udf_count_free_table(sb,
map->s_uspace.s_table);
}
if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) {
accum += udf_count_free_table(sb,
map->s_fspace.s_table);
}
return accum;
}
......
......@@ -30,11 +30,11 @@
#define UDF_FLAG_LASTBLOCK_SET 16
#define UDF_FLAG_BLOCKSIZE_SET 17
#define UDF_FLAG_INCONSISTENT 18
#define UDF_FLAG_RW_INCOMPAT 19 /* Set when we find RW incompatible
* feature */
#define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001
#define UDF_PART_FLAG_UNALLOC_TABLE 0x0002
#define UDF_PART_FLAG_FREED_BITMAP 0x0004
#define UDF_PART_FLAG_FREED_TABLE 0x0008
#define UDF_PART_FLAG_READ_ONLY 0x0010
#define UDF_PART_FLAG_WRITE_ONCE 0x0020
#define UDF_PART_FLAG_REWRITABLE 0x0040
......@@ -50,8 +50,6 @@
#define UDF_INVALID_MODE ((umode_t)-1)
#pragma pack(1) /* XXX(hch): Why? This file just defines in-core structures */
#define MF_DUPLICATE_MD 0x01
#define MF_MIRROR_FE_LOADED 0x02
......@@ -93,10 +91,6 @@ struct udf_part_map {
struct udf_bitmap *s_bitmap;
struct inode *s_table;
} s_uspace;
union {
struct udf_bitmap *s_bitmap;
struct inode *s_table;
} s_fspace;
__u32 s_partition_root;
__u32 s_partition_len;
__u16 s_partition_type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment