diff options
-rw-r--r-- | Documentation/filesystems/udf.txt | 2 | ||||
-rw-r--r-- | fs/udf/balloc.c | 150 | ||||
-rw-r--r-- | fs/udf/dir.c | 14 | ||||
-rw-r--r-- | fs/udf/directory.c | 38 | ||||
-rw-r--r-- | fs/udf/ecma_167.h | 416 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 9 | ||||
-rw-r--r-- | fs/udf/inode.c | 213 | ||||
-rw-r--r-- | fs/udf/misc.c | 29 | ||||
-rw-r--r-- | fs/udf/namei.c | 86 | ||||
-rw-r--r-- | fs/udf/osta_udf.h | 22 | ||||
-rw-r--r-- | fs/udf/partition.c | 2 | ||||
-rw-r--r-- | fs/udf/super.c | 605 | ||||
-rw-r--r-- | fs/udf/truncate.c | 44 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 6 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 9 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 57 | ||||
-rw-r--r-- | fs/udf/udfend.h | 28 | ||||
-rw-r--r-- | fs/udf/udftime.c | 6 | ||||
-rw-r--r-- | fs/udf/unicode.c | 62 |
19 files changed, 930 insertions, 868 deletions
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt index fde829a756e6..902b95d0ee51 100644 --- a/Documentation/filesystems/udf.txt +++ b/Documentation/filesystems/udf.txt @@ -24,6 +24,8 @@ The following mount options are supported: gid= Set the default group. umask= Set the default umask. + mode= Set the default file permissions. + dmode= Set the default directory permissions. uid= Set the default user. bs= Set the block size. unhide Show otherwise hidden files. diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 2bb788a2acb1..e48e9a3af763 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -87,12 +87,12 @@ static int read_block_bitmap(struct super_block *sb, { struct buffer_head *bh = NULL; int retval = 0; - kernel_lb_addr loc; + struct kernel_lb_addr loc; loc.logicalBlockNum = bitmap->s_extPosition; loc.partitionReferenceNum = UDF_SB(sb)->s_partition; - bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block)); + bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block)); if (!bh) retval = -EIO; @@ -140,27 +140,29 @@ static inline int load_block_bitmap(struct super_block *sb, return slot; } -static bool udf_add_free_space(struct udf_sb_info *sbi, - u16 partition, u32 cnt) +static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt) { + struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDesc *lvid; - if (sbi->s_lvid_bh == NULL) - return false; + if (!sbi->s_lvid_bh) + return; lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; le32_add_cpu(&lvid->freeSpaceTable[partition], cnt); - return true; + udf_updated_lvid(sb); } static void udf_bitmap_free_blocks(struct super_block *sb, struct inode *inode, struct udf_bitmap *bitmap, - kernel_lb_addr bloc, uint32_t offset, + struct kernel_lb_addr *bloc, + uint32_t offset, uint32_t count) { struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = NULL; + struct udf_part_map *partmap; unsigned long block; unsigned long block_group; unsigned long bit; @@ -169,17 +171,17 @@ static void udf_bitmap_free_blocks(struct super_block *sb, unsigned long overflow; mutex_lock(&sbi->s_alloc_mutex); - if (bloc.logicalBlockNum < 0 || - (bloc.logicalBlockNum + count) > - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) { + partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; + if (bloc->logicalBlockNum < 0 || + (bloc->logicalBlockNum + count) > + partmap->s_partition_len) { udf_debug("%d < %d || %d + %d > %d\n", - bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, - sbi->s_partmaps[bloc.partitionReferenceNum]. - s_partition_len); + bloc->logicalBlockNum, 0, bloc->logicalBlockNum, + count, partmap->s_partition_len); goto error_return; } - block = bloc.logicalBlockNum + offset + + block = bloc->logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3); do { @@ -207,7 +209,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb, } else { if (inode) vfs_dq_free_block(inode, 1); - udf_add_free_space(sbi, sbi->s_partition, 1); + udf_add_free_space(sb, sbi->s_partition, 1); } } mark_buffer_dirty(bh); @@ -218,9 +220,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb, } while (overflow); error_return: - sb->s_dirt = 1; - if (sbi->s_lvid_bh) - mark_buffer_dirty(sbi->s_lvid_bh); mutex_unlock(&sbi->s_alloc_mutex); } @@ -277,9 +276,7 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, } while (block_count > 0); out: - if (udf_add_free_space(sbi, partition, -alloc_count)) - mark_buffer_dirty(sbi->s_lvid_bh); - sb->s_dirt = 1; + udf_add_free_space(sb, partition, -alloc_count); mutex_unlock(&sbi->s_alloc_mutex); return alloc_count; } @@ -409,9 +406,7 @@ got_block: mark_buffer_dirty(bh); - if (udf_add_free_space(sbi, partition, -1)) - mark_buffer_dirty(sbi->s_lvid_bh); - sb->s_dirt = 1; + udf_add_free_space(sb, partition, -1); mutex_unlock(&sbi->s_alloc_mutex); *err = 0; return newblock; @@ -425,26 +420,28 @@ error_return: static void udf_table_free_blocks(struct super_block *sb, struct inode *inode, struct inode *table, - kernel_lb_addr bloc, uint32_t offset, + struct kernel_lb_addr *bloc, + uint32_t offset, uint32_t count) { struct udf_sb_info *sbi = UDF_SB(sb); + struct udf_part_map *partmap; uint32_t start, end; uint32_t elen; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; struct extent_position oepos, epos; int8_t etype; int i; struct udf_inode_info *iinfo; mutex_lock(&sbi->s_alloc_mutex); - if (bloc.logicalBlockNum < 0 || - (bloc.logicalBlockNum + count) > - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) { + partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; + if (bloc->logicalBlockNum < 0 || + (bloc->logicalBlockNum + count) > + partmap->s_partition_len) { udf_debug("%d < %d || %d + %d > %d\n", bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, - sbi->s_partmaps[bloc.partitionReferenceNum]. - s_partition_len); + partmap->s_partition_len); goto error_return; } @@ -453,11 +450,10 @@ static void udf_table_free_blocks(struct super_block *sb, could occure, but.. oh well */ if (inode) vfs_dq_free_block(inode, count); - if (udf_add_free_space(sbi, sbi->s_partition, count)) - mark_buffer_dirty(sbi->s_lvid_bh); + udf_add_free_space(sb, sbi->s_partition, count); - start = bloc.logicalBlockNum + offset; - end = bloc.logicalBlockNum + offset + count - 1; + start = bloc->logicalBlockNum + offset; + end = bloc->logicalBlockNum + offset + count - 1; epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry); elen = 0; @@ -483,7 +479,7 @@ static void udf_table_free_blocks(struct super_block *sb, start += count; count = 0; } - udf_write_aext(table, &oepos, eloc, elen, 1); + udf_write_aext(table, &oepos, &eloc, elen, 1); } else if (eloc.logicalBlockNum == (end + 1)) { if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) { @@ -502,7 +498,7 @@ static void udf_table_free_blocks(struct super_block *sb, end -= count; count = 0; } - udf_write_aext(table, &oepos, eloc, elen, 1); + udf_write_aext(table, &oepos, &eloc, elen, 1); } if (epos.bh != oepos.bh) { @@ -532,8 +528,8 @@ static void udf_table_free_blocks(struct super_block *sb, */ int adsize; - short_ad *sad = NULL; - long_ad *lad = NULL; + struct short_ad *sad = NULL; + struct long_ad *lad = NULL; struct allocExtDesc *aed; eloc.logicalBlockNum = start; @@ -541,9 +537,9 @@ static void udf_table_free_blocks(struct super_block *sb, (count << sb->s_blocksize_bits); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else { brelse(oepos.bh); brelse(epos.bh); @@ -563,7 +559,7 @@ static void udf_table_free_blocks(struct super_block *sb, elen -= sb->s_blocksize; epos.bh = udf_tread(sb, - udf_get_lb_pblock(sb, epos.block, 0)); + udf_get_lb_pblock(sb, &epos.block, 0)); if (!epos.bh) { brelse(oepos.bh); goto error_return; @@ -601,15 +597,15 @@ static void udf_table_free_blocks(struct super_block *sb, if (sbi->s_udfrev >= 0x0200) udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1, epos.block.logicalBlockNum, - sizeof(tag)); + sizeof(struct tag)); else udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1, epos.block.logicalBlockNum, - sizeof(tag)); + sizeof(struct tag)); switch (iinfo->i_alloc_type) { case ICBTAG_FLAG_AD_SHORT: - sad = (short_ad *)sptr; + sad = (struct short_ad *)sptr; sad->extLength = cpu_to_le32( EXT_NEXT_EXTENT_ALLOCDECS | sb->s_blocksize); @@ -617,7 +613,7 @@ static void udf_table_free_blocks(struct super_block *sb, cpu_to_le32(epos.block.logicalBlockNum); break; case ICBTAG_FLAG_AD_LONG: - lad = (long_ad *)sptr; + lad = (struct long_ad *)sptr; lad->extLength = cpu_to_le32( EXT_NEXT_EXTENT_ALLOCDECS | sb->s_blocksize); @@ -635,7 +631,7 @@ static void udf_table_free_blocks(struct super_block *sb, /* It's possible that stealing the block emptied the extent */ if (elen) { - udf_write_aext(table, &epos, eloc, elen, 1); + udf_write_aext(table, &epos, &eloc, elen, 1); if (!epos.bh) { iinfo->i_lenAlloc += adsize; @@ -653,7 +649,6 @@ static void udf_table_free_blocks(struct super_block *sb, brelse(oepos.bh); error_return: - sb->s_dirt = 1; mutex_unlock(&sbi->s_alloc_mutex); return; } @@ -666,7 +661,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, struct udf_sb_info *sbi = UDF_SB(sb); int alloc_count = 0; uint32_t elen, adsize; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; struct extent_position epos; int8_t etype = -1; struct udf_inode_info *iinfo; @@ -677,9 +672,9 @@ static int udf_table_prealloc_blocks(struct super_block *sb, iinfo = UDF_I(table); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else return 0; @@ -707,7 +702,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, alloc_count = block_count; eloc.logicalBlockNum += alloc_count; elen -= (alloc_count << sb->s_blocksize_bits); - udf_write_aext(table, &epos, eloc, + udf_write_aext(table, &epos, &eloc, (etype << 30) | elen, 1); } else udf_delete_aext(table, epos, eloc, @@ -718,10 +713,8 @@ static int udf_table_prealloc_blocks(struct super_block *sb, brelse(epos.bh); - if (alloc_count && udf_add_free_space(sbi, partition, -alloc_count)) { - mark_buffer_dirty(sbi->s_lvid_bh); - sb->s_dirt = 1; - } + if (alloc_count) + udf_add_free_space(sb, partition, -alloc_count); mutex_unlock(&sbi->s_alloc_mutex); return alloc_count; } @@ -735,7 +728,7 @@ static int udf_table_new_block(struct super_block *sb, uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; uint32_t newblock = 0, adsize; uint32_t elen, goal_elen = 0; - kernel_lb_addr eloc, uninitialized_var(goal_eloc); + struct kernel_lb_addr eloc, uninitialized_var(goal_eloc); struct extent_position epos, goal_epos; int8_t etype; struct udf_inode_info *iinfo = UDF_I(table); @@ -743,9 +736,9 @@ static int udf_table_new_block(struct super_block *sb, *err = -ENOSPC; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else return newblock; @@ -814,46 +807,37 @@ static int udf_table_new_block(struct super_block *sb, } if (goal_elen) - udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1); + udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1); else udf_delete_aext(table, goal_epos, goal_eloc, goal_elen); brelse(goal_epos.bh); - if (udf_add_free_space(sbi, partition, -1)) - mark_buffer_dirty(sbi->s_lvid_bh); + udf_add_free_space(sb, partition, -1); - sb->s_dirt = 1; mutex_unlock(&sbi->s_alloc_mutex); *err = 0; return newblock; } -inline void udf_free_blocks(struct super_block *sb, - struct inode *inode, - kernel_lb_addr bloc, uint32_t offset, - uint32_t count) +void udf_free_blocks(struct super_block *sb, struct inode *inode, + struct kernel_lb_addr *bloc, uint32_t offset, + uint32_t count) { - uint16_t partition = bloc.partitionReferenceNum; + uint16_t partition = bloc->partitionReferenceNum; struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { - return udf_bitmap_free_blocks(sb, inode, - map->s_uspace.s_bitmap, - bloc, offset, count); + udf_bitmap_free_blocks(sb, inode, map->s_uspace.s_bitmap, + bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { - return udf_table_free_blocks(sb, inode, - map->s_uspace.s_table, - bloc, offset, count); + udf_table_free_blocks(sb, inode, map->s_uspace.s_table, + bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { - return udf_bitmap_free_blocks(sb, inode, - map->s_fspace.s_bitmap, - bloc, offset, count); + udf_bitmap_free_blocks(sb, inode, map->s_fspace.s_bitmap, + bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { - return udf_table_free_blocks(sb, inode, - map->s_fspace.s_table, - bloc, offset, count); - } else { - return; + udf_table_free_blocks(sb, inode, map->s_fspace.s_table, + bloc, offset, count); } } diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 62dc270c69d1..2efd4d5291b6 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -51,7 +51,7 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, uint8_t lfi; loff_t size = udf_ext0_offset(dir) + dir->i_size; struct buffer_head *tmp, *bha[16]; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen; sector_t offset; int i, num, ret = 0; @@ -80,13 +80,13 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, ret = -ENOENT; goto out; } - block = udf_get_lb_pblock(dir->i_sb, eloc, offset); + block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - epos.offset -= sizeof(short_ad); + epos.offset -= sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - epos.offset -= sizeof(long_ad); + epos.offset -= sizeof(struct long_ad); } else { offset = 0; } @@ -101,7 +101,7 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, if (i + offset > (elen >> dir->i_sb->s_blocksize_bits)) i = (elen >> dir->i_sb->s_blocksize_bits) - offset; for (num = 0; i > 0; i--) { - block = udf_get_lb_pblock(dir->i_sb, eloc, offset + i); + block = udf_get_lb_pblock(dir->i_sb, &eloc, offset + i); tmp = udf_tgetblk(dir->i_sb, block); if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) bha[num++] = tmp; @@ -161,9 +161,9 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, memcpy(fname, "..", flen); dt_type = DT_DIR; } else { - kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation); + struct kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation); - iblock = udf_get_lb_pblock(dir->i_sb, tloc, 0); + iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0); flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); dt_type = DT_UNKNOWN; } diff --git a/fs/udf/directory.c b/fs/udf/directory.c index 2820f8fcf4cc..1d2c570704c8 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -20,7 +20,7 @@ #if 0 static uint8_t *udf_filead_read(struct inode *dir, uint8_t *tmpad, - uint8_t ad_size, kernel_lb_addr fe_loc, + uint8_t ad_size, struct kernel_lb_addr fe_loc, int *pos, int *offset, struct buffer_head **bh, int *error) { @@ -75,7 +75,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, struct udf_fileident_bh *fibh, struct fileIdentDesc *cfi, struct extent_position *epos, - kernel_lb_addr *eloc, uint32_t *elen, + struct kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) { struct fileIdentDesc *fi; @@ -111,7 +111,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, (EXT_RECORDED_ALLOCATED >> 30)) return NULL; - block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); + block = udf_get_lb_pblock(dir->i_sb, eloc, *offset); (*offset)++; @@ -131,7 +131,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, if (i + *offset > (*elen >> blocksize_bits)) i = (*elen >> blocksize_bits)-*offset; for (num = 0; i > 0; i--) { - block = udf_get_lb_pblock(dir->i_sb, *eloc, + block = udf_get_lb_pblock(dir->i_sb, eloc, *offset + i); tmp = udf_tgetblk(dir->i_sb, block); if (tmp && !buffer_uptodate(tmp) && @@ -169,7 +169,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, (EXT_RECORDED_ALLOCATED >> 30)) return NULL; - block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); + block = udf_get_lb_pblock(dir->i_sb, eloc, *offset); (*offset)++; @@ -249,9 +249,9 @@ struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset) } #if 0 -static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset) +static struct extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset) { - extent_ad *ext; + struct extent_ad *ext; struct fileEntry *fe; uint8_t *ptr; @@ -274,54 +274,54 @@ static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset) if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs))) ptr += *offset; - ext = (extent_ad *)ptr; + ext = (struct extent_ad *)ptr; - *offset = *offset + sizeof(extent_ad); + *offset = *offset + sizeof(struct extent_ad); return ext; } #endif -short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, +struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc) { - short_ad *sa; + struct short_ad *sa; if ((!ptr) || (!offset)) { printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n"); return NULL; } - if ((*offset + sizeof(short_ad)) > maxoffset) + if ((*offset + sizeof(struct short_ad)) > maxoffset) return NULL; else { - sa = (short_ad *)ptr; + sa = (struct short_ad *)ptr; if (sa->extLength == 0) return NULL; } if (inc) - *offset += sizeof(short_ad); + *offset += sizeof(struct short_ad); return sa; } -long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc) +struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc) { - long_ad *la; + struct long_ad *la; if ((!ptr) || (!offset)) { printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n"); return NULL; } - if ((*offset + sizeof(long_ad)) > maxoffset) + if ((*offset + sizeof(struct long_ad)) > maxoffset) return NULL; else { - la = (long_ad *)ptr; + la = (struct long_ad *)ptr; if (la->extLength == 0) return NULL; } if (inc) - *offset += sizeof(long_ad); + *offset += sizeof(struct long_ad); return la; } diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h index a0974df82b31..4792b771aa80 100644 --- a/fs/udf/ecma_167.h +++ b/fs/udf/ecma_167.h @@ -38,10 +38,10 @@ #define _ECMA_167_H 1 /* Character set specification (ECMA 167r3 1/7.2.1) */ -typedef struct { +struct charspec { uint8_t charSetType; uint8_t charSetInfo[63]; -} __attribute__ ((packed)) charspec; +} __attribute__ ((packed)); /* Character Set Type (ECMA 167r3 1/7.2.1.1) */ #define CHARSPEC_TYPE_CS0 0x00 /* (1/7.2.2) */ @@ -57,7 +57,7 @@ typedef struct { typedef uint8_t dstring; /* Timestamp (ECMA 167r3 1/7.3) */ -typedef struct { +struct timestamp { __le16 typeAndTimezone; __le16 year; uint8_t month; @@ -68,7 +68,7 @@ typedef struct { uint8_t centiseconds; uint8_t hundredsOfMicroseconds; uint8_t microseconds; -} __attribute__ ((packed)) timestamp; +} __attribute__ ((packed)); /* Type and Time Zone (ECMA 167r3 1/7.3.1) */ #define TIMESTAMP_TYPE_MASK 0xF000 @@ -78,11 +78,11 @@ typedef struct { #define TIMESTAMP_TIMEZONE_MASK 0x0FFF /* Entity identifier (ECMA 167r3 1/7.4) */ -typedef struct { +struct regid { uint8_t flags; uint8_t ident[23]; uint8_t identSuffix[8]; -} __attribute__ ((packed)) regid; +} __attribute__ ((packed)); /* Flags (ECMA 167r3 1/7.4.1) */ #define ENTITYID_FLAGS_DIRTY 0x00 @@ -126,38 +126,38 @@ struct terminatingExtendedAreaDesc { /* Boot Descriptor (ECMA 167r3 2/9.4) */ struct bootDesc { - uint8_t structType; - uint8_t stdIdent[VSD_STD_ID_LEN]; - uint8_t structVersion; - uint8_t reserved1; - regid archType; - regid bootIdent; - __le32 bootExtLocation; - __le32 bootExtLength; - __le64 loadAddress; - __le64 startAddress; - timestamp descCreationDateAndTime; - __le16 flags; - uint8_t reserved2[32]; - uint8_t bootUse[1906]; + uint8_t structType; + uint8_t stdIdent[VSD_STD_ID_LEN]; + uint8_t structVersion; + uint8_t reserved1; + struct regid archType; + struct regid bootIdent; + __le32 bootExtLocation; + __le32 bootExtLength; + __le64 loadAddress; + __le64 startAddress; + struct timestamp descCreationDateAndTime; + __le16 flags; + uint8_t reserved2[32]; + uint8_t bootUse[1906]; } __attribute__ ((packed)); /* Flags (ECMA 167r3 2/9.4.12) */ #define BOOT_FLAGS_ERASE 0x01 /* Extent Descriptor (ECMA 167r3 3/7.1) */ -typedef struct { +struct extent_ad { __le32 extLength; __le32 extLocation; -} __attribute__ ((packed)) extent_ad; +} __attribute__ ((packed)); -typedef struct { +struct kernel_extent_ad { uint32_t extLength; uint32_t extLocation; -} kernel_extent_ad; +}; /* Descriptor Tag (ECMA 167r3 3/7.2) */ -typedef struct { +struct tag { __le16 tagIdent; __le16 descVersion; uint8_t tagChecksum; @@ -166,7 +166,7 @@ typedef struct { __le16 descCRC; __le16 descCRCLength; __le32 tagLocation; -} __attribute__ ((packed)) tag; +} __attribute__ ((packed)); /* Tag Identifier (ECMA 167r3 3/7.2.1) */ #define TAG_IDENT_PVD 0x0001 @@ -190,28 +190,28 @@ struct NSRDesc { /* Primary Volume Descriptor (ECMA 167r3 3/10.1) */ struct primaryVolDesc { - tag descTag; - __le32 volDescSeqNum; - __le32 primaryVolDescNum; - dstring volIdent[32]; - __le16 volSeqNum; - __le16 maxVolSeqNum; - __le16 interchangeLvl; - __le16 maxInterchangeLvl; - __le32 charSetList; - __le32 maxCharSetList; - dstring volSetIdent[128]; - charspec descCharSet; - charspec explanatoryCharSet; - extent_ad volAbstract; - extent_ad volCopyright; - regid appIdent; - timestamp recordingDateAndTime; - regid impIdent; - uint8_t impUse[64]; - __le32 predecessorVolDescSeqLocation; - __le16 flags; - uint8_t reserved[22]; + struct tag descTag; + __le32 volDescSeqNum; + __le32 primaryVolDescNum; + dstring volIdent[32]; + __le16 volSeqNum; + __le16 maxVolSeqNum; + __le16 interchangeLvl; + __le16 maxInterchangeLvl; + __le32 charSetList; + __le32 maxCharSetList; + dstring volSetIdent[128]; + struct charspec descCharSet; + struct charspec explanatoryCharSet; + struct extent_ad volAbstract; + struct extent_ad volCopyright; + struct regid appIdent; + struct timestamp recordingDateAndTime; + struct regid impIdent; + uint8_t impUse[64]; + __le32 predecessorVolDescSeqLocation; + __le16 flags; + uint8_t reserved[22]; } __attribute__ ((packed)); /* Flags (ECMA 167r3 3/10.1.21) */ @@ -219,40 +219,40 @@ struct primaryVolDesc { /* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */ struct anchorVolDescPtr { - tag descTag; - extent_ad mainVolDescSeqExt; - extent_ad reserveVolDescSeqExt; - uint8_t reserved[480]; + struct tag descTag; + struct extent_ad mainVolDescSeqExt; + struct extent_ad reserveVolDescSeqExt; + uint8_t reserved[480]; } __attribute__ ((packed)); /* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */ struct volDescPtr { - tag descTag; - __le32 volDescSeqNum; - extent_ad nextVolDescSeqExt; - uint8_t reserved[484]; + struct tag descTag; + __le32 volDescSeqNum; + struct extent_ad nextVolDescSeqExt; + uint8_t reserved[484]; } __attribute__ ((packed)); /* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */ struct impUseVolDesc { - tag descTag; + struct tag descTag; __le32 volDescSeqNum; - regid impIdent; + struct regid impIdent; uint8_t impUse[460]; } __attribute__ ((packed)); /* Partition Descriptor (ECMA 167r3 3/10.5) */ struct partitionDesc { - tag descTag; + struct tag descTag; __le32 volDescSeqNum; __le16 partitionFlags; __le16 partitionNumber; - regid partitionContents; + struct regid partitionContents; uint8_t partitionContentsUse[128]; __le32 accessType; __le32 partitionStartingLocation; __le32 partitionLength; - regid impIdent; + struct regid impIdent; uint8_t impUse[128]; uint8_t reserved[156]; } __attribute__ ((packed)); @@ -278,19 +278,19 @@ struct partitionDesc { /* Logical Volume Descriptor (ECMA 167r3 3/10.6) */ struct logicalVolDesc { - tag descTag; - __le32 volDescSeqNum; - charspec descCharSet; - dstring logicalVolIdent[128]; - __le32 logicalBlockSize; - regid domainIdent; - uint8_t logicalVolContentsUse[16]; - __le32 mapTableLength; - __le32 numPartitionMaps; - regid impIdent; - uint8_t impUse[128]; - extent_ad integritySeqExt; - uint8_t partitionMaps[0]; + struct tag descTag; + __le32 volDescSeqNum; + struct charspec descCharSet; + dstring logicalVolIdent[128]; + __le32 logicalBlockSize; + struct regid domainIdent; + uint8_t logicalVolContentsUse[16]; + __le32 mapTableLength; + __le32 numPartitionMaps; + struct regid impIdent; + uint8_t impUse[128]; + struct extent_ad integritySeqExt; + uint8_t partitionMaps[0]; } __attribute__ ((packed)); /* Generic Partition Map (ECMA 167r3 3/10.7.1) */ @@ -322,30 +322,30 @@ struct genericPartitionMap2 { /* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */ struct unallocSpaceDesc { - tag descTag; - __le32 volDescSeqNum; - __le32 numAllocDescs; - extent_ad allocDescs[0]; + struct tag descTag; + __le32 volDescSeqNum; + __le32 numAllocDescs; + struct extent_ad allocDescs[0]; } __attribute__ ((packed)); /* Terminating Descriptor (ECMA 167r3 3/10.9) */ struct terminatingDesc { - tag descTag; + struct tag descTag; uint8_t reserved[496]; } __attribute__ ((packed)); /* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */ struct logicalVolIntegrityDesc { - tag descTag; - timestamp recordingDateAndTime; - __le32 integrityType; - extent_ad nextIntegrityExt; - uint8_t logicalVolContentsUse[32]; - __le32 numOfPartitions; - __le32 lengthOfImpUse; - __le32 freeSpaceTable[0]; - __le32 sizeTable[0]; - uint8_t impUse[0]; + struct tag descTag; + struct timestamp recordingDateAndTime; + __le32 integrityType; + struct extent_ad nextIntegrityExt; + uint8_t logicalVolContentsUse[32]; + __le32 numOfPartitions; + __le32 lengthOfImpUse; + __le32 freeSpaceTable[0]; + __le32 sizeTable[0]; + uint8_t impUse[0]; } __attribute__ ((packed)); /* Integrity Type (ECMA 167r3 3/10.10.3) */ @@ -353,50 +353,50 @@ struct logicalVolIntegrityDesc { #define LVID_INTEGRITY_TYPE_CLOSE 0x00000001 /* Recorded Address (ECMA 167r3 4/7.1) */ -typedef struct { +struct lb_addr { __le32 logicalBlockNum; __le16 partitionReferenceNum; -} __attribute__ ((packed)) lb_addr; +} __attribute__ ((packed)); /* ... and its in-core analog */ -typedef struct { +struct kernel_lb_addr { uint32_t logicalBlockNum; uint16_t partitionReferenceNum; -} kernel_lb_addr; +}; /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */ -typedef struct { +struct short_ad { __le32 extLength; __le32 extPosition; -} __attribute__ ((packed)) short_ad; +} __attribute__ ((packed)); /* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */ -typedef struct { +struct long_ad { __le32 extLength; - lb_addr extLocation; + struct lb_addr extLocation; uint8_t impUse[6]; -} __attribute__ ((packed)) long_ad; +} __attribute__ ((packed)); -typedef struct { - uint32_t extLength; - kernel_lb_addr extLocation; - uint8_t impUse[6]; -} kernel_long_ad; +struct kernel_long_ad { + uint32_t extLength; + struct kernel_lb_addr extLocation; + uint8_t impUse[6]; +}; /* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */ -typedef struct { +struct ext_ad { __le32 extLength; __le32 recordedLength; __le32 informationLength; - lb_addr extLocation; -} __attribute__ ((packed)) ext_ad; + struct lb_addr extLocation; +} __attribute__ ((packed)); -typedef struct { - uint32_t extLength; - uint32_t recordedLength; - uint32_t informationLength; - kernel_lb_addr extLocation; -} kernel_ext_ad; +struct kernel_ext_ad { + uint32_t extLength; + uint32_t recordedLength; + uint32_t informationLength; + struct kernel_lb_addr extLocation; +}; /* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */ @@ -415,44 +415,44 @@ typedef struct { /* File Set Descriptor (ECMA 167r3 4/14.1) */ struct fileSetDesc { - tag descTag; - timestamp recordingDateAndTime; - __le16 interchangeLvl; - __le16 maxInterchangeLvl; - __le32 charSetList; - __le32 maxCharSetList; - __le32 fileSetNum; - __le32 fileSetDescNum; - charspec logicalVolIdentCharSet; - dstring logicalVolIdent[128]; - charspec fileSetCharSet; - dstring fileSetIdent[32]; - dstring copyrightFileIdent[32]; - dstring abstractFileIdent[32]; - long_ad rootDirectoryICB; - regid domainIdent; - long_ad nextExt; - long_ad streamDirectoryICB; - uint8_t reserved[32]; + struct tag descTag; + struct timestamp recordingDateAndTime; + __le16 interchangeLvl; + __le16 maxInterchangeLvl; + __le32 charSetList; + __le32 maxCharSetList; + __le32 fileSetNum; + __le32 fileSetDescNum; + struct charspec logicalVolIdentCharSet; + dstring logicalVolIdent[128]; + struct charspec fileSetCharSet; + dstring fileSetIdent[32]; + dstring copyrightFileIdent[32]; + dstring abstractFileIdent[32]; + struct long_ad rootDirectoryICB; + struct regid domainIdent; + struct long_ad nextExt; + struct long_ad streamDirectoryICB; + uint8_t reserved[32]; } __attribute__ ((packed)); /* Partition Header Descriptor (ECMA 167r3 4/14.3) */ struct partitionHeaderDesc { - short_ad unallocSpaceTable; - short_ad unallocSpaceBitmap; - short_ad partitionIntegrityTable; - short_ad freedSpaceTable; - short_ad freedSpaceBitmap; + struct short_ad unallocSpaceTable; + struct short_ad unallocSpaceBitmap; + struct short_ad partitionIntegrityTable; + struct short_ad freedSpaceTable; + struct short_ad freedSpaceBitmap; uint8_t reserved[88]; } __attribute__ ((packed)); /* File Identifier Descriptor (ECMA 167r3 4/14.4) */ struct fileIdentDesc { - tag descTag; + struct tag descTag; __le16 fileVersionNum; uint8_t fileCharacteristics; uint8_t lengthFileIdent; - long_ad icb; + struct long_ad icb; __le16 lengthOfImpUse; uint8_t impUse[0]; uint8_t fileIdent[0]; @@ -468,22 +468,22 @@ struct fileIdentDesc { /* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */ struct allocExtDesc { - tag descTag; + struct tag descTag; __le32 previousAllocExtLocation; __le32 lengthAllocDescs; } __attribute__ ((packed)); /* ICB Tag (ECMA 167r3 4/14.6) */ -typedef struct { +struct icbtag { __le32 priorRecordedNumDirectEntries; __le16 strategyType; __le16 strategyParameter; __le16 numEntries; uint8_t reserved; uint8_t fileType; - lb_addr parentICBLocation; + struct lb_addr parentICBLocation; __le16 flags; -} __attribute__ ((packed)) icbtag; +} __attribute__ ((packed)); /* Strategy Type (ECMA 167r3 4/14.6.2) */ #define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000 @@ -528,41 +528,41 @@ typedef struct { /* Indirect Entry (ECMA 167r3 4/14.7) */ struct indirectEntry { - tag descTag; - icbtag icbTag; - long_ad indirectICB; + struct tag descTag; + struct icbtag icbTag; + struct long_ad indirectICB; } __attribute__ ((packed)); /* Terminal Entry (ECMA 167r3 4/14.8) */ struct terminalEntry { - tag descTag; - icbtag icbTag; + struct tag descTag; + struct icbtag icbTag; } __attribute__ ((packed)); /* File Entry (ECMA 167r3 4/14.9) */ struct fileEntry { - tag descTag; - icbtag icbTag; - __le32 uid; - __le32 gid; - __le32 permissions; - __le16 fileLinkCount; - uint8_t recordFormat; - uint8_t recordDisplayAttr; - __le32 recordLength; - __le64 informationLength; - __le64 logicalBlocksRecorded; - timestamp accessTime; - timestamp modificationTime; - timestamp attrTime; - __le32 checkpoint; - long_ad extendedAttrICB; - regid impIdent; - __le64 uniqueID; - __le32 lengthExtendedAttr; - __le32 lengthAllocDescs; - uint8_t extendedAttr[0]; - uint8_t allocDescs[0]; + struct tag descTag; + struct icbtag icbTag; + __le32 uid; + __le32 gid; + __le32 permissions; + __le16 fileLinkCount; + uint8_t recordFormat; + uint8_t recordDisplayAttr; + __le32 recordLength; + __le64 informationLength; + __le64 logicalBlocksRecorded; + struct timestamp accessTime; + struct timestamp modificationTime; + struct timestamp attrTime; + __le32 checkpoint; + struct long_ad extendedAttrICB; + struct regid impIdent; + __le64 uniqueID; + __le32 lengthExtendedAttr; + __le32 lengthAllocDescs; + uint8_t extendedAttr[0]; + uint8_t allocDescs[0]; } __attribute__ ((packed)); /* Permissions (ECMA 167r3 4/14.9.5) */ @@ -604,7 +604,7 @@ struct fileEntry { /* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */ struct extendedAttrHeaderDesc { - tag descTag; + struct tag descTag; __le32 impAttrLocation; __le32 appAttrLocation; } __attribute__ ((packed)); @@ -687,7 +687,7 @@ struct impUseExtAttr { uint8_t reserved[3]; __le32 attrLength; __le32 impUseLength; - regid impIdent; + struct regid impIdent; uint8_t impUse[0]; } __attribute__ ((packed)); @@ -698,7 +698,7 @@ struct appUseExtAttr { uint8_t reserved[3]; __le32 attrLength; __le32 appUseLength; - regid appIdent; + struct regid appIdent; uint8_t appUse[0]; } __attribute__ ((packed)); @@ -712,15 +712,15 @@ struct appUseExtAttr { /* Unallocated Space Entry (ECMA 167r3 4/14.11) */ struct unallocSpaceEntry { - tag descTag; - icbtag icbTag; + struct tag descTag; + struct icbtag icbTag; __le32 lengthAllocDescs; uint8_t allocDescs[0]; } __attribute__ ((packed)); /* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */ struct spaceBitmapDesc { - tag descTag; + struct tag descTag; __le32 numOfBits; __le32 numOfBytes; uint8_t bitmap[0]; @@ -728,13 +728,13 @@ struct spaceBitmapDesc { /* Partition Integrity Entry (ECMA 167r3 4/14.13) */ struct partitionIntegrityEntry { - tag descTag; - icbtag icbTag; - timestamp recordingDateAndTime; - uint8_t integrityType; - uint8_t reserved[175]; - regid impIdent; - uint8_t impUse[256]; + struct tag descTag; + struct icbtag icbTag; + struct timestamp recordingDateAndTime; + uint8_t integrityType; + uint8_t reserved[175]; + struct regid impIdent; + uint8_t impUse[256]; } __attribute__ ((packed)); /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */ @@ -765,32 +765,32 @@ struct pathComponent { /* File Entry (ECMA 167r3 4/14.17) */ struct extendedFileEntry { - tag descTag; - icbtag icbTag; - __le32 uid; - __le32 gid; - __le32 permissions; - __le16 fileLinkCount; - uint8_t recordFormat; - uint8_t recordDisplayAttr; - __le32 recordLength; - __le64 informationLength; - __le64 objectSize; - __le64 logicalBlocksRecorded; - timestamp accessTime; - timestamp modificationTime; - timestamp createTime; - timestamp attrTime; - __le32 checkpoint; - __le32 reserved; - long_ad extendedAttrICB; - long_ad streamDirectoryICB; - regid impIdent; - __le64 uniqueID; - __le32 lengthExtendedAttr; - __le32 lengthAllocDescs; - uint8_t extendedAttr[0]; - uint8_t allocDescs[0]; + struct tag descTag; + struct icbtag icbTag; + __le32 uid; + __le32 gid; + __le32 permissions; + __le16 fileLinkCount; + uint8_t recordFormat; + uint8_t recordDisplayAttr; + __le32 recordLength; + __le64 informationLength; + __le64 objectSize; + __le64 logicalBlocksRecorded; + struct timestamp accessTime; + struct timestamp modificationTime; + struct timestamp createTime; + struct timestamp attrTime; + __le32 checkpoint; + __le32 reserved; + struct long_ad extendedAttrICB; + struct long_ad streamDirectoryICB; + struct regid impIdent; + __le64 uniqueID; + __le32 lengthExtendedAttr; + __le32 lengthAllocDescs; + uint8_t extendedAttr[0]; + uint8_t allocDescs[0]; } __attribute__ ((packed)); #endif /* _ECMA_167_H */ diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 47dbe5613f90..c10fa39f97e2 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -49,12 +49,11 @@ void udf_free_inode(struct inode *inode) le32_add_cpu(&lvidiu->numDirs, -1); else le32_add_cpu(&lvidiu->numFiles, -1); - - mark_buffer_dirty(sbi->s_lvid_bh); + udf_updated_lvid(sb); } mutex_unlock(&sbi->s_alloc_mutex); - udf_free_blocks(sb, NULL, UDF_I(inode)->i_location, 0, 1); + udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1); } struct inode *udf_new_inode(struct inode *dir, int mode, int *err) @@ -122,7 +121,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) if (!(++uniqueID & 0x00000000FFFFFFFFUL)) uniqueID += 16; lvhd->uniqueID = cpu_to_le64(uniqueID); - mark_buffer_dirty(sbi->s_lvid_bh); + udf_updated_lvid(sb); } mutex_unlock(&sbi->s_alloc_mutex); inode->i_mode = mode; @@ -138,7 +137,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) iinfo->i_location.logicalBlockNum = block; iinfo->i_location.partitionReferenceNum = dinfo->i_location.partitionReferenceNum; - inode->i_ino = udf_get_lb_pblock(sb, iinfo->i_location, 0); + inode->i_ino = udf_get_lb_pblock(sb, &iinfo->i_location, 0); inode->i_blocks = 0; iinfo->i_lenEAttr = 0; iinfo->i_lenAlloc = 0; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 30ebde490f7f..e7533f785636 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -55,15 +55,15 @@ static int udf_alloc_i_data(struct inode *inode, size_t size); static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, sector_t *, int *); static int8_t udf_insert_aext(struct inode *, struct extent_position, - kernel_lb_addr, uint32_t); + struct kernel_lb_addr, uint32_t); static void udf_split_extents(struct inode *, int *, int, int, - kernel_long_ad[EXTENT_MERGE_SIZE], int *); + struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); static void udf_prealloc_extents(struct inode *, int, int, - kernel_long_ad[EXTENT_MERGE_SIZE], int *); + struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); static void udf_merge_extents(struct inode *, - kernel_long_ad[EXTENT_MERGE_SIZE], int *); + struct kernel_long_ad[EXTENT_MERGE_SIZE], int *); static void udf_update_extents(struct inode *, - kernel_long_ad[EXTENT_MERGE_SIZE], int, int, + struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int, struct extent_position *); static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); @@ -200,7 +200,7 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, { int newblock; struct buffer_head *dbh = NULL; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen; uint8_t alloctype; struct extent_position epos; @@ -281,7 +281,7 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, epos.bh = NULL; epos.block = iinfo->i_location; epos.offset = udf_file_entry_alloc_offset(inode); - udf_add_aext(inode, &epos, eloc, elen, 0); + udf_add_aext(inode, &epos, &eloc, elen, 0); /* UniqueID stuff */ brelse(epos.bh); @@ -359,12 +359,12 @@ static struct buffer_head *udf_getblk(struct inode *inode, long block, /* Extend the file by 'blocks' blocks, return the number of extents added */ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, - kernel_long_ad *last_ext, sector_t blocks) + struct kernel_long_ad *last_ext, sector_t blocks) { sector_t add; int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); struct super_block *sb = inode->i_sb; - kernel_lb_addr prealloc_loc = {}; + struct kernel_lb_addr prealloc_loc = {}; int prealloc_len = 0; struct udf_inode_info *iinfo; @@ -411,11 +411,11 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, } if (fake) { - udf_add_aext(inode, last_pos, last_ext->extLocation, + udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); count++; } else - udf_write_aext(inode, last_pos, last_ext->extLocation, + udf_write_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); /* Managed to do everything necessary? */ @@ -432,7 +432,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, /* Create enough extents to cover the whole hole */ while (blocks > add) { blocks -= add; - if (udf_add_aext(inode, last_pos, last_ext->extLocation, + if (udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1) == -1) return -1; count++; @@ -440,7 +440,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, if (blocks) { last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (blocks << sb->s_blocksize_bits); - if (udf_add_aext(inode, last_pos, last_ext->extLocation, + if (udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1) == -1) return -1; count++; @@ -449,7 +449,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, out: /* Do we have some preallocated blocks saved? */ if (prealloc_len) { - if (udf_add_aext(inode, last_pos, prealloc_loc, + if (udf_add_aext(inode, last_pos, &prealloc_loc, prealloc_len, 1) == -1) return -1; last_ext->extLocation = prealloc_loc; @@ -459,9 +459,9 @@ out: /* last_pos should point to the last written extent... */ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - last_pos->offset -= sizeof(short_ad); + last_pos->offset -= sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - last_pos->offset -= sizeof(long_ad); + last_pos->offset -= sizeof(struct long_ad); else return -1; @@ -473,11 +473,11 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, { static sector_t last_block; struct buffer_head *result = NULL; - kernel_long_ad laarr[EXTENT_MERGE_SIZE]; + struct kernel_long_ad laarr[EXTENT_MERGE_SIZE]; struct extent_position prev_epos, cur_epos, next_epos; int count = 0, startnum = 0, endnum = 0; uint32_t elen = 0, tmpelen; - kernel_lb_addr eloc, tmpeloc; + struct kernel_lb_addr eloc, tmpeloc; int c = 1; loff_t lbcount = 0, b_off = 0; uint32_t newblocknum, newblock; @@ -550,12 +550,12 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, elen = EXT_RECORDED_ALLOCATED | ((elen + inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize - 1)); - etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1); + etype = udf_write_aext(inode, &cur_epos, &eloc, elen, 1); } brelse(prev_epos.bh); brelse(cur_epos.bh); brelse(next_epos.bh); - newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); + newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset); *phys = newblock; return NULL; } @@ -572,7 +572,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, } else { /* Create a fake extent when there's not one */ memset(&laarr[0].extLocation, 0x00, - sizeof(kernel_lb_addr)); + sizeof(struct kernel_lb_addr)); laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; /* Will udf_extend_file() create real extent from a fake one? */ @@ -602,7 +602,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | inode->i_sb->s_blocksize; memset(&laarr[c].extLocation, 0x00, - sizeof(kernel_lb_addr)); + sizeof(struct kernel_lb_addr)); count++; endnum++; } @@ -699,7 +699,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block, static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum, - kernel_long_ad laarr[EXTENT_MERGE_SIZE], + struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) { unsigned long blocksize = inode->i_sb->s_blocksize; @@ -726,7 +726,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset, if (offset) { if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { udf_free_blocks(inode->i_sb, inode, - laarr[curr].extLocation, + &laarr[curr].extLocation, 0, offset); laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | @@ -763,7 +763,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset, } static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, - kernel_long_ad laarr[EXTENT_MERGE_SIZE], + struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) { int start, length = 0, currlength = 0, i; @@ -817,7 +817,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, inode->i_sb->s_blocksize_bits); else { memmove(&laarr[c + 2], &laarr[c + 1], - sizeof(long_ad) * (*endnum - (c + 1))); + sizeof(struct long_ad) * (*endnum - (c + 1))); (*endnum)++; laarr[c + 1].extLocation.logicalBlockNum = next; laarr[c + 1].extLocation.partitionReferenceNum = @@ -846,7 +846,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, if (*endnum > (i + 1)) memmove(&laarr[i], &laarr[i + 1], - sizeof(long_ad) * + sizeof(struct long_ad) * (*endnum - (i + 1))); i--; (*endnum)--; @@ -859,7 +859,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, } static void udf_merge_extents(struct inode *inode, - kernel_long_ad laarr[EXTENT_MERGE_SIZE], + struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) { int i; @@ -867,8 +867,8 @@ static void udf_merge_extents(struct inode *inode, unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; for (i = 0; i < (*endnum - 1); i++) { - kernel_long_ad *li /*l[i]*/ = &laarr[i]; - kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1]; + struct kernel_long_ad *li /*l[i]*/ = &laarr[i]; + struct kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1]; if (((li->extLength >> 30) == (lip1->extLength >> 30)) && (((li->extLength >> 30) == @@ -902,7 +902,7 @@ static void udf_merge_extents(struct inode *inode, blocksize - 1) & ~(blocksize - 1)); if (*endnum > (i + 2)) memmove(&laarr[i + 1], &laarr[i + 2], - sizeof(long_ad) * + sizeof(struct long_ad) * (*endnum - (i + 2))); i--; (*endnum)--; @@ -911,7 +911,7 @@ static void udf_merge_extents(struct inode *inode, (EXT_NOT_RECORDED_ALLOCATED >> 30)) && ((lip1->extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) { - udf_free_blocks(inode->i_sb, inode, li->extLocation, 0, + udf_free_blocks(inode->i_sb, inode, &li->extLocation, 0, ((li->extLength & UDF_EXTENT_LENGTH_MASK) + blocksize - 1) >> blocksize_bits); @@ -937,7 +937,7 @@ static void udf_merge_extents(struct inode *inode, blocksize - 1) & ~(blocksize - 1)); if (*endnum > (i + 2)) memmove(&laarr[i + 1], &laarr[i + 2], - sizeof(long_ad) * + sizeof(struct long_ad) * (*endnum - (i + 2))); i--; (*endnum)--; @@ -945,7 +945,7 @@ static void udf_merge_extents(struct inode *inode, } else if ((li->extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { udf_free_blocks(inode->i_sb, inode, - li->extLocation, 0, + &li->extLocation, 0, ((li->extLength & UDF_EXTENT_LENGTH_MASK) + blocksize - 1) >> blocksize_bits); @@ -959,12 +959,12 @@ static void udf_merge_extents(struct inode *inode, } static void udf_update_extents(struct inode *inode, - kernel_long_ad laarr[EXTENT_MERGE_SIZE], + struct kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, struct extent_position *epos) { int start = 0, i; - kernel_lb_addr tmploc; + struct kernel_lb_addr tmploc; uint32_t tmplen; if (startnum > endnum) { @@ -983,7 +983,7 @@ static void udf_update_extents(struct inode *inode, for (i = start; i < endnum; i++) { udf_next_aext(inode, epos, &tmploc, &tmplen, 0); - udf_write_aext(inode, epos, laarr[i].extLocation, + udf_write_aext(inode, epos, &laarr[i].extLocation, laarr[i].extLength, 1); } } @@ -1076,7 +1076,7 @@ static void __udf_read_inode(struct inode *inode) * i_nlink = 1 * i_op = NULL; */ - bh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 0, &ident); + bh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 0, &ident); if (!bh) { printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n", inode->i_ino); @@ -1098,24 +1098,24 @@ static void __udf_read_inode(struct inode *inode) if (fe->icbTag.strategyType == cpu_to_le16(4096)) { struct buffer_head *ibh; - ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1, + ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1, &ident); if (ident == TAG_IDENT_IE && ibh) { struct buffer_head *nbh = NULL; - kernel_lb_addr loc; + struct kernel_lb_addr loc; struct indirectEntry *ie; ie = (struct indirectEntry *)ibh->b_data; loc = lelb_to_cpu(ie->indirectICB.extLocation); if (ie->indirectICB.extLength && - (nbh = udf_read_ptagged(inode->i_sb, loc, 0, + (nbh = udf_read_ptagged(inode->i_sb, &loc, 0, &ident))) { if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE) { memcpy(&iinfo->i_location, &loc, - sizeof(kernel_lb_addr)); + sizeof(struct kernel_lb_addr)); brelse(bh); brelse(ibh); brelse(nbh); @@ -1222,8 +1222,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) inode->i_size = le64_to_cpu(fe->informationLength); iinfo->i_lenExtents = inode->i_size; - inode->i_mode = udf_convert_permissions(fe); - inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask; + if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && + sbi->s_fmode != UDF_INVALID_MODE) + inode->i_mode = sbi->s_fmode; + else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY && + sbi->s_dmode != UDF_INVALID_MODE) + inode->i_mode = sbi->s_dmode; + else + inode->i_mode = udf_convert_permissions(fe); + inode->i_mode &= ~sbi->s_umask; if (iinfo->i_efe == 0) { inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << @@ -1396,7 +1403,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, - iinfo->i_location, 0)); + &iinfo->i_location, 0)); if (!bh) { udf_debug("bread failure\n"); return -EIO; @@ -1416,13 +1423,13 @@ static int udf_update_inode(struct inode *inode, int do_sync) iinfo->i_ext.i_data, inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)); crclen = sizeof(struct unallocSpaceEntry) + - iinfo->i_lenAlloc - sizeof(tag); + iinfo->i_lenAlloc - sizeof(struct tag); use->descTag.tagLocation = cpu_to_le32( iinfo->i_location. logicalBlockNum); use->descTag.descCRCLength = cpu_to_le16(crclen); use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + - sizeof(tag), + sizeof(struct tag), crclen)); use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); @@ -1459,23 +1466,23 @@ static int udf_update_inode(struct inode *inode, int do_sync) fe->informationLength = cpu_to_le64(inode->i_size); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - regid *eid; + struct regid *eid; struct deviceSpec *dsea = (struct deviceSpec *)udf_get_extendedattr(inode, 12, 1); if (!dsea) { dsea = (struct deviceSpec *) udf_add_extendedattr(inode, sizeof(struct deviceSpec) + - sizeof(regid), 12, 0x3); + sizeof(struct regid), 12, 0x3); dsea->attrType = cpu_to_le32(12); dsea->attrSubtype = 1; dsea->attrLength = cpu_to_le32( sizeof(struct deviceSpec) + - sizeof(regid)); - dsea->impUseLength = cpu_to_le32(sizeof(regid)); + sizeof(struct regid)); + dsea->impUseLength = cpu_to_le32(sizeof(struct regid)); } - eid = (regid *)dsea->impUse; - memset(eid, 0, sizeof(regid)); + eid = (struct regid *)dsea->impUse; + memset(eid, 0, sizeof(struct regid)); strcpy(eid->ident, UDF_ID_DEVELOPER); eid->identSuffix[0] = UDF_OS_CLASS_UNIX; eid->identSuffix[1] = UDF_OS_ID_LINUX; @@ -1494,7 +1501,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime); - memset(&(fe->impIdent), 0, sizeof(regid)); + memset(&(fe->impIdent), 0, sizeof(struct regid)); strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; @@ -1533,7 +1540,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime); udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime); - memset(&(efe->impIdent), 0, sizeof(regid)); + memset(&(efe->impIdent), 0, sizeof(struct regid)); strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; @@ -1584,9 +1591,9 @@ static int udf_update_inode(struct inode *inode, int do_sync) fe->descTag.tagLocation = cpu_to_le32( iinfo->i_location.logicalBlockNum); crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - - sizeof(tag); + sizeof(struct tag); fe->descTag.descCRCLength = cpu_to_le16(crclen); - fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(tag), + fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag), crclen)); fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); @@ -1606,7 +1613,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) return err; } -struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino) +struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino) { unsigned long block = udf_get_lb_pblock(sb, ino, 0); struct inode *inode = iget_locked(sb, block); @@ -1615,7 +1622,7 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino) return NULL; if (inode->i_state & I_NEW) { - memcpy(&UDF_I(inode)->i_location, &ino, sizeof(kernel_lb_addr)); + memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); __udf_read_inode(inode); unlock_new_inode(inode); } @@ -1623,10 +1630,10 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino) if (is_bad_inode(inode)) goto out_iput; - if (ino.logicalBlockNum >= UDF_SB(sb)-> - s_partmaps[ino.partitionReferenceNum].s_partition_len) { + if (ino->logicalBlockNum >= UDF_SB(sb)-> + s_partmaps[ino->partitionReferenceNum].s_partition_len) { udf_debug("block=%d, partition=%d out of range\n", - ino.logicalBlockNum, ino.partitionReferenceNum); + ino->logicalBlockNum, ino->partitionReferenceNum); make_bad_inode(inode); goto out_iput; } @@ -1639,11 +1646,11 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino) } int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, - kernel_lb_addr eloc, uint32_t elen, int inc) + struct kernel_lb_addr *eloc, uint32_t elen, int inc) { int adsize; - short_ad *sad = NULL; - long_ad *lad = NULL; + struct short_ad *sad = NULL; + struct long_ad *lad = NULL; struct allocExtDesc *aed; int8_t etype; uint8_t *ptr; @@ -1657,9 +1664,9 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, ptr = epos->bh->b_data + epos->offset; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else return -1; @@ -1667,7 +1674,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, char *sptr, *dptr; struct buffer_head *nbh; int err, loffset; - kernel_lb_addr obloc = epos->block; + struct kernel_lb_addr obloc = epos->block; epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, obloc.partitionReferenceNum, @@ -1675,7 +1682,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, if (!epos->block.logicalBlockNum) return -1; nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, - epos->block, + &epos->block, 0)); if (!nbh) return -1; @@ -1712,20 +1719,20 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, } if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200) udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, - epos->block.logicalBlockNum, sizeof(tag)); + epos->block.logicalBlockNum, sizeof(struct tag)); else udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, - epos->block.logicalBlockNum, sizeof(tag)); + epos->block.logicalBlockNum, sizeof(struct tag)); switch (iinfo->i_alloc_type) { case ICBTAG_FLAG_AD_SHORT: - sad = (short_ad *)sptr; + sad = (struct short_ad *)sptr; sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | inode->i_sb->s_blocksize); sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum); break; case ICBTAG_FLAG_AD_LONG: - lad = (long_ad *)sptr; + lad = (struct long_ad *)sptr; lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS | inode->i_sb->s_blocksize); lad->extLocation = cpu_to_lelb(epos->block); @@ -1769,12 +1776,12 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, } int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, - kernel_lb_addr eloc, uint32_t elen, int inc) + struct kernel_lb_addr *eloc, uint32_t elen, int inc) { int adsize; uint8_t *ptr; - short_ad *sad; - long_ad *lad; + struct short_ad *sad; + struct long_ad *lad; struct udf_inode_info *iinfo = UDF_I(inode); if (!epos->bh) @@ -1786,17 +1793,17 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, switch (iinfo->i_alloc_type) { case ICBTAG_FLAG_AD_SHORT: - sad = (short_ad *)ptr; + sad = (struct short_ad *)ptr; sad->extLength = cpu_to_le32(elen); - sad->extPosition = cpu_to_le32(eloc.logicalBlockNum); - adsize = sizeof(short_ad); + sad->extPosition = cpu_to_le32(eloc->logicalBlockNum); + adsize = sizeof(struct short_ad); break; case ICBTAG_FLAG_AD_LONG: - lad = (long_ad *)ptr; + lad = (struct long_ad *)ptr; lad->extLength = cpu_to_le32(elen); - lad->extLocation = cpu_to_lelb(eloc); + lad->extLocation = cpu_to_lelb(*eloc); memset(lad->impUse, 0x00, sizeof(lad->impUse)); - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); break; default: return -1; @@ -1823,7 +1830,7 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, } int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, - kernel_lb_addr *eloc, uint32_t *elen, int inc) + struct kernel_lb_addr *eloc, uint32_t *elen, int inc) { int8_t etype; @@ -1833,7 +1840,7 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, epos->block = *eloc; epos->offset = sizeof(struct allocExtDesc); brelse(epos->bh); - block = udf_get_lb_pblock(inode->i_sb, epos->block, 0); + block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0); epos->bh = udf_tread(inode->i_sb, block); if (!epos->bh) { udf_debug("reading block %d failed!\n", block); @@ -1845,13 +1852,13 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, } int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, - kernel_lb_addr *eloc, uint32_t *elen, int inc) + struct kernel_lb_addr *eloc, uint32_t *elen, int inc) { int alen; int8_t etype; uint8_t *ptr; - short_ad *sad; - long_ad *lad; + struct short_ad *sad; + struct long_ad *lad; struct udf_inode_info *iinfo = UDF_I(inode); if (!epos->bh) { @@ -1900,9 +1907,9 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, } static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, - kernel_lb_addr neloc, uint32_t nelen) + struct kernel_lb_addr neloc, uint32_t nelen) { - kernel_lb_addr oeloc; + struct kernel_lb_addr oeloc; uint32_t oelen; int8_t etype; @@ -1910,18 +1917,18 @@ static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, get_bh(epos.bh); while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) { - udf_write_aext(inode, &epos, neloc, nelen, 1); + udf_write_aext(inode, &epos, &neloc, nelen, 1); neloc = oeloc; nelen = (etype << 30) | oelen; } - udf_add_aext(inode, &epos, neloc, nelen, 1); + udf_add_aext(inode, &epos, &neloc, nelen, 1); brelse(epos.bh); return (nelen >> 30); } int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, - kernel_lb_addr eloc, uint32_t elen) + struct kernel_lb_addr eloc, uint32_t elen) { struct extent_position oepos; int adsize; @@ -1936,9 +1943,9 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, iinfo = UDF_I(inode); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else adsize = 0; @@ -1947,7 +1954,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, return -1; while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { - udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1); + udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1); if (oepos.bh != epos.bh) { oepos.block = epos.block; brelse(oepos.bh); @@ -1956,13 +1963,13 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, oepos.offset = epos.offset - adsize; } } - memset(&eloc, 0x00, sizeof(kernel_lb_addr)); + memset(&eloc, 0x00, sizeof(struct kernel_lb_addr)); elen = 0; if (epos.bh != oepos.bh) { - udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1); - udf_write_aext(inode, &oepos, eloc, elen, 1); - udf_write_aext(inode, &oepos, eloc, elen, 1); + udf_free_blocks(inode->i_sb, inode, &epos.block, 0, 1); + udf_write_aext(inode, &oepos, &eloc, elen, 1); + udf_write_aext(inode, &oepos, &eloc, elen, 1); if (!oepos.bh) { iinfo->i_lenAlloc -= (adsize * 2); mark_inode_dirty(inode); @@ -1979,7 +1986,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, mark_buffer_dirty_inode(oepos.bh, inode); } } else { - udf_write_aext(inode, &oepos, eloc, elen, 1); + udf_write_aext(inode, &oepos, &eloc, elen, 1); if (!oepos.bh) { iinfo->i_lenAlloc -= adsize; mark_inode_dirty(inode); @@ -2004,7 +2011,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, } int8_t inode_bmap(struct inode *inode, sector_t block, - struct extent_position *pos, kernel_lb_addr *eloc, + struct extent_position *pos, struct kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) { unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; @@ -2036,7 +2043,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block, long udf_block_map(struct inode *inode, sector_t block) { - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen; sector_t offset; struct extent_position epos = {}; @@ -2046,7 +2053,7 @@ long udf_block_map(struct inode *inode, sector_t block) if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) - ret = udf_get_lb_pblock(inode->i_sb, eloc, offset); + ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset); else ret = 0; diff --git a/fs/udf/misc.c b/fs/udf/misc.c index 84bf0fd4a4f1..9215700c00a4 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c @@ -134,10 +134,10 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, } } /* rewrite CRC + checksum of eahd */ - crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); + crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(struct tag); eahd->descTag.descCRCLength = cpu_to_le16(crclen); eahd->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)eahd + - sizeof(tag), crclen)); + sizeof(struct tag), crclen)); eahd->descTag.tagChecksum = udf_tag_checksum(&eahd->descTag); iinfo->i_lenEAttr += size; return (struct genericFormat *)&ea[offset]; @@ -202,7 +202,7 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type, struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint16_t *ident) { - tag *tag_p; + struct tag *tag_p; struct buffer_head *bh = NULL; /* Read the block */ @@ -216,7 +216,7 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, return NULL; } - tag_p = (tag *)(bh->b_data); + tag_p = (struct tag *)(bh->b_data); *ident = le16_to_cpu(tag_p->tagIdent); @@ -241,9 +241,9 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, } /* Verify the descriptor CRC */ - if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || + if (le16_to_cpu(tag_p->descCRCLength) + sizeof(struct tag) > sb->s_blocksize || le16_to_cpu(tag_p->descCRC) == crc_itu_t(0, - bh->b_data + sizeof(tag), + bh->b_data + sizeof(struct tag), le16_to_cpu(tag_p->descCRCLength))) return bh; @@ -255,27 +255,28 @@ error_out: return NULL; } -struct buffer_head *udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, +struct buffer_head *udf_read_ptagged(struct super_block *sb, + struct kernel_lb_addr *loc, uint32_t offset, uint16_t *ident) { return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset), - loc.logicalBlockNum + offset, ident); + loc->logicalBlockNum + offset, ident); } void udf_update_tag(char *data, int length) { - tag *tptr = (tag *)data; - length -= sizeof(tag); + struct tag *tptr = (struct tag *)data; + length -= sizeof(struct tag); tptr->descCRCLength = cpu_to_le16(length); - tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(tag), length)); + tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(struct tag), length)); tptr->tagChecksum = udf_tag_checksum(tptr); } void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum, uint32_t loc, int length) { - tag *tptr = (tag *)data; + struct tag *tptr = (struct tag *)data; tptr->tagIdent = cpu_to_le16(ident); tptr->descVersion = cpu_to_le16(version); tptr->tagSerialNum = cpu_to_le16(snum); @@ -283,12 +284,12 @@ void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum, udf_update_tag(data, length); } -u8 udf_tag_checksum(const tag *t) +u8 udf_tag_checksum(const struct tag *t) { u8 *data = (u8 *)t; u8 checksum = 0; int i; - for (i = 0; i < sizeof(tag); ++i) + for (i = 0; i < sizeof(struct tag); ++i) if (i != 4) /* position of checksum */ checksum += data[i]; return checksum; diff --git a/fs/udf/namei.c b/fs/udf/namei.c index f84bfaa8d941..6a29fa34c478 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -47,7 +47,7 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh, uint8_t *impuse, uint8_t *fileident) { - uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag); + uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(struct tag); uint16_t crc; int offset; uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse); @@ -99,18 +99,18 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, memset(fibh->ebh->b_data, 0x00, padlen + offset); } - crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(tag), - sizeof(struct fileIdentDesc) - sizeof(tag)); + crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(struct tag), + sizeof(struct fileIdentDesc) - sizeof(struct tag)); if (fibh->sbh == fibh->ebh) { crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, - crclen + sizeof(tag) - + crclen + sizeof(struct tag) - sizeof(struct fileIdentDesc)); } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { crc = crc_itu_t(crc, fibh->ebh->b_data + sizeof(struct fileIdentDesc) + fibh->soffset, - crclen + sizeof(tag) - + crclen + sizeof(struct tag) - sizeof(struct fileIdentDesc)); } else { crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, @@ -154,7 +154,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, uint8_t lfi; uint16_t liu; loff_t size; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen; sector_t offset; struct extent_position epos = {}; @@ -171,12 +171,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) goto out_err; - block = udf_get_lb_pblock(dir->i_sb, eloc, offset); + block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - epos.offset -= sizeof(short_ad); + epos.offset -= sizeof(struct short_ad); else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - epos.offset -= sizeof(long_ad); + epos.offset -= sizeof(struct long_ad); } else offset = 0; @@ -268,7 +268,7 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, #ifdef UDF_RECOVERY /* temporary shorthand for specifying files by inode number */ if (!strncmp(dentry->d_name.name, ".B=", 3)) { - kernel_lb_addr lb = { + struct kernel_lb_addr lb = { .logicalBlockNum = 0, .partitionReferenceNum = simple_strtoul(dentry->d_name.name + 3, @@ -283,11 +283,14 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, #endif /* UDF_RECOVERY */ if (udf_find_entry(dir, &dentry->d_name, &fibh, &cfi)) { + struct kernel_lb_addr loc; + if (fibh.sbh != fibh.ebh) brelse(fibh.ebh); brelse(fibh.sbh); - inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); + loc = lelb_to_cpu(cfi.icb.extLocation); + inode = udf_iget(dir->i_sb, &loc); if (!inode) { unlock_kernel(); return ERR_PTR(-EACCES); @@ -313,7 +316,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, uint8_t lfi; uint16_t liu; int block; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen = 0; sector_t offset; struct extent_position epos = {}; @@ -351,16 +354,16 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) { block = udf_get_lb_pblock(dir->i_sb, - dinfo->i_location, 0); + &dinfo->i_location, 0); fibh->soffset = fibh->eoffset = sb->s_blocksize; goto add; } - block = udf_get_lb_pblock(dir->i_sb, eloc, offset); + block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - epos.offset -= sizeof(short_ad); + epos.offset -= sizeof(struct short_ad); else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - epos.offset -= sizeof(long_ad); + epos.offset -= sizeof(struct long_ad); } else offset = 0; @@ -409,10 +412,10 @@ add: if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) { elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - epos.offset -= sizeof(short_ad); + epos.offset -= sizeof(struct short_ad); else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - epos.offset -= sizeof(long_ad); - udf_write_aext(dir, &epos, eloc, elen, 1); + epos.offset -= sizeof(struct long_ad); + udf_write_aext(dir, &epos, &eloc, elen, 1); } f_pos += nfidlen; @@ -494,10 +497,10 @@ add: memset(cfi, 0, sizeof(struct fileIdentDesc)); if (UDF_SB(sb)->s_udfrev >= 0x0200) udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, - sizeof(tag)); + sizeof(struct tag)); else udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, - sizeof(tag)); + sizeof(struct tag)); cfi->fileVersionNum = cpu_to_le16(1); cfi->lengthFileIdent = namelen; cfi->lengthOfImpUse = cpu_to_le16(0); @@ -530,7 +533,7 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) - memset(&(cfi->icb), 0x00, sizeof(long_ad)); + memset(&(cfi->icb), 0x00, sizeof(struct long_ad)); return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); } @@ -710,7 +713,7 @@ static int empty_dir(struct inode *dir) loff_t f_pos; loff_t size = udf_ext0_offset(dir) + dir->i_size; int block; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen; sector_t offset; struct extent_position epos = {}; @@ -724,12 +727,12 @@ static int empty_dir(struct inode *dir) else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { - block = udf_get_lb_pblock(dir->i_sb, eloc, offset); + block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - epos.offset -= sizeof(short_ad); + epos.offset -= sizeof(struct short_ad); else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - epos.offset -= sizeof(long_ad); + epos.offset -= sizeof(struct long_ad); } else offset = 0; @@ -778,7 +781,7 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) struct inode *inode = dentry->d_inode; struct udf_fileident_bh fibh; struct fileIdentDesc *fi, cfi; - kernel_lb_addr tloc; + struct kernel_lb_addr tloc; retval = -ENOENT; lock_kernel(); @@ -788,7 +791,7 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) retval = -EIO; tloc = lelb_to_cpu(cfi.icb.extLocation); - if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino) + if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino) goto end_rmdir; retval = -ENOTEMPTY; if (!empty_dir(inode)) @@ -824,7 +827,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) struct udf_fileident_bh fibh; struct fileIdentDesc *fi; struct fileIdentDesc cfi; - kernel_lb_addr tloc; + struct kernel_lb_addr tloc; retval = -ENOENT; lock_kernel(); @@ -834,7 +837,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) retval = -EIO; tloc = lelb_to_cpu(cfi.icb.extLocation); - if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino) + if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino) goto end_unlink; if (!inode->i_nlink) { @@ -897,7 +900,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, inode->i_op = &page_symlink_inode_operations; if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t bsize; block = udf_new_block(inode->i_sb, inode, @@ -913,7 +916,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, iinfo->i_location.partitionReferenceNum; bsize = inode->i_sb->s_blocksize; iinfo->i_lenExtents = bsize; - udf_add_aext(inode, &epos, eloc, bsize, 0); + udf_add_aext(inode, &epos, &eloc, bsize, 0); brelse(epos.bh); block = udf_get_pblock(inode->i_sb, block, @@ -1108,7 +1111,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, struct fileIdentDesc ocfi, ncfi; struct buffer_head *dir_bh = NULL; int retval = -ENOENT; - kernel_lb_addr tloc; + struct kernel_lb_addr tloc; struct udf_inode_info *old_iinfo = UDF_I(old_inode); lock_kernel(); @@ -1119,7 +1122,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, brelse(ofibh.sbh); } tloc = lelb_to_cpu(ocfi.icb.extLocation); - if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0) + if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino) goto end_rename; @@ -1158,7 +1161,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, if (!dir_fi) goto end_rename; tloc = lelb_to_cpu(dir_fi->icb.extLocation); - if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0) != + if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) != old_dir->i_ino) goto end_rename; @@ -1187,7 +1190,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, */ ncfi.fileVersionNum = ocfi.fileVersionNum; ncfi.fileCharacteristics = ocfi.fileCharacteristics; - memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad)); + memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(struct long_ad)); udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL); /* The old fid may have moved - find it again */ @@ -1242,6 +1245,7 @@ end_rename: static struct dentry *udf_get_parent(struct dentry *child) { + struct kernel_lb_addr tloc; struct inode *inode = NULL; struct qstr dotdot = {.name = "..", .len = 2}; struct fileIdentDesc cfi; @@ -1255,8 +1259,8 @@ static struct dentry *udf_get_parent(struct dentry *child) brelse(fibh.ebh); brelse(fibh.sbh); - inode = udf_iget(child->d_inode->i_sb, - lelb_to_cpu(cfi.icb.extLocation)); + tloc = lelb_to_cpu(cfi.icb.extLocation); + inode = udf_iget(child->d_inode->i_sb, &tloc); if (!inode) goto out_unlock; unlock_kernel(); @@ -1272,14 +1276,14 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block, u16 partref, __u32 generation) { struct inode *inode; - kernel_lb_addr loc; + struct kernel_lb_addr loc; if (block == 0) return ERR_PTR(-ESTALE); loc.logicalBlockNum = block; loc.partitionReferenceNum = partref; - inode = udf_iget(sb, loc); + inode = udf_iget(sb, &loc); if (inode == NULL) return ERR_PTR(-ENOMEM); @@ -1318,7 +1322,7 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, { int len = *lenp; struct inode *inode = de->d_inode; - kernel_lb_addr location = UDF_I(inode)->i_location; + struct kernel_lb_addr location = UDF_I(inode)->i_location; struct fid *fid = (struct fid *)fh; int type = FILEID_UDF_WITHOUT_PARENT; diff --git a/fs/udf/osta_udf.h b/fs/udf/osta_udf.h index 65ff47902bd2..fbff74654df2 100644 --- a/fs/udf/osta_udf.h +++ b/fs/udf/osta_udf.h @@ -85,7 +85,7 @@ struct appIdentSuffix { /* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */ /* Implementation Use (UDF 2.50 2.2.6.4) */ struct logicalVolIntegrityDescImpUse { - regid impIdent; + struct regid impIdent; __le32 numFiles; __le32 numDirs; __le16 minUDFReadRev; @@ -97,12 +97,12 @@ struct logicalVolIntegrityDescImpUse { /* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */ /* Implementation Use (UDF 2.50 2.2.7.2) */ struct impUseVolDescImpUse { - charspec LVICharset; + struct charspec LVICharset; dstring logicalVolIdent[128]; dstring LVInfo1[36]; dstring LVInfo2[36]; dstring LVInfo3[36]; - regid impIdent; + struct regid impIdent; uint8_t impUse[128]; } __attribute__ ((packed)); @@ -110,7 +110,7 @@ struct udfPartitionMap2 { uint8_t partitionMapType; uint8_t partitionMapLength; uint8_t reserved1[2]; - regid partIdent; + struct regid partIdent; __le16 volSeqNum; __le16 partitionNum; } __attribute__ ((packed)); @@ -120,7 +120,7 @@ struct virtualPartitionMap { uint8_t partitionMapType; uint8_t partitionMapLength; uint8_t reserved1[2]; - regid partIdent; + struct regid partIdent; __le16 volSeqNum; __le16 partitionNum; uint8_t reserved2[24]; @@ -131,7 +131,7 @@ struct sparablePartitionMap { uint8_t partitionMapType; uint8_t partitionMapLength; uint8_t reserved1[2]; - regid partIdent; + struct regid partIdent; __le16 volSeqNum; __le16 partitionNum; __le16 packetLength; @@ -146,7 +146,7 @@ struct metadataPartitionMap { uint8_t partitionMapType; uint8_t partitionMapLength; uint8_t reserved1[2]; - regid partIdent; + struct regid partIdent; __le16 volSeqNum; __le16 partitionNum; __le32 metadataFileLoc; @@ -161,7 +161,7 @@ struct metadataPartitionMap { /* Virtual Allocation Table (UDF 1.5 2.2.10) */ struct virtualAllocationTable15 { __le32 VirtualSector[0]; - regid vatIdent; + struct regid vatIdent; __le32 previousVATICBLoc; } __attribute__ ((packed)); @@ -192,8 +192,8 @@ struct sparingEntry { } __attribute__ ((packed)); struct sparingTable { - tag descTag; - regid sparingIdent; + struct tag descTag; + struct regid sparingIdent; __le16 reallocationTableLen; __le16 reserved; __le32 sequenceNum; @@ -206,7 +206,7 @@ struct sparingTable { #define ICBTAG_FILE_TYPE_MIRROR 0xFB #define ICBTAG_FILE_TYPE_BITMAP 0xFC -/* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */ +/* struct struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */ struct allocDescImpUse { __le16 flags; uint8_t impUse[4]; diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 96dfd207c3d6..4b540ee632d5 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c @@ -273,7 +273,7 @@ static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, { struct super_block *sb = inode->i_sb; struct udf_part_map *map; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen; sector_t ext_offset; struct extent_position epos = {}; diff --git a/fs/udf/super.c b/fs/udf/super.c index e25e7010627b..72348cc855a4 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -81,16 +81,13 @@ static char error_buf[1024]; /* These are the "meat" - everything else is stuffing */ static int udf_fill_super(struct super_block *, void *, int); static void udf_put_super(struct super_block *); -static void udf_write_super(struct super_block *); +static int udf_sync_fs(struct super_block *, int); static int udf_remount_fs(struct super_block *, int *, char *); -static int udf_check_valid(struct super_block *, int, int); -static int udf_vrs(struct super_block *sb, int silent); -static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); -static void udf_find_anchor(struct super_block *); -static int udf_find_fileset(struct super_block *, kernel_lb_addr *, - kernel_lb_addr *); +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 *, - kernel_lb_addr *); + struct kernel_lb_addr *); static void udf_open_lvid(struct super_block *); static void udf_close_lvid(struct super_block *); static unsigned int udf_count_free(struct super_block *); @@ -181,7 +178,7 @@ static const struct super_operations udf_sb_ops = { .delete_inode = udf_delete_inode, .clear_inode = udf_clear_inode, .put_super = udf_put_super, - .write_super = udf_write_super, + .sync_fs = udf_sync_fs, .statfs = udf_statfs, .remount_fs = udf_remount_fs, .show_options = udf_show_options, @@ -201,6 +198,8 @@ struct udf_options { mode_t umask; gid_t gid; uid_t uid; + mode_t fmode; + mode_t dmode; struct nls_table *nls_map; }; @@ -258,7 +257,7 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt) if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) seq_puts(seq, ",nostrict"); - if (sb->s_blocksize != UDF_DEFAULT_BLOCKSIZE) + if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET)) seq_printf(seq, ",bs=%lu", sb->s_blocksize); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) seq_puts(seq, ",unhide"); @@ -282,18 +281,16 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt) seq_printf(seq, ",gid=%u", sbi->s_gid); if (sbi->s_umask != 0) seq_printf(seq, ",umask=%o", sbi->s_umask); + if (sbi->s_fmode != UDF_INVALID_MODE) + seq_printf(seq, ",mode=%o", sbi->s_fmode); + if (sbi->s_dmode != UDF_INVALID_MODE) + seq_printf(seq, ",dmode=%o", sbi->s_dmode); if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET)) seq_printf(seq, ",session=%u", sbi->s_session); if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET)) seq_printf(seq, ",lastblock=%u", sbi->s_last_block); - /* - * s_anchor[2] could be zeroed out in case there is no anchor - * in the specified block, but then the "anchor=N" option - * originally given by the user wasn't effective, so it's OK - * if we don't show it. - */ - if (sbi->s_anchor[2] != 0) - seq_printf(seq, ",anchor=%u", sbi->s_anchor[2]); + if (sbi->s_anchor != 0) + seq_printf(seq, ",anchor=%u", sbi->s_anchor); /* * volume, partition, fileset and rootdir seem to be ignored * currently @@ -317,6 +314,8 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt) * * gid= Set the default group. * umask= Set the default umask. + * mode= Set the default file permissions. + * dmode= Set the default directory permissions. * uid= Set the default user. * bs= Set the block size. * unhide Show otherwise hidden files. @@ -366,7 +365,8 @@ enum { Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, Opt_rootdir, Opt_utf8, Opt_iocharset, - Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore + Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore, + Opt_fmode, Opt_dmode }; static const match_table_t tokens = { @@ -395,6 +395,8 @@ static const match_table_t tokens = { {Opt_rootdir, "rootdir=%u"}, {Opt_utf8, "utf8"}, {Opt_iocharset, "iocharset=%s"}, + {Opt_fmode, "mode=%o"}, + {Opt_dmode, "dmode=%o"}, {Opt_err, NULL} }; @@ -405,7 +407,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt, int option; uopt->novrs = 0; - uopt->blocksize = UDF_DEFAULT_BLOCKSIZE; uopt->partition = 0xFFFF; uopt->session = 0xFFFFFFFF; uopt->lastblock = 0; @@ -428,10 +429,12 @@ static int udf_parse_options(char *options, struct udf_options *uopt, switch (token) { case Opt_novrs: uopt->novrs = 1; + break; case Opt_bs: if (match_int(&args[0], &option)) return 0; uopt->blocksize = option; + uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET); break; case Opt_unhide: uopt->flags |= (1 << UDF_FLAG_UNHIDE); @@ -531,6 +534,16 @@ static int udf_parse_options(char *options, struct udf_options *uopt, case Opt_gforget: uopt->flags |= (1 << UDF_FLAG_GID_FORGET); break; + case Opt_fmode: + if (match_octal(args, &option)) + return 0; + uopt->fmode = option & 0777; + break; + case Opt_dmode: + if (match_octal(args, &option)) + return 0; + uopt->dmode = option & 0777; + break; default: printk(KERN_ERR "udf: bad mount option \"%s\" " "or missing value\n", p); @@ -540,17 +553,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt, return 1; } -static void udf_write_super(struct super_block *sb) -{ - lock_kernel(); - - if (!(sb->s_flags & MS_RDONLY)) - udf_open_lvid(sb); - sb->s_dirt = 0; - - unlock_kernel(); -} - static int udf_remount_fs(struct super_block *sb, int *flags, char *options) { struct udf_options uopt; @@ -560,6 +562,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) uopt.uid = sbi->s_uid; uopt.gid = sbi->s_gid; uopt.umask = sbi->s_umask; + uopt.fmode = sbi->s_fmode; + uopt.dmode = sbi->s_dmode; if (!udf_parse_options(options, &uopt, true)) return -EINVAL; @@ -568,6 +572,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) sbi->s_uid = uopt.uid; sbi->s_gid = uopt.gid; sbi->s_umask = uopt.umask; + sbi->s_fmode = uopt.fmode; + sbi->s_dmode = uopt.dmode; if (sbi->s_lvid_bh) { int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); @@ -585,22 +591,19 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) return 0; } -static int udf_vrs(struct super_block *sb, int silent) +/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ +/* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ +static loff_t udf_check_vsd(struct super_block *sb) { struct volStructDesc *vsd = NULL; loff_t sector = 32768; int sectorsize; struct buffer_head *bh = NULL; - int iso9660 = 0; int nsr02 = 0; int nsr03 = 0; struct udf_sb_info *sbi; - /* Block size must be a multiple of 512 */ - if (sb->s_blocksize & 511) - return 0; sbi = UDF_SB(sb); - if (sb->s_blocksize < sizeof(struct volStructDesc)) sectorsize = sizeof(struct volStructDesc); else @@ -627,7 +630,6 @@ static int udf_vrs(struct super_block *sb, int silent) break; } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) { - iso9660 = sector; switch (vsd->structType) { case 0: udf_debug("ISO9660 Boot Record found\n"); @@ -679,139 +681,9 @@ static int udf_vrs(struct super_block *sb, int silent) return 0; } -/* - * Check whether there is an anchor block in the given block - */ -static int udf_check_anchor_block(struct super_block *sb, sector_t block) -{ - struct buffer_head *bh; - uint16_t ident; - - if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && - udf_fixed_to_variable(block) >= - sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) - return 0; - - bh = udf_read_tagged(sb, block, block, &ident); - if (!bh) - return 0; - brelse(bh); - - return ident == TAG_IDENT_AVDP; -} - -/* Search for an anchor volume descriptor pointer */ -static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) -{ - sector_t last[6]; - int i; - struct udf_sb_info *sbi = UDF_SB(sb); - - last[0] = lastblock; - last[1] = last[0] - 1; - last[2] = last[0] + 1; - last[3] = last[0] - 2; - last[4] = last[0] - 150; - last[5] = last[0] - 152; - - /* according to spec, anchor is in either: - * block 256 - * lastblock-256 - * lastblock - * however, if the disc isn't closed, it could be 512 */ - - for (i = 0; i < ARRAY_SIZE(last); i++) { - if (last[i] < 0) - continue; - if (last[i] >= sb->s_bdev->bd_inode->i_size >> - sb->s_blocksize_bits) - continue; - - if (udf_check_anchor_block(sb, last[i])) { - sbi->s_anchor[0] = last[i]; - sbi->s_anchor[1] = last[i] - 256; - return last[i]; - } - - if (last[i] < 256) - continue; - - if (udf_check_anchor_block(sb, last[i] - 256)) { - sbi->s_anchor[1] = last[i] - 256; - return last[i]; - } - } - - if (udf_check_anchor_block(sb, sbi->s_session + 256)) { - sbi->s_anchor[0] = sbi->s_session + 256; - return last[0]; - } - if (udf_check_anchor_block(sb, sbi->s_session + 512)) { - sbi->s_anchor[0] = sbi->s_session + 512; - return last[0]; - } - return 0; -} - -/* - * Find an anchor volume descriptor. The function expects sbi->s_lastblock to - * be the last block on the media. - * - * Return 1 if not found, 0 if ok - * - */ -static void udf_find_anchor(struct super_block *sb) -{ - sector_t lastblock; - struct buffer_head *bh = NULL; - uint16_t ident; - int i; - struct udf_sb_info *sbi = UDF_SB(sb); - - lastblock = udf_scan_anchors(sb, sbi->s_last_block); - if (lastblock) - goto check_anchor; - - /* No anchor found? Try VARCONV conversion of block numbers */ - UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); - /* Firstly, we try to not convert number of the last block */ - lastblock = udf_scan_anchors(sb, - udf_variable_to_fixed(sbi->s_last_block)); - if (lastblock) - goto check_anchor; - - /* Secondly, we try with converted number of the last block */ - lastblock = udf_scan_anchors(sb, sbi->s_last_block); - if (!lastblock) { - /* VARCONV didn't help. Clear it. */ - UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); - } - -check_anchor: - /* - * Check located anchors and the anchor block supplied via - * mount options - */ - for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { - if (!sbi->s_anchor[i]) - continue; - bh = udf_read_tagged(sb, sbi->s_anchor[i], - sbi->s_anchor[i], &ident); - if (!bh) - sbi->s_anchor[i] = 0; - else { - brelse(bh); - if (ident != TAG_IDENT_AVDP) - sbi->s_anchor[i] = 0; - } - } - - sbi->s_last_block = lastblock; -} - static int udf_find_fileset(struct super_block *sb, - kernel_lb_addr *fileset, - kernel_lb_addr *root) + struct kernel_lb_addr *fileset, + struct kernel_lb_addr *root) { struct buffer_head *bh = NULL; long lastblock; @@ -820,7 +692,7 @@ static int udf_find_fileset(struct super_block *sb, if (fileset->logicalBlockNum != 0xFFFFFFFF || fileset->partitionReferenceNum != 0xFFFF) { - bh = udf_read_ptagged(sb, *fileset, 0, &ident); + bh = udf_read_ptagged(sb, fileset, 0, &ident); if (!bh) { return 1; @@ -834,7 +706,7 @@ static int udf_find_fileset(struct super_block *sb, sbi = UDF_SB(sb); if (!bh) { /* Search backwards through the partitions */ - kernel_lb_addr newfileset; + struct kernel_lb_addr newfileset; /* --> cvg: FIXME - is it reasonable? */ return 1; @@ -850,7 +722,7 @@ static int udf_find_fileset(struct super_block *sb, newfileset.logicalBlockNum = 0; do { - bh = udf_read_ptagged(sb, newfileset, 0, + bh = udf_read_ptagged(sb, &newfileset, 0, &ident); if (!bh) { newfileset.logicalBlockNum++; @@ -902,14 +774,23 @@ static int udf_find_fileset(struct super_block *sb, static int udf_load_pvoldesc(struct super_block *sb, sector_t block) { struct primaryVolDesc *pvoldesc; - struct ustr instr; - struct ustr outstr; + struct ustr *instr, *outstr; struct buffer_head *bh; uint16_t ident; + int ret = 1; + + instr = kmalloc(sizeof(struct ustr), GFP_NOFS); + if (!instr) + return 1; + + outstr = kmalloc(sizeof(struct ustr), GFP_NOFS); + if (!outstr) + goto out1; bh = udf_read_tagged(sb, block, block, &ident); if (!bh) - return 1; + goto out2; + BUG_ON(ident != TAG_IDENT_PVD); pvoldesc = (struct primaryVolDesc *)bh->b_data; @@ -917,7 +798,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, pvoldesc->recordingDateAndTime)) { #ifdef UDFFS_DEBUG - timestamp *ts = &pvoldesc->recordingDateAndTime; + struct timestamp *ts = &pvoldesc->recordingDateAndTime; udf_debug("recording time %04u/%02u/%02u" " %02u:%02u (%x)\n", le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, @@ -925,20 +806,25 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) #endif } - if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) - if (udf_CS0toUTF8(&outstr, &instr)) { - strncpy(UDF_SB(sb)->s_volume_ident, outstr.u_name, - outstr.u_len > 31 ? 31 : outstr.u_len); + if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) + if (udf_CS0toUTF8(outstr, instr)) { + strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name, + outstr->u_len > 31 ? 31 : outstr->u_len); udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); } - if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) - if (udf_CS0toUTF8(&outstr, &instr)) - udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); + if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128)) + if (udf_CS0toUTF8(outstr, instr)) + udf_debug("volSetIdent[] = '%s'\n", outstr->u_name); brelse(bh); - return 0; + ret = 0; +out2: + kfree(outstr); +out1: + kfree(instr); + return ret; } static int udf_load_metadata_files(struct super_block *sb, int partition) @@ -946,7 +832,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map; struct udf_meta_data *mdata; - kernel_lb_addr addr; + struct kernel_lb_addr addr; int fe_error = 0; map = &sbi->s_partmaps[partition]; @@ -959,7 +845,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) udf_debug("Metadata file location: block = %d part = %d\n", addr.logicalBlockNum, addr.partitionReferenceNum); - mdata->s_metadata_fe = udf_iget(sb, addr); + mdata->s_metadata_fe = udf_iget(sb, &addr); if (mdata->s_metadata_fe == NULL) { udf_warning(sb, __func__, "metadata inode efe not found, " @@ -981,7 +867,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) udf_debug("Mirror metadata file location: block = %d part = %d\n", addr.logicalBlockNum, addr.partitionReferenceNum); - mdata->s_mirror_fe = udf_iget(sb, addr); + mdata->s_mirror_fe = udf_iget(sb, &addr); if (mdata->s_mirror_fe == NULL) { if (fe_error) { @@ -1013,7 +899,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) udf_debug("Bitmap file location: block = %d part = %d\n", addr.logicalBlockNum, addr.partitionReferenceNum); - mdata->s_bitmap_fe = udf_iget(sb, addr); + mdata->s_bitmap_fe = udf_iget(sb, &addr); if (mdata->s_bitmap_fe == NULL) { if (sb->s_flags & MS_RDONLY) @@ -1037,7 +923,7 @@ error_exit: } static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, - kernel_lb_addr *root) + struct kernel_lb_addr *root) { struct fileSetDesc *fset; @@ -1119,13 +1005,13 @@ static int udf_fill_partdesc_info(struct super_block *sb, phd = (struct partitionHeaderDesc *)p->partitionContentsUse; if (phd->unallocSpaceTable.extLength) { - kernel_lb_addr loc = { + struct kernel_lb_addr loc = { .logicalBlockNum = le32_to_cpu( phd->unallocSpaceTable.extPosition), .partitionReferenceNum = p_index, }; - map->s_uspace.s_table = udf_iget(sb, loc); + map->s_uspace.s_table = udf_iget(sb, &loc); if (!map->s_uspace.s_table) { udf_debug("cannot load unallocSpaceTable (part %d)\n", p_index); @@ -1154,13 +1040,13 @@ static int udf_fill_partdesc_info(struct super_block *sb, udf_debug("partitionIntegrityTable (part %d)\n", p_index); if (phd->freedSpaceTable.extLength) { - kernel_lb_addr loc = { + struct kernel_lb_addr loc = { .logicalBlockNum = le32_to_cpu( phd->freedSpaceTable.extPosition), .partitionReferenceNum = p_index, }; - map->s_fspace.s_table = udf_iget(sb, loc); + map->s_fspace.s_table = udf_iget(sb, &loc); if (!map->s_fspace.s_table) { udf_debug("cannot load freedSpaceTable (part %d)\n", p_index); @@ -1192,7 +1078,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) { struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map = &sbi->s_partmaps[p_index]; - kernel_lb_addr ino; + struct kernel_lb_addr ino; struct buffer_head *bh = NULL; struct udf_inode_info *vati; uint32_t pos; @@ -1201,7 +1087,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) /* VAT file entry is in the last recorded block */ ino.partitionReferenceNum = type1_index; ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root; - sbi->s_vat_inode = udf_iget(sb, ino); + sbi->s_vat_inode = udf_iget(sb, &ino); if (!sbi->s_vat_inode) return 1; @@ -1322,7 +1208,7 @@ out_bh: } static int udf_load_logicalvol(struct super_block *sb, sector_t block, - kernel_lb_addr *fileset) + struct kernel_lb_addr *fileset) { struct logicalVolDesc *lvd; int i, j, offset; @@ -1471,7 +1357,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, } if (fileset) { - long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]); + struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]); *fileset = lelb_to_cpu(la->extLocation); udf_debug("FileSet found in LogicalVolDesc at block=%d, " @@ -1490,7 +1376,7 @@ out_bh: * udf_load_logicalvolint * */ -static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) +static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc) { struct buffer_head *bh = NULL; uint16_t ident; @@ -1533,7 +1419,7 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) * Written, tested, and released. */ static noinline int udf_process_sequence(struct super_block *sb, long block, - long lastblock, kernel_lb_addr *fileset) + long lastblock, struct kernel_lb_addr *fileset) { struct buffer_head *bh = NULL; struct udf_vds_record vds[VDS_POS_LENGTH]; @@ -1655,85 +1541,199 @@ static noinline int udf_process_sequence(struct super_block *sb, long block, return 0; } +static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh, + struct kernel_lb_addr *fileset) +{ + struct anchorVolDescPtr *anchor; + long main_s, main_e, reserve_s, reserve_e; + struct udf_sb_info *sbi; + + sbi = UDF_SB(sb); + anchor = (struct anchorVolDescPtr *)bh->b_data; + + /* Locate the main sequence */ + main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation); + main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength); + main_e = main_e >> sb->s_blocksize_bits; + main_e += main_s; + + /* Locate the reserve sequence */ + reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation); + reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength); + reserve_e = reserve_e >> sb->s_blocksize_bits; + reserve_e += reserve_s; + + /* Process the main & reserve sequences */ + /* responsible for finding the PartitionDesc(s) */ + if (!udf_process_sequence(sb, main_s, main_e, fileset)) + return 1; + return !udf_process_sequence(sb, reserve_s, reserve_e, fileset); +} + /* - * udf_check_valid() + * Check whether there is an anchor block in the given block and + * load Volume Descriptor Sequence if so. */ -static int udf_check_valid(struct super_block *sb, int novrs, int silent) +static int udf_check_anchor_block(struct super_block *sb, sector_t block, + struct kernel_lb_addr *fileset) { - long block; - struct udf_sb_info *sbi = UDF_SB(sb); + struct buffer_head *bh; + uint16_t ident; + int ret; - if (novrs) { - udf_debug("Validity check skipped because of novrs option\n"); + if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && + udf_fixed_to_variable(block) >= + sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) + return 0; + + bh = udf_read_tagged(sb, block, block, &ident); + if (!bh) + return 0; + if (ident != TAG_IDENT_AVDP) { + brelse(bh); return 0; } - /* Check that it is NSR02 compliant */ - /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ - block = udf_vrs(sb, silent); - if (block == -1) - udf_debug("Failed to read byte 32768. Assuming open " - "disc. Skipping validity check\n"); - if (block && !sbi->s_last_block) - sbi->s_last_block = udf_get_last_block(sb); - return !block; + ret = udf_load_sequence(sb, bh, fileset); + brelse(bh); + return ret; } -static int udf_load_sequence(struct super_block *sb, kernel_lb_addr *fileset) +/* Search for an anchor volume descriptor pointer */ +static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock, + struct kernel_lb_addr *fileset) { - struct anchorVolDescPtr *anchor; - uint16_t ident; - struct buffer_head *bh; - long main_s, main_e, reserve_s, reserve_e; + sector_t last[6]; int i; - struct udf_sb_info *sbi; - - if (!sb) - return 1; - sbi = UDF_SB(sb); + struct udf_sb_info *sbi = UDF_SB(sb); + int last_count = 0; - for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { - if (!sbi->s_anchor[i]) + /* First try user provided anchor */ + if (sbi->s_anchor) { + if (udf_check_anchor_block(sb, sbi->s_anchor, fileset)) + return lastblock; + } + /* + * according to spec, anchor is in either: + * block 256 + * lastblock-256 + * lastblock + * however, if the disc isn't closed, it could be 512. + */ + if (udf_check_anchor_block(sb, sbi->s_session + 256, fileset)) + return lastblock; + /* + * The trouble is which block is the last one. Drives often misreport + * this so we try various possibilities. + */ + last[last_count++] = lastblock; + if (lastblock >= 1) + last[last_count++] = lastblock - 1; + last[last_count++] = lastblock + 1; + if (lastblock >= 2) + last[last_count++] = lastblock - 2; + if (lastblock >= 150) + last[last_count++] = lastblock - 150; + if (lastblock >= 152) + last[last_count++] = lastblock - 152; + + for (i = 0; i < last_count; i++) { + if (last[i] >= sb->s_bdev->bd_inode->i_size >> + sb->s_blocksize_bits) continue; - - bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i], - &ident); - if (!bh) + if (udf_check_anchor_block(sb, last[i], fileset)) + return last[i]; + if (last[i] < 256) continue; + if (udf_check_anchor_block(sb, last[i] - 256, fileset)) + return last[i]; + } - anchor = (struct anchorVolDescPtr *)bh->b_data; + /* Finally try block 512 in case media is open */ + if (udf_check_anchor_block(sb, sbi->s_session + 512, fileset)) + return last[0]; + return 0; +} - /* Locate the main sequence */ - main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation); - main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength); - main_e = main_e >> sb->s_blocksize_bits; - main_e += main_s; +/* + * Find an anchor volume descriptor and load Volume Descriptor Sequence from + * area specified by it. The function expects sbi->s_lastblock to be the last + * block on the media. + * + * Return 1 if ok, 0 if not found. + * + */ +static int udf_find_anchor(struct super_block *sb, + struct kernel_lb_addr *fileset) +{ + sector_t lastblock; + struct udf_sb_info *sbi = UDF_SB(sb); - /* Locate the reserve sequence */ - reserve_s = le32_to_cpu( - anchor->reserveVolDescSeqExt.extLocation); - reserve_e = le32_to_cpu( - anchor->reserveVolDescSeqExt.extLength); - reserve_e = reserve_e >> sb->s_blocksize_bits; - reserve_e += reserve_s; + lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset); + if (lastblock) + goto out; - brelse(bh); + /* No anchor found? Try VARCONV conversion of block numbers */ + UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); + /* Firstly, we try to not convert number of the last block */ + lastblock = udf_scan_anchors(sb, + udf_variable_to_fixed(sbi->s_last_block), + fileset); + if (lastblock) + goto out; - /* Process the main & reserve sequences */ - /* responsible for finding the PartitionDesc(s) */ - if (!(udf_process_sequence(sb, main_s, main_e, - fileset) && - udf_process_sequence(sb, reserve_s, reserve_e, - fileset))) - break; + /* Secondly, we try with converted number of the last block */ + lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset); + if (!lastblock) { + /* VARCONV didn't help. Clear it. */ + UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); + return 0; } +out: + sbi->s_last_block = lastblock; + return 1; +} - if (i == ARRAY_SIZE(sbi->s_anchor)) { - udf_debug("No Anchor block found\n"); - return 1; +/* + * Check Volume Structure Descriptor, find Anchor block and load Volume + * Descriptor Sequence + */ +static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, + int silent, struct kernel_lb_addr *fileset) +{ + struct udf_sb_info *sbi = UDF_SB(sb); + loff_t nsr_off; + + if (!sb_set_blocksize(sb, uopt->blocksize)) { + if (!silent) + printk(KERN_WARNING "UDF-fs: Bad block size\n"); + return 0; + } + sbi->s_last_block = uopt->lastblock; + if (!uopt->novrs) { + /* Check that it is NSR02 compliant */ + nsr_off = udf_check_vsd(sb); + if (!nsr_off) { + if (!silent) + printk(KERN_WARNING "UDF-fs: No VRS found\n"); + return 0; + } + if (nsr_off == -1) + udf_debug("Failed to read byte 32768. Assuming open " + "disc. Skipping validity check\n"); + if (!sbi->s_last_block) + sbi->s_last_block = udf_get_last_block(sb); + } else { + udf_debug("Validity check skipped because of novrs option\n"); } - udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]); - return 0; + /* Look for anchor block and load Volume Descriptor Sequence */ + sbi->s_anchor = uopt->anchor; + if (!udf_find_anchor(sb, fileset)) { + if (!silent) + printk(KERN_WARNING "UDF-fs: No anchor found\n"); + return 0; + } + return 1; } static void udf_open_lvid(struct super_block *sb) @@ -1742,9 +1742,9 @@ static void udf_open_lvid(struct super_block *sb) struct buffer_head *bh = sbi->s_lvid_bh; struct logicalVolIntegrityDesc *lvid; struct logicalVolIntegrityDescImpUse *lvidiu; + if (!bh) return; - lvid = (struct logicalVolIntegrityDesc *)bh->b_data; lvidiu = udf_sb_lvidiu(sbi); @@ -1752,14 +1752,15 @@ static void udf_open_lvid(struct super_block *sb) lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); - lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; + lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN); lvid->descTag.descCRC = cpu_to_le16( - crc_itu_t(0, (char *)lvid + sizeof(tag), + crc_itu_t(0, (char *)lvid + sizeof(struct tag), le16_to_cpu(lvid->descTag.descCRCLength))); lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); mark_buffer_dirty(bh); + sbi->s_lvid_dirty = 0; } static void udf_close_lvid(struct super_block *sb) @@ -1773,10 +1774,6 @@ static void udf_close_lvid(struct super_block *sb) return; lvid = (struct logicalVolIntegrityDesc *)bh->b_data; - - if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN) - return; - lvidiu = udf_sb_lvidiu(sbi); lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; @@ -1790,11 +1787,12 @@ static void udf_close_lvid(struct super_block *sb) lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); lvid->descTag.descCRC = cpu_to_le16( - crc_itu_t(0, (char *)lvid + sizeof(tag), + crc_itu_t(0, (char *)lvid + sizeof(struct tag), le16_to_cpu(lvid->descTag.descCRCLength))); lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); mark_buffer_dirty(bh); + sbi->s_lvid_dirty = 0; } static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) @@ -1846,15 +1844,18 @@ static void udf_free_partition(struct udf_part_map *map) static int udf_fill_super(struct super_block *sb, void *options, int silent) { int i; + int ret; struct inode *inode = NULL; struct udf_options uopt; - kernel_lb_addr rootdir, fileset; + struct kernel_lb_addr rootdir, fileset; struct udf_sb_info *sbi; uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); uopt.uid = -1; uopt.gid = -1; uopt.umask = 0; + uopt.fmode = UDF_INVALID_MODE; + uopt.dmode = UDF_INVALID_MODE; sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); if (!sbi) @@ -1892,15 +1893,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) sbi->s_uid = uopt.uid; sbi->s_gid = uopt.gid; sbi->s_umask = uopt.umask; + sbi->s_fmode = uopt.fmode; + sbi->s_dmode = uopt.dmode; sbi->s_nls_map = uopt.nls_map; - /* Set the block size for all transfers */ - if (!sb_min_blocksize(sb, uopt.blocksize)) { - udf_debug("Bad block size (%d)\n", uopt.blocksize); - printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize); - goto error_out; - } - if (uopt.session == 0xFFFFFFFF) sbi->s_session = udf_get_last_session(sb); else @@ -1908,18 +1904,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) udf_debug("Multi-session=%d\n", sbi->s_session); - sbi->s_last_block = uopt.lastblock; - sbi->s_anchor[0] = sbi->s_anchor[1] = 0; - sbi->s_anchor[2] = uopt.anchor; - - if (udf_check_valid(sb, uopt.novrs, silent)) { - /* read volume recognition sequences */ - printk(KERN_WARNING "UDF-fs: No VRS found\n"); - goto error_out; - } - - udf_find_anchor(sb); - /* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; sb->s_export_op = &udf_export_ops; @@ -1928,7 +1912,21 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) sb->s_magic = UDF_SUPER_MAGIC; sb->s_time_gran = 1000; - if (udf_load_sequence(sb, &fileset)) { + if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { + ret = udf_load_vrs(sb, &uopt, silent, &fileset); + } else { + uopt.blocksize = bdev_hardsect_size(sb->s_bdev); + ret = udf_load_vrs(sb, &uopt, silent, &fileset); + if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { + if (!silent) + printk(KERN_NOTICE + "UDF-fs: Rescanning with blocksize " + "%d\n", UDF_DEFAULT_BLOCKSIZE); + uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; + ret = udf_load_vrs(sb, &uopt, silent, &fileset); + } + } + if (!ret) { printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); goto error_out; } @@ -1978,7 +1976,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) } if (!silent) { - timestamp ts; + struct timestamp ts; udf_time_to_disk_stamp(&ts, sbi->s_record_time); udf_info("UDF: Mounting volume '%s', " "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", @@ -1991,7 +1989,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) /* Assign the root inode */ /* assign inodes by physical block number */ /* perhaps it's not extensible enough, but for now ... */ - inode = udf_iget(sb, rootdir); + inode = udf_iget(sb, &rootdir); if (!inode) { printk(KERN_ERR "UDF-fs: Error in udf_iget, block=%d, " "partition=%d\n", @@ -2081,11 +2079,31 @@ static void udf_put_super(struct super_block *sb) sb->s_fs_info = NULL; } +static int udf_sync_fs(struct super_block *sb, int wait) +{ + struct udf_sb_info *sbi = UDF_SB(sb); + + mutex_lock(&sbi->s_alloc_mutex); + if (sbi->s_lvid_dirty) { + /* + * Blockdevice will be synced later so we don't have to submit + * the buffer for IO + */ + mark_buffer_dirty(sbi->s_lvid_bh); + sb->s_dirt = 0; + sbi->s_lvid_dirty = 0; + } + mutex_unlock(&sbi->s_alloc_mutex); + + return 0; +} + static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDescImpUse *lvidiu; + u64 id = huge_encode_dev(sb->s_bdev->bd_dev); if (sbi->s_lvid_bh != NULL) lvidiu = udf_sb_lvidiu(sbi); @@ -2101,8 +2119,9 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) le32_to_cpu(lvidiu->numDirs)) : 0) + buf->f_bfree; buf->f_ffree = buf->f_bfree; - /* __kernel_fsid_t f_fsid */ buf->f_namelen = UDF_NAME_LEN - 2; + buf->f_fsid.val[0] = (u32)id; + buf->f_fsid.val[1] = (u32)(id >> 32); return 0; } @@ -2114,7 +2133,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, unsigned int accum = 0; int index; int block = 0, newblock; - kernel_lb_addr loc; + struct kernel_lb_addr loc; uint32_t bytes; uint8_t *ptr; uint16_t ident; @@ -2124,7 +2143,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, loc.logicalBlockNum = bitmap->s_extPosition; loc.partitionReferenceNum = UDF_SB(sb)->s_partition; - bh = udf_read_ptagged(sb, loc, 0, &ident); + bh = udf_read_ptagged(sb, &loc, 0, &ident); if (!bh) { printk(KERN_ERR "udf: udf_count_free failed\n"); @@ -2147,7 +2166,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, bytes -= cur_bytes; if (bytes) { brelse(bh); - newblock = udf_get_lb_pblock(sb, loc, ++block); + newblock = udf_get_lb_pblock(sb, &loc, ++block); bh = udf_tread(sb, newblock); if (!bh) { udf_debug("read failed\n"); @@ -2170,7 +2189,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, { unsigned int accum = 0; uint32_t elen; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; int8_t etype; struct extent_position epos; diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 65e19b4f9424..225527cdc885 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -28,10 +28,10 @@ #include "udf_sb.h" static void extent_trunc(struct inode *inode, struct extent_position *epos, - kernel_lb_addr eloc, int8_t etype, uint32_t elen, + struct kernel_lb_addr *eloc, int8_t etype, uint32_t elen, uint32_t nelen) { - kernel_lb_addr neloc = {}; + struct kernel_lb_addr neloc = {}; int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> @@ -43,12 +43,12 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos, last_block); etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30); } else - neloc = eloc; + neloc = *eloc; nelen = (etype << 30) | nelen; } if (elen != nelen) { - udf_write_aext(inode, epos, neloc, nelen, 0); + udf_write_aext(inode, epos, &neloc, nelen, 0); if (last_block - first_block > 0) { if (etype == (EXT_RECORDED_ALLOCATED >> 30)) mark_inode_dirty(inode); @@ -68,7 +68,7 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos, void udf_truncate_tail_extent(struct inode *inode) { struct extent_position epos = {}; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen, nelen; uint64_t lbcount = 0; int8_t etype = -1, netype; @@ -83,9 +83,9 @@ void udf_truncate_tail_extent(struct inode *inode) return; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else BUG(); @@ -106,7 +106,7 @@ void udf_truncate_tail_extent(struct inode *inode) (unsigned)elen); nelen = elen - (lbcount - inode->i_size); epos.offset -= adsize; - extent_trunc(inode, &epos, eloc, etype, elen, nelen); + extent_trunc(inode, &epos, &eloc, etype, elen, nelen); epos.offset += adsize; if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1) printk(KERN_ERR "udf_truncate_tail_extent(): " @@ -124,7 +124,7 @@ void udf_truncate_tail_extent(struct inode *inode) void udf_discard_prealloc(struct inode *inode) { struct extent_position epos = { NULL, 0, {0, 0} }; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; uint32_t elen; uint64_t lbcount = 0; int8_t etype = -1, netype; @@ -136,9 +136,9 @@ void udf_discard_prealloc(struct inode *inode) return; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else adsize = 0; @@ -152,7 +152,7 @@ void udf_discard_prealloc(struct inode *inode) if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { epos.offset -= adsize; lbcount -= elen; - extent_trunc(inode, &epos, eloc, etype, elen, 0); + extent_trunc(inode, &epos, &eloc, etype, elen, 0); if (!epos.bh) { iinfo->i_lenAlloc = epos.offset - @@ -200,7 +200,7 @@ static void udf_update_alloc_ext_desc(struct inode *inode, void udf_truncate_extents(struct inode *inode) { struct extent_position epos; - kernel_lb_addr eloc, neloc = {}; + struct kernel_lb_addr eloc, neloc = {}; uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; int8_t etype; struct super_block *sb = inode->i_sb; @@ -210,9 +210,9 @@ void udf_truncate_extents(struct inode *inode) struct udf_inode_info *iinfo = UDF_I(inode); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else BUG(); @@ -221,7 +221,7 @@ void udf_truncate_extents(struct inode *inode) (inode->i_size & (sb->s_blocksize - 1)); if (etype != -1) { epos.offset -= adsize; - extent_trunc(inode, &epos, eloc, etype, elen, byte_offset); + extent_trunc(inode, &epos, &eloc, etype, elen, byte_offset); epos.offset += adsize; if (byte_offset) lenalloc = epos.offset; @@ -236,12 +236,12 @@ void udf_truncate_extents(struct inode *inode) while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) { if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { - udf_write_aext(inode, &epos, neloc, nelen, 0); + udf_write_aext(inode, &epos, &neloc, nelen, 0); if (indirect_ext_len) { /* We managed to free all extents in the * indirect extent - free it too */ BUG_ON(!epos.bh); - udf_free_blocks(sb, inode, epos.block, + udf_free_blocks(sb, inode, &epos.block, 0, indirect_ext_len); } else if (!epos.bh) { iinfo->i_lenAlloc = lenalloc; @@ -253,7 +253,7 @@ void udf_truncate_extents(struct inode *inode) epos.offset = sizeof(struct allocExtDesc); epos.block = eloc; epos.bh = udf_tread(sb, - udf_get_lb_pblock(sb, eloc, 0)); + udf_get_lb_pblock(sb, &eloc, 0)); if (elen) indirect_ext_len = (elen + sb->s_blocksize - 1) >> @@ -261,7 +261,7 @@ void udf_truncate_extents(struct inode *inode) else indirect_ext_len = 1; } else { - extent_trunc(inode, &epos, eloc, etype, + extent_trunc(inode, &epos, &eloc, etype, elen, 0); epos.offset += adsize; } @@ -269,7 +269,7 @@ void udf_truncate_extents(struct inode *inode) if (indirect_ext_len) { BUG_ON(!epos.bh); - udf_free_blocks(sb, inode, epos.block, 0, + udf_free_blocks(sb, inode, &epos.block, 0, indirect_ext_len); } else if (!epos.bh) { iinfo->i_lenAlloc = lenalloc; @@ -278,7 +278,7 @@ void udf_truncate_extents(struct inode *inode) udf_update_alloc_ext_desc(inode, &epos, lenalloc); } else if (inode->i_size) { if (byte_offset) { - kernel_long_ad extent; + struct kernel_long_ad extent; /* * OK, there is not extent covering inode->i_size and diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index 4f86b1d98a5d..e58d1de41073 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h @@ -4,7 +4,7 @@ struct udf_inode_info { struct timespec i_crtime; /* Physical address of inode */ - kernel_lb_addr i_location; + struct kernel_lb_addr i_location; __u64 i_unique; __u32 i_lenEAttr; __u32 i_lenAlloc; @@ -17,8 +17,8 @@ struct udf_inode_info { unsigned i_strat4096 : 1; unsigned reserved : 26; union { - short_ad *i_sad; - long_ad *i_lad; + struct short_ad *i_sad; + struct long_ad *i_lad; __u8 *i_data; } i_ext; struct inode vfs_inode; diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 1c1c514a9725..d113b72c2768 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h @@ -30,6 +30,7 @@ #define UDF_FLAG_GID_SET 16 #define UDF_FLAG_SESSION_SET 17 #define UDF_FLAG_LASTBLOCK_SET 18 +#define UDF_FLAG_BLOCKSIZE_SET 19 #define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001 #define UDF_PART_FLAG_UNALLOC_TABLE 0x0002 @@ -48,6 +49,8 @@ #define UDF_SPARABLE_MAP15 0x1522U #define UDF_METADATA_MAP25 0x2511U +#define UDF_INVALID_MODE ((mode_t)-1) + #pragma pack(1) /* XXX(hch): Why? This file just defines in-core structures */ struct udf_meta_data { @@ -114,7 +117,7 @@ struct udf_sb_info { /* Sector headers */ __s32 s_session; - __u32 s_anchor[3]; + __u32 s_anchor; __u32 s_last_block; struct buffer_head *s_lvid_bh; @@ -123,6 +126,8 @@ struct udf_sb_info { mode_t s_umask; gid_t s_gid; uid_t s_uid; + mode_t s_fmode; + mode_t s_dmode; /* Root Info */ struct timespec s_record_time; @@ -143,6 +148,8 @@ struct udf_sb_info { struct inode *s_vat_inode; struct mutex s_alloc_mutex; + /* Protected by s_alloc_mutex */ + unsigned int s_lvid_dirty; }; static inline struct udf_sb_info *UDF_SB(struct super_block *sb) diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 8ec865de5f13..cac51b77a5d1 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -62,10 +62,8 @@ static inline size_t udf_ext0_offset(struct inode *inode) return 0; } -#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset)) - /* computes tag checksum */ -u8 udf_tag_checksum(const tag *t); +u8 udf_tag_checksum(const struct tag *t); struct dentry; struct inode; @@ -95,7 +93,7 @@ struct udf_vds_record { }; struct generic_desc { - tag descTag; + struct tag descTag; __le32 volDescSeqNum; }; @@ -108,11 +106,22 @@ struct ustr { struct extent_position { struct buffer_head *bh; uint32_t offset; - kernel_lb_addr block; + struct kernel_lb_addr block; }; /* super.c */ extern void udf_warning(struct super_block *, const char *, const char *, ...); +static inline void udf_updated_lvid(struct super_block *sb) +{ + struct buffer_head *bh = UDF_SB(sb)->s_lvid_bh; + + BUG_ON(!bh); + WARN_ON_ONCE(((struct logicalVolIntegrityDesc *) + bh->b_data)->integrityType != + cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN)); + sb->s_dirt = 1; + UDF_SB(sb)->s_lvid_dirty = 1; +} /* namei.c */ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, @@ -124,7 +133,7 @@ extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long); /* inode.c */ -extern struct inode *udf_iget(struct super_block *, kernel_lb_addr); +extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); extern int udf_sync_inode(struct inode *); extern void udf_expand_file_adinicb(struct inode *, int, int *); extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *); @@ -136,19 +145,19 @@ extern void udf_clear_inode(struct inode *); extern int udf_write_inode(struct inode *, int); extern long udf_block_map(struct inode *, sector_t); extern int udf_extend_file(struct inode *, struct extent_position *, - kernel_long_ad *, sector_t); + struct kernel_long_ad *, sector_t); extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, - kernel_lb_addr *, uint32_t *, sector_t *); + struct kernel_lb_addr *, uint32_t *, sector_t *); extern int8_t udf_add_aext(struct inode *, struct extent_position *, - kernel_lb_addr, uint32_t, int); + struct kernel_lb_addr *, uint32_t, int); extern int8_t udf_write_aext(struct inode *, struct extent_position *, - kernel_lb_addr, uint32_t, int); + struct kernel_lb_addr *, uint32_t, int); extern int8_t udf_delete_aext(struct inode *, struct extent_position, - kernel_lb_addr, uint32_t); + struct kernel_lb_addr, uint32_t); extern int8_t udf_next_aext(struct inode *, struct extent_position *, - kernel_lb_addr *, uint32_t *, int); + struct kernel_lb_addr *, uint32_t *, int); extern int8_t udf_current_aext(struct inode *, struct extent_position *, - kernel_lb_addr *, uint32_t *, int); + struct kernel_lb_addr *, uint32_t *, int); /* misc.c */ extern struct buffer_head *udf_tgetblk(struct super_block *, int); @@ -160,7 +169,7 @@ extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *); extern struct buffer_head *udf_read_ptagged(struct super_block *, - kernel_lb_addr, uint32_t, + struct kernel_lb_addr *, uint32_t, uint16_t *); extern void udf_update_tag(char *, int); extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); @@ -182,6 +191,14 @@ extern uint32_t udf_get_pblock_meta25(struct super_block *, uint32_t, uint16_t, uint32_t); extern int udf_relocate_blocks(struct super_block *, long, long *); +static inline uint32_t +udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, + uint32_t offset) +{ + return udf_get_pblock(sb, loc->logicalBlockNum, + loc->partitionReferenceNum, offset); +} + /* unicode.c */ extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, @@ -200,7 +217,7 @@ extern void udf_truncate_extents(struct inode *); /* balloc.c */ extern void udf_free_blocks(struct super_block *, struct inode *, - kernel_lb_addr, uint32_t, uint32_t); + struct kernel_lb_addr *, uint32_t, uint32_t); extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, uint32_t, uint32_t); extern int udf_new_block(struct super_block *, struct inode *, uint16_t, @@ -214,16 +231,16 @@ extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, struct extent_position *, - kernel_lb_addr *, uint32_t *, + struct kernel_lb_addr *, uint32_t *, sector_t *); extern struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset); -extern long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int); -extern short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int); +extern struct long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int); +extern struct short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int); /* udftime.c */ extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest, - timestamp src); -extern timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec src); + struct timestamp src); +extern struct timestamp *udf_time_to_disk_stamp(struct timestamp *dest, struct timespec src); #endif /* __UDF_DECL_H */ diff --git a/fs/udf/udfend.h b/fs/udf/udfend.h index 489f52fb428c..6a9f3a9cc428 100644 --- a/fs/udf/udfend.h +++ b/fs/udf/udfend.h @@ -4,9 +4,9 @@ #include <asm/byteorder.h> #include <linux/string.h> -static inline kernel_lb_addr lelb_to_cpu(lb_addr in) +static inline struct kernel_lb_addr lelb_to_cpu(struct lb_addr in) { - kernel_lb_addr out; + struct kernel_lb_addr out; out.logicalBlockNum = le32_to_cpu(in.logicalBlockNum); out.partitionReferenceNum = le16_to_cpu(in.partitionReferenceNum); @@ -14,9 +14,9 @@ static inline kernel_lb_addr lelb_to_cpu(lb_addr in) return out; } -static inline lb_addr cpu_to_lelb(kernel_lb_addr in) +static inline struct lb_addr cpu_to_lelb(struct kernel_lb_addr in) { - lb_addr out; + struct lb_addr out; out.logicalBlockNum = cpu_to_le32(in.logicalBlockNum); out.partitionReferenceNum = cpu_to_le16(in.partitionReferenceNum); @@ -24,9 +24,9 @@ static inline lb_addr cpu_to_lelb(kernel_lb_addr in) return out; } -static inline short_ad lesa_to_cpu(short_ad in) +static inline struct short_ad lesa_to_cpu(struct short_ad in) { - short_ad out; + struct short_ad out; out.extLength = le32_to_cpu(in.extLength); out.extPosition = le32_to_cpu(in.extPosition); @@ -34,9 +34,9 @@ static inline short_ad lesa_to_cpu(short_ad in) return out; } -static inline short_ad cpu_to_lesa(short_ad in) +static inline struct short_ad cpu_to_lesa(struct short_ad in) { - short_ad out; + struct short_ad out; out.extLength = cpu_to_le32(in.extLength); out.extPosition = cpu_to_le32(in.extPosition); @@ -44,9 +44,9 @@ static inline short_ad cpu_to_lesa(short_ad in) return out; } -static inline kernel_long_ad lela_to_cpu(long_ad in) +static inline struct kernel_long_ad lela_to_cpu(struct long_ad in) { - kernel_long_ad out; + struct kernel_long_ad out; out.extLength = le32_to_cpu(in.extLength); out.extLocation = lelb_to_cpu(in.extLocation); @@ -54,9 +54,9 @@ static inline kernel_long_ad lela_to_cpu(long_ad in) return out; } -static inline long_ad cpu_to_lela(kernel_long_ad in) +static inline struct long_ad cpu_to_lela(struct kernel_long_ad in) { - long_ad out; + struct long_ad out; out.extLength = cpu_to_le32(in.extLength); out.extLocation = cpu_to_lelb(in.extLocation); @@ -64,9 +64,9 @@ static inline long_ad cpu_to_lela(kernel_long_ad in) return out; } -static inline kernel_extent_ad leea_to_cpu(extent_ad in) +static inline struct kernel_extent_ad leea_to_cpu(struct extent_ad in) { - kernel_extent_ad out; + struct kernel_extent_ad out; out.extLength = le32_to_cpu(in.extLength); out.extLocation = le32_to_cpu(in.extLocation); diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c index 5f811655c9b5..b8c828c4d200 100644 --- a/fs/udf/udftime.c +++ b/fs/udf/udftime.c @@ -85,7 +85,8 @@ extern struct timezone sys_tz; #define SECS_PER_HOUR (60 * 60) #define SECS_PER_DAY (SECS_PER_HOUR * 24) -struct timespec *udf_disk_stamp_to_time(struct timespec *dest, timestamp src) +struct timespec * +udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src) { int yday; u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone); @@ -116,7 +117,8 @@ struct timespec *udf_disk_stamp_to_time(struct timespec *dest, timestamp src) return dest; } -timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec ts) +struct timestamp * +udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts) { long int days, rem, y; const unsigned short int *ip; diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 9fdf8c93c58e..cefa8c8913e6 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -254,7 +254,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, { const uint8_t *ocu; uint8_t cmp_id, ocu_len; - int i; + int i, len; ocu_len = ocu_i->u_len; @@ -279,8 +279,13 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, if (cmp_id == 16) c = (c << 8) | ocu[i++]; - utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len], - UDF_NAME_LEN - utf_o->u_len); + len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], + UDF_NAME_LEN - utf_o->u_len); + /* Valid character? */ + if (len >= 0) + utf_o->u_len += len; + else + utf_o->u_name[utf_o->u_len++] = '?'; } utf_o->u_cmpID = 8; @@ -290,7 +295,8 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length) { - unsigned len, i, max_val; + int len; + unsigned i, max_val; uint16_t uni_char; int u_len; @@ -302,8 +308,13 @@ try_again: u_len = 0U; for (i = 0U; i < uni->u_len; i++) { len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); - if (len <= 0) + if (!len) continue; + /* Invalid character, deal with it */ + if (len < 0) { + len = 1; + uni_char = '?'; + } if (uni_char > max_val) { max_val = 0xffffU; @@ -324,34 +335,43 @@ try_again: int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, int flen) { - struct ustr filename, unifilename; - int len; + struct ustr *filename, *unifilename; + int len = 0; - if (udf_build_ustr_exact(&unifilename, sname, flen)) + filename = kmalloc(sizeof(struct ustr), GFP_NOFS); + if (!filename) return 0; + unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS); + if (!unifilename) + goto out1; + + if (udf_build_ustr_exact(unifilename, sname, flen)) + goto out2; + if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { - if (!udf_CS0toUTF8(&filename, &unifilename)) { + if (!udf_CS0toUTF8(filename, unifilename)) { udf_debug("Failed in udf_get_filename: sname = %s\n", sname); - return 0; + goto out2; } } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { - if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, &filename, - &unifilename)) { + if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, + unifilename)) { udf_debug("Failed in udf_get_filename: sname = %s\n", sname); - return 0; + goto out2; } } else - return 0; - - len = udf_translate_to_linux(dname, filename.u_name, filename.u_len, - unifilename.u_name, unifilename.u_len); - if (len) - return len; - - return 0; + goto out2; + + len = udf_translate_to_linux(dname, filename->u_name, filename->u_len, + unifilename->u_name, unifilename->u_len); +out2: + kfree(unifilename); +out1: + kfree(filename); + return len; } int udf_put_filename(struct super_block *sb, const uint8_t *sname, |