Commit cb00ea35 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Linus Torvalds

UDF: coding style conversion - lindent

This patch converts UDF coding style to kernel coding style using Lindent.
Signed-off-by: default avatarCyrill Gorcunov <gorcunov@gmail.com>
Cc: Jan Kara <jack@ucw.cz>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 95a631e2
...@@ -41,18 +41,17 @@ ...@@ -41,18 +41,17 @@
#define uint(x) xuint(x) #define uint(x) xuint(x)
#define xuint(x) __le ## x #define xuint(x) __le ## x
static inline int find_next_one_bit (void * addr, int size, int offset) static inline int find_next_one_bit(void *addr, int size, int offset)
{ {
uintBPL_t * p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG); uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG);
int result = offset & ~(BITS_PER_LONG-1); int result = offset & ~(BITS_PER_LONG - 1);
unsigned long tmp; unsigned long tmp;
if (offset >= size) if (offset >= size)
return size; return size;
size -= result; size -= result;
offset &= (BITS_PER_LONG-1); offset &= (BITS_PER_LONG - 1);
if (offset) if (offset) {
{
tmp = leBPL_to_cpup(p++); tmp = leBPL_to_cpup(p++);
tmp &= ~0UL << offset; tmp &= ~0UL << offset;
if (size < BITS_PER_LONG) if (size < BITS_PER_LONG)
...@@ -62,8 +61,7 @@ static inline int find_next_one_bit (void * addr, int size, int offset) ...@@ -62,8 +61,7 @@ static inline int find_next_one_bit (void * addr, int size, int offset)
size -= BITS_PER_LONG; size -= BITS_PER_LONG;
result += BITS_PER_LONG; result += BITS_PER_LONG;
} }
while (size & ~(BITS_PER_LONG-1)) while (size & ~(BITS_PER_LONG - 1)) {
{
if ((tmp = leBPL_to_cpup(p++))) if ((tmp = leBPL_to_cpup(p++)))
goto found_middle; goto found_middle;
result += BITS_PER_LONG; result += BITS_PER_LONG;
...@@ -72,17 +70,18 @@ static inline int find_next_one_bit (void * addr, int size, int offset) ...@@ -72,17 +70,18 @@ static inline int find_next_one_bit (void * addr, int size, int offset)
if (!size) if (!size)
return result; return result;
tmp = leBPL_to_cpup(p); tmp = leBPL_to_cpup(p);
found_first: found_first:
tmp &= ~0UL >> (BITS_PER_LONG-size); tmp &= ~0UL >> (BITS_PER_LONG - size);
found_middle: found_middle:
return result + ffz(~tmp); return result + ffz(~tmp);
} }
#define find_first_one_bit(addr, size)\ #define find_first_one_bit(addr, size)\
find_next_one_bit((addr), (size), 0) find_next_one_bit((addr), (size), 0)
static int read_block_bitmap(struct super_block * sb, static int read_block_bitmap(struct super_block *sb,
struct udf_bitmap *bitmap, unsigned int block, unsigned long bitmap_nr) struct udf_bitmap *bitmap, unsigned int block,
unsigned long bitmap_nr)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int retval = 0; int retval = 0;
...@@ -92,38 +91,39 @@ static int read_block_bitmap(struct super_block * sb, ...@@ -92,38 +91,39 @@ static int read_block_bitmap(struct super_block * sb,
loc.partitionReferenceNum = UDF_SB_PARTITION(sb); loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block)); bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block));
if (!bh) if (!bh) {
{
retval = -EIO; retval = -EIO;
} }
bitmap->s_block_bitmap[bitmap_nr] = bh; bitmap->s_block_bitmap[bitmap_nr] = bh;
return retval; return retval;
} }
static int __load_block_bitmap(struct super_block * sb, static int __load_block_bitmap(struct super_block *sb,
struct udf_bitmap *bitmap, unsigned int block_group) struct udf_bitmap *bitmap,
unsigned int block_group)
{ {
int retval = 0; int retval = 0;
int nr_groups = bitmap->s_nr_groups; int nr_groups = bitmap->s_nr_groups;
if (block_group >= nr_groups) if (block_group >= nr_groups) {
{ udf_debug("block_group (%d) > nr_groups (%d)\n", block_group,
udf_debug("block_group (%d) > nr_groups (%d)\n", block_group, nr_groups); nr_groups);
} }
if (bitmap->s_block_bitmap[block_group]) if (bitmap->s_block_bitmap[block_group])
return block_group; return block_group;
else else {
{ retval =
retval = read_block_bitmap(sb, bitmap, block_group, block_group); read_block_bitmap(sb, bitmap, block_group, block_group);
if (retval < 0) if (retval < 0)
return retval; return retval;
return block_group; return block_group;
} }
} }
static inline int load_block_bitmap(struct super_block * sb, static inline int load_block_bitmap(struct super_block *sb,
struct udf_bitmap *bitmap, unsigned int block_group) struct udf_bitmap *bitmap,
unsigned int block_group)
{ {
int slot; int slot;
...@@ -138,13 +138,14 @@ static inline int load_block_bitmap(struct super_block * sb, ...@@ -138,13 +138,14 @@ static inline int load_block_bitmap(struct super_block * sb,
return slot; return slot;
} }
static void udf_bitmap_free_blocks(struct super_block * sb, static void udf_bitmap_free_blocks(struct super_block *sb,
struct inode * inode, struct inode *inode,
struct udf_bitmap *bitmap, struct udf_bitmap *bitmap,
kernel_lb_addr bloc, uint32_t offset, uint32_t count) kernel_lb_addr bloc, uint32_t offset,
uint32_t count)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct buffer_head * bh = NULL; struct buffer_head *bh = NULL;
unsigned long block; unsigned long block;
unsigned long block_group; unsigned long block_group;
unsigned long bit; unsigned long bit;
...@@ -154,17 +155,22 @@ static void udf_bitmap_free_blocks(struct super_block * sb, ...@@ -154,17 +155,22 @@ static void udf_bitmap_free_blocks(struct super_block * sb,
mutex_lock(&sbi->s_alloc_mutex); mutex_lock(&sbi->s_alloc_mutex);
if (bloc.logicalBlockNum < 0 || if (bloc.logicalBlockNum < 0 ||
(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb,
{ bloc.
udf_debug("%d < %d || %d + %d > %d\n", partitionReferenceNum))
bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, {
UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)); udf_debug("%d < %d || %d + %d > %d\n", bloc.logicalBlockNum, 0,
bloc.logicalBlockNum, count, UDF_SB_PARTLEN(sb,
bloc.
partitionReferenceNum));
goto error_return; goto error_return;
} }
block = bloc.logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3); block =
bloc.logicalBlockNum + offset +
(sizeof(struct spaceBitmapDesc) << 3);
do_more: do_more:
overflow = 0; overflow = 0;
block_group = block >> (sb->s_blocksize_bits + 3); block_group = block >> (sb->s_blocksize_bits + 3);
bit = block % (sb->s_blocksize << 3); bit = block % (sb->s_blocksize << 3);
...@@ -172,8 +178,7 @@ static void udf_bitmap_free_blocks(struct super_block * sb, ...@@ -172,8 +178,7 @@ static void udf_bitmap_free_blocks(struct super_block * sb,
/* /*
* Check to see if we are freeing blocks across a group boundary. * Check to see if we are freeing blocks across a group boundary.
*/ */
if (bit + count > (sb->s_blocksize << 3)) if (bit + count > (sb->s_blocksize << 3)) {
{
overflow = bit + count - (sb->s_blocksize << 3); overflow = bit + count - (sb->s_blocksize << 3);
count -= overflow; count -= overflow;
} }
...@@ -182,32 +187,31 @@ static void udf_bitmap_free_blocks(struct super_block * sb, ...@@ -182,32 +187,31 @@ static void udf_bitmap_free_blocks(struct super_block * sb,
goto error_return; goto error_return;
bh = bitmap->s_block_bitmap[bitmap_nr]; bh = bitmap->s_block_bitmap[bitmap_nr];
for (i=0; i < count; i++) for (i = 0; i < count; i++) {
{ if (udf_set_bit(bit + i, bh->b_data)) {
if (udf_set_bit(bit + i, bh->b_data))
{
udf_debug("bit %ld already set\n", bit + i); udf_debug("bit %ld already set\n", bit + i);
udf_debug("byte=%2x\n", ((char *)bh->b_data)[(bit + i) >> 3]); udf_debug("byte=%2x\n",
} ((char *)bh->b_data)[(bit + i) >> 3]);
else } else {
{
if (inode) if (inode)
DQUOT_FREE_BLOCK(inode, 1); DQUOT_FREE_BLOCK(inode, 1);
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{ UDF_SB_LVID(sb)->
UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] = freeSpaceTable[UDF_SB_PARTITION(sb)] =
cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)])+1); cpu_to_le32(le32_to_cpu
(UDF_SB_LVID(sb)->
freeSpaceTable[UDF_SB_PARTITION
(sb)]) + 1);
} }
} }
} }
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
if (overflow) if (overflow) {
{
block += count; block += count;
count = overflow; count = overflow;
goto do_more; goto do_more;
} }
error_return: error_return:
sb->s_dirt = 1; sb->s_dirt = 1;
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb))
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
...@@ -215,10 +219,11 @@ static void udf_bitmap_free_blocks(struct super_block * sb, ...@@ -215,10 +219,11 @@ static void udf_bitmap_free_blocks(struct super_block * sb,
return; return;
} }
static int udf_bitmap_prealloc_blocks(struct super_block * sb, static int udf_bitmap_prealloc_blocks(struct super_block *sb,
struct inode * inode, struct inode *inode,
struct udf_bitmap *bitmap, uint16_t partition, uint32_t first_block, struct udf_bitmap *bitmap,
uint32_t block_count) uint16_t partition, uint32_t first_block,
uint32_t block_count)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
int alloc_count = 0; int alloc_count = 0;
...@@ -233,9 +238,10 @@ static int udf_bitmap_prealloc_blocks(struct super_block * sb, ...@@ -233,9 +238,10 @@ static int udf_bitmap_prealloc_blocks(struct super_block * sb,
if (first_block + block_count > UDF_SB_PARTLEN(sb, partition)) if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
block_count = UDF_SB_PARTLEN(sb, partition) - first_block; block_count = UDF_SB_PARTLEN(sb, partition) - first_block;
repeat: repeat:
nr_groups = (UDF_SB_PARTLEN(sb, partition) + nr_groups = (UDF_SB_PARTLEN(sb, partition) +
(sizeof(struct spaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8); (sizeof(struct spaceBitmapDesc) << 3) +
(sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
block = first_block + (sizeof(struct spaceBitmapDesc) << 3); block = first_block + (sizeof(struct spaceBitmapDesc) << 3);
block_group = block >> (sb->s_blocksize_bits + 3); block_group = block >> (sb->s_blocksize_bits + 3);
group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc); group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
...@@ -247,31 +253,30 @@ static int udf_bitmap_prealloc_blocks(struct super_block * sb, ...@@ -247,31 +253,30 @@ static int udf_bitmap_prealloc_blocks(struct super_block * sb,
bit = block % (sb->s_blocksize << 3); bit = block % (sb->s_blocksize << 3);
while (bit < (sb->s_blocksize << 3) && block_count > 0) while (bit < (sb->s_blocksize << 3) && block_count > 0) {
{
if (!udf_test_bit(bit, bh->b_data)) if (!udf_test_bit(bit, bh->b_data))
goto out; goto out;
else if (DQUOT_PREALLOC_BLOCK(inode, 1)) else if (DQUOT_PREALLOC_BLOCK(inode, 1))
goto out; goto out;
else if (!udf_clear_bit(bit, bh->b_data)) else if (!udf_clear_bit(bit, bh->b_data)) {
{
udf_debug("bit already cleared for block %d\n", bit); udf_debug("bit already cleared for block %d\n", bit);
DQUOT_FREE_BLOCK(inode, 1); DQUOT_FREE_BLOCK(inode, 1);
goto out; goto out;
} }
block_count --; block_count--;
alloc_count ++; alloc_count++;
bit ++; bit++;
block ++; block++;
} }
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
if (block_count > 0) if (block_count > 0)
goto repeat; goto repeat;
out: out:
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{
UDF_SB_LVID(sb)->freeSpaceTable[partition] = UDF_SB_LVID(sb)->freeSpaceTable[partition] =
cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count); cpu_to_le32(le32_to_cpu
(UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
alloc_count);
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
} }
sb->s_dirt = 1; sb->s_dirt = 1;
...@@ -279,12 +284,13 @@ static int udf_bitmap_prealloc_blocks(struct super_block * sb, ...@@ -279,12 +284,13 @@ static int udf_bitmap_prealloc_blocks(struct super_block * sb,
return alloc_count; return alloc_count;
} }
static int udf_bitmap_new_block(struct super_block * sb, static int udf_bitmap_new_block(struct super_block *sb,
struct inode * inode, struct inode *inode,
struct udf_bitmap *bitmap, uint16_t partition, uint32_t goal, int *err) struct udf_bitmap *bitmap, uint16_t partition,
uint32_t goal, int *err)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
int newbit, bit=0, block, block_group, group_start; int newbit, bit = 0, block, block_group, group_start;
int end_goal, nr_groups, bitmap_nr, i; int end_goal, nr_groups, bitmap_nr, i;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
char *ptr; char *ptr;
...@@ -293,7 +299,7 @@ static int udf_bitmap_new_block(struct super_block * sb, ...@@ -293,7 +299,7 @@ static int udf_bitmap_new_block(struct super_block * sb,
*err = -ENOSPC; *err = -ENOSPC;
mutex_lock(&sbi->s_alloc_mutex); mutex_lock(&sbi->s_alloc_mutex);
repeat: repeat:
if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition)) if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
goal = 0; goal = 0;
...@@ -306,38 +312,39 @@ static int udf_bitmap_new_block(struct super_block * sb, ...@@ -306,38 +312,39 @@ static int udf_bitmap_new_block(struct super_block * sb,
if (bitmap_nr < 0) if (bitmap_nr < 0)
goto error_return; goto error_return;
bh = bitmap->s_block_bitmap[bitmap_nr]; bh = bitmap->s_block_bitmap[bitmap_nr];
ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start); ptr =
memscan((char *)bh->b_data + group_start, 0xFF,
sb->s_blocksize - group_start);
if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize) if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize) {
{
bit = block % (sb->s_blocksize << 3); bit = block % (sb->s_blocksize << 3);
if (udf_test_bit(bit, bh->b_data)) if (udf_test_bit(bit, bh->b_data)) {
{
goto got_block; goto got_block;
} }
end_goal = (bit + 63) & ~63; end_goal = (bit + 63) & ~63;
bit = udf_find_next_one_bit(bh->b_data, end_goal, bit); bit = udf_find_next_one_bit(bh->b_data, end_goal, bit);
if (bit < end_goal) if (bit < end_goal)
goto got_block; goto got_block;
ptr = memscan((char *)bh->b_data + (bit >> 3), 0xFF, sb->s_blocksize - ((bit + 7) >> 3)); ptr =
memscan((char *)bh->b_data + (bit >> 3), 0xFF,
sb->s_blocksize - ((bit + 7) >> 3));
newbit = (ptr - ((char *)bh->b_data)) << 3; newbit = (ptr - ((char *)bh->b_data)) << 3;
if (newbit < sb->s_blocksize << 3) if (newbit < sb->s_blocksize << 3) {
{
bit = newbit; bit = newbit;
goto search_back; goto search_back;
} }
newbit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, bit); newbit =
if (newbit < sb->s_blocksize << 3) udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3,
{ bit);
if (newbit < sb->s_blocksize << 3) {
bit = newbit; bit = newbit;
goto got_block; goto got_block;
} }
} }
for (i=0; i<(nr_groups*2); i++) for (i = 0; i < (nr_groups * 2); i++) {
{ block_group++;
block_group ++;
if (block_group >= nr_groups) if (block_group >= nr_groups)
block_group = 0; block_group = 0;
group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc); group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
...@@ -346,67 +353,69 @@ static int udf_bitmap_new_block(struct super_block * sb, ...@@ -346,67 +353,69 @@ static int udf_bitmap_new_block(struct super_block * sb,
if (bitmap_nr < 0) if (bitmap_nr < 0)
goto error_return; goto error_return;
bh = bitmap->s_block_bitmap[bitmap_nr]; bh = bitmap->s_block_bitmap[bitmap_nr];
if (i < nr_groups) if (i < nr_groups) {
{ ptr =
ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start); memscan((char *)bh->b_data + group_start, 0xFF,
if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize) sb->s_blocksize - group_start);
{ if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize) {
bit = (ptr - ((char *)bh->b_data)) << 3; bit = (ptr - ((char *)bh->b_data)) << 3;
break; break;
} }
} } else {
else bit =
{ udf_find_next_one_bit((char *)bh->b_data,
bit = udf_find_next_one_bit((char *)bh->b_data, sb->s_blocksize << 3, group_start << 3); sb->s_blocksize << 3,
group_start << 3);
if (bit < sb->s_blocksize << 3) if (bit < sb->s_blocksize << 3)
break; break;
} }
} }
if (i >= (nr_groups*2)) if (i >= (nr_groups * 2)) {
{
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
return newblock; return newblock;
} }
if (bit < sb->s_blocksize << 3) if (bit < sb->s_blocksize << 3)
goto search_back; goto search_back;
else else
bit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, group_start << 3); bit =
if (bit >= sb->s_blocksize << 3) udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3,
{ group_start << 3);
if (bit >= sb->s_blocksize << 3) {
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
return 0; return 0;
} }
search_back: search_back:
for (i=0; i<7 && bit > (group_start << 3) && udf_test_bit(bit - 1, bh->b_data); i++, bit--); for (i = 0;
i < 7 && bit > (group_start << 3)
&& udf_test_bit(bit - 1, bh->b_data); i++, bit--) ;
got_block: got_block:
/* /*
* Check quota for allocation of this block. * Check quota for allocation of this block.
*/ */
if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) {
{
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
*err = -EDQUOT; *err = -EDQUOT;
return 0; return 0;
} }
newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
(sizeof(struct spaceBitmapDesc) << 3); (sizeof(struct spaceBitmapDesc) << 3);
if (!udf_clear_bit(bit, bh->b_data)) if (!udf_clear_bit(bit, bh->b_data)) {
{
udf_debug("bit already cleared for block %d\n", bit); udf_debug("bit already cleared for block %d\n", bit);
goto repeat; goto repeat;
} }
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{
UDF_SB_LVID(sb)->freeSpaceTable[partition] = UDF_SB_LVID(sb)->freeSpaceTable[partition] =
cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-1); cpu_to_le32(le32_to_cpu
(UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
1);
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
} }
sb->s_dirt = 1; sb->s_dirt = 1;
...@@ -414,16 +423,17 @@ static int udf_bitmap_new_block(struct super_block * sb, ...@@ -414,16 +423,17 @@ static int udf_bitmap_new_block(struct super_block * sb,
*err = 0; *err = 0;
return newblock; return newblock;
error_return: error_return:
*err = -EIO; *err = -EIO;
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
return 0; return 0;
} }
static void udf_table_free_blocks(struct super_block * sb, static void udf_table_free_blocks(struct super_block *sb,
struct inode * inode, struct inode *inode,
struct inode * table, struct inode *table,
kernel_lb_addr bloc, uint32_t offset, uint32_t count) kernel_lb_addr bloc, uint32_t offset,
uint32_t count)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t start, end; uint32_t start, end;
...@@ -435,11 +445,14 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -435,11 +445,14 @@ static void udf_table_free_blocks(struct super_block * sb,
mutex_lock(&sbi->s_alloc_mutex); mutex_lock(&sbi->s_alloc_mutex);
if (bloc.logicalBlockNum < 0 || if (bloc.logicalBlockNum < 0 ||
(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb,
{ bloc.
udf_debug("%d < %d || %d + %d > %d\n", partitionReferenceNum))
bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, {
UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)); udf_debug("%d < %d || %d + %d > %d\n", bloc.logicalBlockNum, 0,
bloc.logicalBlockNum, count, UDF_SB_PARTLEN(sb,
bloc.
partitionReferenceNum));
goto error_return; goto error_return;
} }
...@@ -447,10 +460,11 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -447,10 +460,11 @@ static void udf_table_free_blocks(struct super_block * sb,
but.. oh well */ but.. oh well */
if (inode) if (inode)
DQUOT_FREE_BLOCK(inode, count); DQUOT_FREE_BLOCK(inode, count);
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{
UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] = UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)])+count); cpu_to_le32(le32_to_cpu
(UDF_SB_LVID(sb)->
freeSpaceTable[UDF_SB_PARTITION(sb)]) + count);
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
} }
...@@ -463,73 +477,75 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -463,73 +477,75 @@ static void udf_table_free_blocks(struct super_block * sb,
epos.bh = oepos.bh = NULL; epos.bh = oepos.bh = NULL;
while (count && (etype = while (count && (etype =
udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
{
if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
start)) start)) {
{ if ((0x3FFFFFFF - elen) <
if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) (count << sb->s_blocksize_bits)) {
{ count -=
count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits); ((0x3FFFFFFF -
start += ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits); elen) >> sb->s_blocksize_bits);
elen = (etype << 30) | (0x40000000 - sb->s_blocksize); start +=
} ((0x3FFFFFFF -
else elen) >> sb->s_blocksize_bits);
{ elen =
(etype << 30) | (0x40000000 -
sb->s_blocksize);
} else {
elen = (etype << 30) | elen = (etype << 30) |
(elen + (count << sb->s_blocksize_bits)); (elen + (count << sb->s_blocksize_bits));
start += count; start += count;
count = 0; count = 0;
} }
udf_write_aext(table, &oepos, eloc, elen, 1); udf_write_aext(table, &oepos, eloc, elen, 1);
} } else if (eloc.logicalBlockNum == (end + 1)) {
else if (eloc.logicalBlockNum == (end + 1)) if ((0x3FFFFFFF - elen) <
{ (count << sb->s_blocksize_bits)) {
if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) count -=
{ ((0x3FFFFFFF -
count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits); elen) >> sb->s_blocksize_bits);
end -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits); end -=
((0x3FFFFFFF -
elen) >> sb->s_blocksize_bits);
eloc.logicalBlockNum -= eloc.logicalBlockNum -=
((0x3FFFFFFF - elen) >> sb->s_blocksize_bits); ((0x3FFFFFFF -
elen = (etype << 30) | (0x40000000 - sb->s_blocksize); elen) >> sb->s_blocksize_bits);
} elen =
else (etype << 30) | (0x40000000 -
{ sb->s_blocksize);
} else {
eloc.logicalBlockNum = start; eloc.logicalBlockNum = start;
elen = (etype << 30) | elen = (etype << 30) |
(elen + (count << sb->s_blocksize_bits)); (elen + (count << sb->s_blocksize_bits));
end -= count; end -= count;
count = 0; count = 0;
} }
udf_write_aext(table, &oepos, eloc, elen, 1); udf_write_aext(table, &oepos, eloc, elen, 1);
} }
if (epos.bh != oepos.bh) if (epos.bh != oepos.bh) {
{
i = -1; i = -1;
oepos.block = epos.block; oepos.block = epos.block;
brelse(oepos.bh); brelse(oepos.bh);
get_bh(epos.bh); get_bh(epos.bh);
oepos.bh = epos.bh; oepos.bh = epos.bh;
oepos.offset = 0; oepos.offset = 0;
} } else
else
oepos.offset = epos.offset; oepos.offset = epos.offset;
} }
if (count) if (count) {
{
/* NOTE: we CANNOT use udf_add_aext here, as it can try to allocate /* NOTE: we CANNOT use udf_add_aext here, as it can try to allocate
a new block, and since we hold the super block lock already a new block, and since we hold the super block lock already
very bad things would happen :) very bad things would happen :)
We copy the behavior of udf_add_aext, but instead of We copy the behavior of udf_add_aext, but instead of
trying to allocate a new block close to the existing one, trying to allocate a new block close to the existing one,
we just steal a block from the extent we are trying to add. we just steal a block from the extent we are trying to add.
It would be nice if the blocks were close together, but it It would be nice if the blocks were close together, but it
isn't required. isn't required.
*/ */
int adsize; int adsize;
short_ad *sad = NULL; short_ad *sad = NULL;
...@@ -537,121 +553,124 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -537,121 +553,124 @@ static void udf_table_free_blocks(struct super_block * sb,
struct allocExtDesc *aed; struct allocExtDesc *aed;
eloc.logicalBlockNum = start; eloc.logicalBlockNum = start;
elen = EXT_RECORDED_ALLOCATED | elen = EXT_RECORDED_ALLOCATED | (count << sb->s_blocksize_bits);
(count << sb->s_blocksize_bits);
if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(short_ad); adsize = sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
adsize = sizeof(long_ad); adsize = sizeof(long_ad);
else else {
{
brelse(oepos.bh); brelse(oepos.bh);
brelse(epos.bh); brelse(epos.bh);
goto error_return; goto error_return;
} }
if (epos.offset + (2 * adsize) > sb->s_blocksize) if (epos.offset + (2 * adsize) > sb->s_blocksize) {
{
char *sptr, *dptr; char *sptr, *dptr;
int loffset; int loffset;
brelse(oepos.bh); brelse(oepos.bh);
oepos = epos; oepos = epos;
/* Steal a block from the extent being free'd */ /* Steal a block from the extent being free'd */
epos.block.logicalBlockNum = eloc.logicalBlockNum; epos.block.logicalBlockNum = eloc.logicalBlockNum;
eloc.logicalBlockNum ++; eloc.logicalBlockNum++;
elen -= sb->s_blocksize; elen -= sb->s_blocksize;
if (!(epos.bh = udf_tread(sb, if (!(epos.bh = udf_tread(sb,
udf_get_lb_pblock(sb, epos.block, 0)))) udf_get_lb_pblock(sb,
{ epos.block,
0)))) {
brelse(oepos.bh); brelse(oepos.bh);
goto error_return; goto error_return;
} }
aed = (struct allocExtDesc *)(epos.bh->b_data); aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->previousAllocExtLocation = cpu_to_le32(oepos.block.logicalBlockNum); aed->previousAllocExtLocation =
if (epos.offset + adsize > sb->s_blocksize) cpu_to_le32(oepos.block.logicalBlockNum);
{ if (epos.offset + adsize > sb->s_blocksize) {
loffset = epos.offset; loffset = epos.offset;
aed->lengthAllocDescs = cpu_to_le32(adsize); aed->lengthAllocDescs = cpu_to_le32(adsize);
sptr = UDF_I_DATA(inode) + epos.offset - sptr = UDF_I_DATA(inode) + epos.offset -
udf_file_entry_alloc_offset(inode) + udf_file_entry_alloc_offset(inode) +
UDF_I_LENEATTR(inode) - adsize; UDF_I_LENEATTR(inode) - adsize;
dptr = epos.bh->b_data + sizeof(struct allocExtDesc); dptr =
epos.bh->b_data +
sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize); memcpy(dptr, sptr, adsize);
epos.offset = sizeof(struct allocExtDesc) + adsize; epos.offset =
} sizeof(struct allocExtDesc) + adsize;
else } else {
{
loffset = epos.offset + adsize; loffset = epos.offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0); aed->lengthAllocDescs = cpu_to_le32(0);
sptr = oepos.bh->b_data + epos.offset; sptr = oepos.bh->b_data + epos.offset;
epos.offset = sizeof(struct allocExtDesc); epos.offset = sizeof(struct allocExtDesc);
if (oepos.bh) if (oepos.bh) {
{ aed =
aed = (struct allocExtDesc *)oepos.bh->b_data; (struct allocExtDesc *)oepos.bh->
b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); cpu_to_le32(le32_to_cpu
} (aed->
else lengthAllocDescs) +
{ adsize);
} else {
UDF_I_LENALLOC(table) += adsize; UDF_I_LENALLOC(table) += adsize;
mark_inode_dirty(table); mark_inode_dirty(table);
} }
} }
if (UDF_SB_UDFREV(sb) >= 0x0200) if (UDF_SB_UDFREV(sb) >= 0x0200)
udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1, udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3,
epos.block.logicalBlockNum, sizeof(tag)); 1, epos.block.logicalBlockNum,
sizeof(tag));
else else
udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1, udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2,
epos.block.logicalBlockNum, sizeof(tag)); 1, epos.block.logicalBlockNum,
switch (UDF_I_ALLOCTYPE(table)) sizeof(tag));
{ switch (UDF_I_ALLOCTYPE(table)) {
case ICBTAG_FLAG_AD_SHORT: case ICBTAG_FLAG_AD_SHORT:
{ {
sad = (short_ad *)sptr; sad = (short_ad *) sptr;
sad->extLength = cpu_to_le32( sad->extLength =
EXT_NEXT_EXTENT_ALLOCDECS | cpu_to_le32
sb->s_blocksize); (EXT_NEXT_EXTENT_ALLOCDECS | sb->
sad->extPosition = cpu_to_le32(epos.block.logicalBlockNum); s_blocksize);
sad->extPosition =
cpu_to_le32(epos.block.
logicalBlockNum);
break; break;
} }
case ICBTAG_FLAG_AD_LONG: case ICBTAG_FLAG_AD_LONG:
{ {
lad = (long_ad *)sptr; lad = (long_ad *) sptr;
lad->extLength = cpu_to_le32( lad->extLength =
EXT_NEXT_EXTENT_ALLOCDECS | cpu_to_le32
sb->s_blocksize); (EXT_NEXT_EXTENT_ALLOCDECS | sb->
lad->extLocation = cpu_to_lelb(epos.block); s_blocksize);
lad->extLocation =
cpu_to_lelb(epos.block);
break; break;
} }
} }
if (oepos.bh) if (oepos.bh) {
{
udf_update_tag(oepos.bh->b_data, loffset); udf_update_tag(oepos.bh->b_data, loffset);
mark_buffer_dirty(oepos.bh); mark_buffer_dirty(oepos.bh);
} } else
else
mark_inode_dirty(table); mark_inode_dirty(table);
} }
if (elen) /* It's possible that stealing the block emptied the extent */ if (elen) { /* It's possible that stealing the block emptied the extent */
{
udf_write_aext(table, &epos, eloc, elen, 1); udf_write_aext(table, &epos, eloc, elen, 1);
if (!epos.bh) if (!epos.bh) {
{
UDF_I_LENALLOC(table) += adsize; UDF_I_LENALLOC(table) += adsize;
mark_inode_dirty(table); mark_inode_dirty(table);
} } else {
else
{
aed = (struct allocExtDesc *)epos.bh->b_data; aed = (struct allocExtDesc *)epos.bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); cpu_to_le32(le32_to_cpu
(aed->lengthAllocDescs) +
adsize);
udf_update_tag(epos.bh->b_data, epos.offset); udf_update_tag(epos.bh->b_data, epos.offset);
mark_buffer_dirty(epos.bh); mark_buffer_dirty(epos.bh);
} }
...@@ -661,16 +680,16 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -661,16 +680,16 @@ static void udf_table_free_blocks(struct super_block * sb,
brelse(epos.bh); brelse(epos.bh);
brelse(oepos.bh); brelse(oepos.bh);
error_return: error_return:
sb->s_dirt = 1; sb->s_dirt = 1;
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
return; return;
} }
static int udf_table_prealloc_blocks(struct super_block * sb, static int udf_table_prealloc_blocks(struct super_block *sb,
struct inode * inode, struct inode *inode,
struct inode *table, uint16_t partition, uint32_t first_block, struct inode *table, uint16_t partition,
uint32_t block_count) uint32_t first_block, uint32_t block_count)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
int alloc_count = 0; int alloc_count = 0;
...@@ -696,39 +715,46 @@ static int udf_table_prealloc_blocks(struct super_block * sb, ...@@ -696,39 +715,46 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
eloc.logicalBlockNum = 0xFFFFFFFF; eloc.logicalBlockNum = 0xFFFFFFFF;
while (first_block != eloc.logicalBlockNum && (etype = while (first_block != eloc.logicalBlockNum && (etype =
udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) udf_next_aext(table,
{ &epos,
&eloc,
&elen,
1)) !=
-1) {
udf_debug("eloc=%d, elen=%d, first_block=%d\n", udf_debug("eloc=%d, elen=%d, first_block=%d\n",
eloc.logicalBlockNum, elen, first_block); eloc.logicalBlockNum, elen, first_block);
; /* empty loop body */ ; /* empty loop body */
} }
if (first_block == eloc.logicalBlockNum) if (first_block == eloc.logicalBlockNum) {
{
epos.offset -= adsize; epos.offset -= adsize;
alloc_count = (elen >> sb->s_blocksize_bits); alloc_count = (elen >> sb->s_blocksize_bits);
if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) if (inode
&& DQUOT_PREALLOC_BLOCK(inode,
alloc_count >
block_count ? block_count :
alloc_count))
alloc_count = 0; alloc_count = 0;
else if (alloc_count > block_count) else if (alloc_count > block_count) {
{
alloc_count = block_count; alloc_count = block_count;
eloc.logicalBlockNum += alloc_count; eloc.logicalBlockNum += alloc_count;
elen -= (alloc_count << sb->s_blocksize_bits); elen -= (alloc_count << sb->s_blocksize_bits);
udf_write_aext(table, &epos, eloc, (etype << 30) | elen, 1); udf_write_aext(table, &epos, eloc, (etype << 30) | elen,
} 1);
else } else
udf_delete_aext(table, epos, eloc, (etype << 30) | elen); udf_delete_aext(table, epos, eloc,
} (etype << 30) | elen);
else } else
alloc_count = 0; alloc_count = 0;
brelse(epos.bh); brelse(epos.bh);
if (alloc_count && UDF_SB_LVIDBH(sb)) if (alloc_count && UDF_SB_LVIDBH(sb)) {
{
UDF_SB_LVID(sb)->freeSpaceTable[partition] = UDF_SB_LVID(sb)->freeSpaceTable[partition] =
cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count); cpu_to_le32(le32_to_cpu
(UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
alloc_count);
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
sb->s_dirt = 1; sb->s_dirt = 1;
} }
...@@ -736,9 +762,10 @@ static int udf_table_prealloc_blocks(struct super_block * sb, ...@@ -736,9 +762,10 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
return alloc_count; return alloc_count;
} }
static int udf_table_new_block(struct super_block * sb, static int udf_table_new_block(struct super_block *sb,
struct inode * inode, struct inode *inode,
struct inode *table, uint16_t partition, uint32_t goal, int *err) struct inode *table, uint16_t partition,
uint32_t goal, int *err)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
...@@ -765,30 +792,27 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -765,30 +792,27 @@ static int udf_table_new_block(struct super_block * sb,
we stop. Otherwise we keep going till we run out of extents. we stop. Otherwise we keep going till we run out of extents.
We store the buffer_head, bloc, and extoffset of the current closest We store the buffer_head, bloc, and extoffset of the current closest
match and use that when we are done. match and use that when we are done.
*/ */
epos.offset = sizeof(struct unallocSpaceEntry); epos.offset = sizeof(struct unallocSpaceEntry);
epos.block = UDF_I_LOCATION(table); epos.block = UDF_I_LOCATION(table);
epos.bh = goal_epos.bh = NULL; epos.bh = goal_epos.bh = NULL;
while (spread && (etype = while (spread && (etype =
udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
{ if (goal >= eloc.logicalBlockNum) {
if (goal >= eloc.logicalBlockNum) if (goal <
{ eloc.logicalBlockNum +
if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) (elen >> sb->s_blocksize_bits))
nspread = 0; nspread = 0;
else else
nspread = goal - eloc.logicalBlockNum - nspread = goal - eloc.logicalBlockNum -
(elen >> sb->s_blocksize_bits); (elen >> sb->s_blocksize_bits);
} } else
else
nspread = eloc.logicalBlockNum - goal; nspread = eloc.logicalBlockNum - goal;
if (nspread < spread) if (nspread < spread) {
{
spread = nspread; spread = nspread;
if (goal_epos.bh != epos.bh) if (goal_epos.bh != epos.bh) {
{
brelse(goal_epos.bh); brelse(goal_epos.bh);
goal_epos.bh = epos.bh; goal_epos.bh = epos.bh;
get_bh(goal_epos.bh); get_bh(goal_epos.bh);
...@@ -802,8 +826,7 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -802,8 +826,7 @@ static int udf_table_new_block(struct super_block * sb,
brelse(epos.bh); brelse(epos.bh);
if (spread == 0xFFFFFFFF) if (spread == 0xFFFFFFFF) {
{
brelse(goal_epos.bh); brelse(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
return 0; return 0;
...@@ -815,11 +838,10 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -815,11 +838,10 @@ static int udf_table_new_block(struct super_block * sb,
/* This works, but very poorly.... */ /* This works, but very poorly.... */
newblock = goal_eloc.logicalBlockNum; newblock = goal_eloc.logicalBlockNum;
goal_eloc.logicalBlockNum ++; goal_eloc.logicalBlockNum++;
goal_elen -= sb->s_blocksize; goal_elen -= sb->s_blocksize;
if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) {
{
brelse(goal_epos.bh); brelse(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
*err = -EDQUOT; *err = -EDQUOT;
...@@ -832,10 +854,11 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -832,10 +854,11 @@ static int udf_table_new_block(struct super_block * sb,
udf_delete_aext(table, goal_epos, goal_eloc, goal_elen); udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
brelse(goal_epos.bh); brelse(goal_epos.bh);
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{
UDF_SB_LVID(sb)->freeSpaceTable[partition] = UDF_SB_LVID(sb)->freeSpaceTable[partition] =
cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-1); cpu_to_le32(le32_to_cpu
(UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
1);
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
} }
...@@ -845,105 +868,99 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -845,105 +868,99 @@ static int udf_table_new_block(struct super_block * sb,
return newblock; return newblock;
} }
inline void udf_free_blocks(struct super_block * sb, inline void udf_free_blocks(struct super_block *sb,
struct inode * inode, struct inode *inode,
kernel_lb_addr bloc, uint32_t offset, uint32_t count) kernel_lb_addr bloc, uint32_t offset,
uint32_t count)
{ {
uint16_t partition = bloc.partitionReferenceNum; uint16_t partition = bloc.partitionReferenceNum;
if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) {
{
return udf_bitmap_free_blocks(sb, inode, return udf_bitmap_free_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap, UDF_SB_PARTMAPS(sb)[partition].
bloc, offset, count); s_uspace.s_bitmap, bloc, offset,
} count);
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) } else if (UDF_SB_PARTFLAGS(sb, partition) &
{ UDF_PART_FLAG_UNALLOC_TABLE) {
return udf_table_free_blocks(sb, inode, return udf_table_free_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table, UDF_SB_PARTMAPS(sb)[partition].
bloc, offset, count); s_uspace.s_table, bloc, offset,
} count);
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) {
{
return udf_bitmap_free_blocks(sb, inode, return udf_bitmap_free_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap, UDF_SB_PARTMAPS(sb)[partition].
bloc, offset, count); s_fspace.s_bitmap, bloc, offset,
} count);
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) {
{
return udf_table_free_blocks(sb, inode, return udf_table_free_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table, UDF_SB_PARTMAPS(sb)[partition].
bloc, offset, count); s_fspace.s_table, bloc, offset,
} count);
else } else
return; return;
} }
inline int udf_prealloc_blocks(struct super_block * sb, inline int udf_prealloc_blocks(struct super_block *sb,
struct inode * inode, struct inode *inode,
uint16_t partition, uint32_t first_block, uint32_t block_count) uint16_t partition, uint32_t first_block,
uint32_t block_count)
{ {
if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) {
{
return udf_bitmap_prealloc_blocks(sb, inode, return udf_bitmap_prealloc_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap, UDF_SB_PARTMAPS(sb)
partition, first_block, block_count); [partition].s_uspace.s_bitmap,
} partition, first_block,
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) block_count);
{ } else if (UDF_SB_PARTFLAGS(sb, partition) &
UDF_PART_FLAG_UNALLOC_TABLE) {
return udf_table_prealloc_blocks(sb, inode, return udf_table_prealloc_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table, UDF_SB_PARTMAPS(sb)[partition].
partition, first_block, block_count); s_uspace.s_table, partition,
} first_block, block_count);
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) {
{
return udf_bitmap_prealloc_blocks(sb, inode, return udf_bitmap_prealloc_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap, UDF_SB_PARTMAPS(sb)
partition, first_block, block_count); [partition].s_fspace.s_bitmap,
} partition, first_block,
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) block_count);
{ } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) {
return udf_table_prealloc_blocks(sb, inode, return udf_table_prealloc_blocks(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table, UDF_SB_PARTMAPS(sb)[partition].
partition, first_block, block_count); s_fspace.s_table, partition,
} first_block, block_count);
else } else
return 0; return 0;
} }
inline int udf_new_block(struct super_block * sb, inline int udf_new_block(struct super_block *sb,
struct inode * inode, struct inode *inode,
uint16_t partition, uint32_t goal, int *err) uint16_t partition, uint32_t goal, int *err)
{ {
int ret; int ret;
if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) {
{
ret = udf_bitmap_new_block(sb, inode, ret = udf_bitmap_new_block(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap, UDF_SB_PARTMAPS(sb)[partition].
partition, goal, err); s_uspace.s_bitmap, partition, goal,
err);
return ret; return ret;
} } else if (UDF_SB_PARTFLAGS(sb, partition) &
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) UDF_PART_FLAG_UNALLOC_TABLE) {
{
return udf_table_new_block(sb, inode, return udf_table_new_block(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table, UDF_SB_PARTMAPS(sb)[partition].
partition, goal, err); s_uspace.s_table, partition, goal,
} err);
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) {
{
return udf_bitmap_new_block(sb, inode, return udf_bitmap_new_block(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap, UDF_SB_PARTMAPS(sb)[partition].
partition, goal, err); s_fspace.s_bitmap, partition, goal,
} err);
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) {
{
return udf_table_new_block(sb, inode, return udf_table_new_block(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table, UDF_SB_PARTMAPS(sb)[partition].
partition, goal, err); s_fspace.s_table, partition, goal,
} err);
else } else {
{
*err = -EIO; *err = -EIO;
return 0; return 0;
} }
......
...@@ -79,8 +79,7 @@ static uint16_t crc_table[256] = { ...@@ -79,8 +79,7 @@ static uint16_t crc_table[256] = {
* July 21, 1997 - Andrew E. Mileski * July 21, 1997 - Andrew E. Mileski
* Adapted from OSTA-UDF(tm) 1.50 standard. * Adapted from OSTA-UDF(tm) 1.50 standard.
*/ */
uint16_t uint16_t udf_crc(uint8_t * data, uint32_t size, uint16_t crc)
udf_crc(uint8_t *data, uint32_t size, uint16_t crc)
{ {
while (size--) while (size--)
crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8); crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8);
...@@ -112,7 +111,7 @@ int main(void) ...@@ -112,7 +111,7 @@ int main(void)
return 0; return 0;
} }
#endif /* defined(TEST) */ #endif /* defined(TEST) */
/****************************************************************************/ /****************************************************************************/
#if defined(GENERATE) #if defined(GENERATE)
...@@ -138,7 +137,7 @@ int main(int argc, char **argv) ...@@ -138,7 +137,7 @@ int main(int argc, char **argv)
/* Get the polynomial */ /* Get the polynomial */
sscanf(argv[1], "%lo", &poly); sscanf(argv[1], "%lo", &poly);
if (poly & 0xffff0000U){ if (poly & 0xffff0000U) {
fprintf(stderr, "polynomial is too large\en"); fprintf(stderr, "polynomial is too large\en");
exit(1); exit(1);
} }
...@@ -147,22 +146,22 @@ int main(int argc, char **argv) ...@@ -147,22 +146,22 @@ int main(int argc, char **argv)
/* Create a table */ /* Create a table */
printf("static unsigned short crc_table[256] = {\n"); printf("static unsigned short crc_table[256] = {\n");
for (n = 0; n < 256; n++){ for (n = 0; n < 256; n++) {
if (n % 8 == 0) if (n % 8 == 0)
printf("\t"); printf("\t");
crc = n << 8; crc = n << 8;
for (i = 0; i < 8; i++){ for (i = 0; i < 8; i++) {
if(crc & 0x8000U) if (crc & 0x8000U)
crc = (crc << 1) ^ poly; crc = (crc << 1) ^ poly;
else else
crc <<= 1; crc <<= 1;
crc &= 0xFFFFU; crc &= 0xFFFFU;
} }
if (n == 255) if (n == 255)
printf("0x%04xU ", crc); printf("0x%04xU ", crc);
else else
printf("0x%04xU, ", crc); printf("0x%04xU, ", crc);
if(n % 8 == 7) if (n % 8 == 7)
printf("\n"); printf("\n");
} }
printf("};\n"); printf("};\n");
...@@ -170,4 +169,4 @@ int main(int argc, char **argv) ...@@ -170,4 +169,4 @@ int main(int argc, char **argv)
return 0; return 0;
} }
#endif /* defined(GENERATE) */ #endif /* defined(GENERATE) */
...@@ -43,10 +43,10 @@ static int do_udf_readdir(struct inode *, struct file *, filldir_t, void *); ...@@ -43,10 +43,10 @@ static int do_udf_readdir(struct inode *, struct file *, filldir_t, void *);
/* readdir and lookup functions */ /* readdir and lookup functions */
const struct file_operations udf_dir_operations = { const struct file_operations udf_dir_operations = {
.read = generic_read_dir, .read = generic_read_dir,
.readdir = udf_readdir, .readdir = udf_readdir,
.ioctl = udf_ioctl, .ioctl = udf_ioctl,
.fsync = udf_fsync_file, .fsync = udf_fsync_file,
}; };
/* /*
...@@ -82,26 +82,26 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -82,26 +82,26 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
lock_kernel(); lock_kernel();
if ( filp->f_pos == 0 ) if (filp->f_pos == 0) {
{ if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) <
if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) 0) {
{
unlock_kernel(); unlock_kernel();
return 0; return 0;
} }
filp->f_pos ++; filp->f_pos++;
} }
result = do_udf_readdir(dir, filp, filldir, dirent); result = do_udf_readdir(dir, filp, filldir, dirent);
unlock_kernel(); unlock_kernel();
return result; return result;
} }
static int static int
do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *dirent) do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
void *dirent)
{ {
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct fileIdentDesc *fi=NULL; struct fileIdentDesc *fi = NULL;
struct fileIdentDesc cfi; struct fileIdentDesc cfi;
int block, iblock; int block, iblock;
loff_t nf_pos = filp->f_pos - 1; loff_t nf_pos = filp->f_pos - 1;
...@@ -117,7 +117,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -117,7 +117,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
sector_t offset; sector_t offset;
int i, num; int i, num;
unsigned int dt_type; unsigned int dt_type;
struct extent_position epos = { NULL, 0, {0, 0}}; struct extent_position epos = { NULL, 0, {0, 0} };
if (nf_pos >= size) if (nf_pos >= size)
return 0; return 0;
...@@ -125,65 +125,61 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -125,65 +125,61 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (nf_pos == 0) if (nf_pos == 0)
nf_pos = (udf_ext0_offset(dir) >> 2); nf_pos = (udf_ext0_offset(dir) >> 2);
fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; fibh.soffset = fibh.eoffset =
(nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL; fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
&epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) &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 ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
epos.offset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
epos.offset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} } else
else
offset = 0; offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) {
{
brelse(epos.bh); brelse(epos.bh);
return -EIO; return -EIO;
} }
if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1))) if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) {
{
i = 16 >> (dir->i_sb->s_blocksize_bits - 9); i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
if (i+offset > (elen >> dir->i_sb->s_blocksize_bits)) if (i + offset > (elen >> dir->i_sb->s_blocksize_bits))
i = (elen >> dir->i_sb->s_blocksize_bits)-offset; i = (elen >> dir->i_sb->s_blocksize_bits) -
for (num=0; i>0; i--) 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); tmp = udf_tgetblk(dir->i_sb, block);
if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) if (tmp && !buffer_uptodate(tmp)
&& !buffer_locked(tmp))
bha[num++] = tmp; bha[num++] = tmp;
else else
brelse(tmp); brelse(tmp);
} }
if (num) if (num) {
{
ll_rw_block(READA, num, bha); ll_rw_block(READA, num, bha);
for (i=0; i<num; i++) for (i = 0; i < num; i++)
brelse(bha[i]); brelse(bha[i]);
} }
} }
} } else {
else
{
brelse(epos.bh); brelse(epos.bh);
return -ENOENT; return -ENOENT;
} }
while ( nf_pos < size ) while (nf_pos < size) {
{
filp->f_pos = nf_pos + 1; filp->f_pos = nf_pos + 1;
fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc,
&elen, &offset);
if (!fi) if (!fi) {
{
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
...@@ -196,43 +192,41 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -196,43 +192,41 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (fibh.sbh == fibh.ebh) if (fibh.sbh == fibh.ebh)
nameptr = fi->fileIdent + liu; nameptr = fi->fileIdent + liu;
else else {
{
int poffset; /* Unpaded ending offset */ int poffset; /* Unpaded ending offset */
poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi; poffset =
fibh.soffset + sizeof(struct fileIdentDesc) + liu +
lfi;
if (poffset >= lfi) if (poffset >= lfi)
nameptr = (char *)(fibh.ebh->b_data + poffset - lfi); nameptr =
else (char *)(fibh.ebh->b_data + poffset - lfi);
{ else {
nameptr = fname; nameptr = fname;
memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); memcpy(nameptr, fi->fileIdent + liu,
memcpy(nameptr + lfi - poffset, fibh.ebh->b_data, poffset); lfi - poffset);
memcpy(nameptr + lfi - poffset,
fibh.ebh->b_data, poffset);
} }
} }
if ( (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 ) if ((cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
{ if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE))
if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
continue; continue;
} }
if ( (cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 ) if ((cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) {
{ if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE))
if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
continue; continue;
} }
if ( cfi.fileCharacteristics & FID_FILE_CHAR_PARENT ) if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) {
{
iblock = parent_ino(filp->f_path.dentry); iblock = parent_ino(filp->f_path.dentry);
flen = 2; flen = 2;
memcpy(fname, "..", flen); memcpy(fname, "..", flen);
dt_type = DT_DIR; dt_type = DT_DIR;
} } else {
else
{
kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation); 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);
...@@ -240,18 +234,18 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -240,18 +234,18 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
dt_type = DT_UNKNOWN; dt_type = DT_UNKNOWN;
} }
if (flen) if (flen) {
{ if (filldir
if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) (dirent, fname, flen, filp->f_pos, iblock,
{ dt_type) < 0) {
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
brelse(epos.bh); brelse(epos.bh);
return 0; return 0;
} }
} }
} /* end while */ } /* end while */
filp->f_pos = nf_pos + 1; filp->f_pos = nf_pos + 1;
......
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#if 0 #if 0
static uint8_t * static uint8_t *udf_filead_read(struct inode *dir, uint8_t * tmpad,
udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, uint8_t ad_size, kernel_lb_addr fe_loc,
kernel_lb_addr fe_loc, int *pos, int *offset, int *pos, int *offset, struct buffer_head **bh,
struct buffer_head **bh, int *error) int *error)
{ {
int loffset = *offset; int loffset = *offset;
int block; int block;
...@@ -31,31 +31,27 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, ...@@ -31,31 +31,27 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
*error = 0; *error = 0;
ad = (uint8_t *)(*bh)->b_data + *offset; ad = (uint8_t *) (*bh)->b_data + *offset;
*offset += ad_size; *offset += ad_size;
if (!ad) if (!ad) {
{
brelse(*bh); brelse(*bh);
*error = 1; *error = 1;
return NULL; return NULL;
} }
if (*offset == dir->i_sb->s_blocksize) if (*offset == dir->i_sb->s_blocksize) {
{
brelse(*bh); brelse(*bh);
block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
if (!block) if (!block)
return NULL; return NULL;
if (!(*bh = udf_tread(dir->i_sb, block))) if (!(*bh = udf_tread(dir->i_sb, block)))
return NULL; return NULL;
} } else if (*offset > dir->i_sb->s_blocksize) {
else if (*offset > dir->i_sb->s_blocksize)
{
ad = tmpad; ad = tmpad;
remainder = dir->i_sb->s_blocksize - loffset; remainder = dir->i_sb->s_blocksize - loffset;
memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder); memcpy((uint8_t *) ad, (*bh)->b_data + loffset, remainder);
brelse(*bh); brelse(*bh);
block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
...@@ -64,56 +60,56 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, ...@@ -64,56 +60,56 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
if (!((*bh) = udf_tread(dir->i_sb, block))) if (!((*bh) = udf_tread(dir->i_sb, block)))
return NULL; return NULL;
memcpy((uint8_t *)ad + remainder, (*bh)->b_data, ad_size - remainder); memcpy((uint8_t *) ad + remainder, (*bh)->b_data,
ad_size - remainder);
*offset = ad_size - remainder; *offset = ad_size - remainder;
} }
return ad; return ad;
} }
#endif #endif
struct fileIdentDesc * struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t * nf_pos,
udf_fileident_read(struct inode *dir, loff_t *nf_pos, struct udf_fileident_bh *fibh,
struct udf_fileident_bh *fibh, struct fileIdentDesc *cfi,
struct fileIdentDesc *cfi, struct extent_position *epos,
struct extent_position *epos, kernel_lb_addr * eloc, uint32_t * elen,
kernel_lb_addr *eloc, uint32_t *elen, sector_t * offset)
sector_t *offset)
{ {
struct fileIdentDesc *fi; struct fileIdentDesc *fi;
int i, num, block; int i, num, block;
struct buffer_head * tmp, * bha[16]; struct buffer_head *tmp, *bha[16];
fibh->soffset = fibh->eoffset; fibh->soffset = fibh->eoffset;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
{
fi = udf_get_fileident(UDF_I_DATA(dir) - fi = udf_get_fileident(UDF_I_DATA(dir) -
(UDF_I_EFE(dir) ? (UDF_I_EFE(dir) ?
sizeof(struct extendedFileEntry) : sizeof(struct extendedFileEntry) :
sizeof(struct fileEntry)), sizeof(struct fileEntry)),
dir->i_sb->s_blocksize, &(fibh->eoffset)); dir->i_sb->s_blocksize,
&(fibh->eoffset));
if (!fi) if (!fi)
return NULL; return NULL;
*nf_pos += ((fibh->eoffset - fibh->soffset) >> 2); *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc)); memcpy((uint8_t *) cfi, (uint8_t *) fi,
sizeof(struct fileIdentDesc));
return fi; return fi;
} }
if (fibh->eoffset == dir->i_sb->s_blocksize) if (fibh->eoffset == dir->i_sb->s_blocksize) {
{
int lextoffset = epos->offset; int lextoffset = epos->offset;
if (udf_next_aext(dir, epos, eloc, elen, 1) != if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30)) (EXT_RECORDED_ALLOCATED >> 30))
return NULL; return NULL;
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
(*offset) ++; (*offset)++;
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0; *offset = 0;
...@@ -125,57 +121,57 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -125,57 +121,57 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
return NULL; return NULL;
fibh->soffset = fibh->eoffset = 0; fibh->soffset = fibh->eoffset = 0;
if (!(*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1))) if (!
(*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1)))
{ {
i = 16 >> (dir->i_sb->s_blocksize_bits - 9); i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
if (i+*offset > (*elen >> dir->i_sb->s_blocksize_bits)) if (i + *offset >
i = (*elen >> dir->i_sb->s_blocksize_bits)-*offset; (*elen >> dir->i_sb->s_blocksize_bits))
for (num=0; i>0; i--) i = (*elen >> dir->i_sb->s_blocksize_bits) -
{ *offset;
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset+i); for (num = 0; i > 0; i--) {
block =
udf_get_lb_pblock(dir->i_sb, *eloc,
*offset + i);
tmp = udf_tgetblk(dir->i_sb, block); tmp = udf_tgetblk(dir->i_sb, block);
if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) if (tmp && !buffer_uptodate(tmp)
&& !buffer_locked(tmp))
bha[num++] = tmp; bha[num++] = tmp;
else else
brelse(tmp); brelse(tmp);
} }
if (num) if (num) {
{
ll_rw_block(READA, num, bha); ll_rw_block(READA, num, bha);
for (i=0; i<num; i++) for (i = 0; i < num; i++)
brelse(bha[i]); brelse(bha[i]);
} }
} }
} } else if (fibh->sbh != fibh->ebh) {
else if (fibh->sbh != fibh->ebh)
{
brelse(fibh->sbh); brelse(fibh->sbh);
fibh->sbh = fibh->ebh; fibh->sbh = fibh->ebh;
} }
fi = udf_get_fileident(fibh->sbh->b_data, dir->i_sb->s_blocksize, fi = udf_get_fileident(fibh->sbh->b_data, dir->i_sb->s_blocksize,
&(fibh->eoffset)); &(fibh->eoffset));
if (!fi) if (!fi)
return NULL; return NULL;
*nf_pos += ((fibh->eoffset - fibh->soffset) >> 2); *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
if (fibh->eoffset <= dir->i_sb->s_blocksize) if (fibh->eoffset <= dir->i_sb->s_blocksize) {
{ memcpy((uint8_t *) cfi, (uint8_t *) fi,
memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc)); sizeof(struct fileIdentDesc));
} } else if (fibh->eoffset > dir->i_sb->s_blocksize) {
else if (fibh->eoffset > dir->i_sb->s_blocksize)
{
int lextoffset = epos->offset; int lextoffset = epos->offset;
if (udf_next_aext(dir, epos, eloc, elen, 1) != if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30)) (EXT_RECORDED_ALLOCATED >> 30))
return NULL; return NULL;
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
(*offset) ++; (*offset)++;
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0; *offset = 0;
...@@ -188,62 +184,62 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -188,62 +184,62 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if (!(fibh->ebh = udf_tread(dir->i_sb, block))) if (!(fibh->ebh = udf_tread(dir->i_sb, block)))
return NULL; return NULL;
if (sizeof(struct fileIdentDesc) > - fibh->soffset) if (sizeof(struct fileIdentDesc) > -fibh->soffset) {
{
int fi_len; int fi_len;
memcpy((uint8_t *)cfi, (uint8_t *)fi, - fibh->soffset); memcpy((uint8_t *) cfi, (uint8_t *) fi, -fibh->soffset);
memcpy((uint8_t *)cfi - fibh->soffset, fibh->ebh->b_data, memcpy((uint8_t *) cfi - fibh->soffset,
sizeof(struct fileIdentDesc) + fibh->soffset); fibh->ebh->b_data,
sizeof(struct fileIdentDesc) + fibh->soffset);
fi_len = (sizeof(struct fileIdentDesc) + cfi->lengthFileIdent + fi_len =
le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3; (sizeof(struct fileIdentDesc) +
cfi->lengthFileIdent +
le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
*nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2); *nf_pos +=
((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
fibh->eoffset = fibh->soffset + fi_len; fibh->eoffset = fibh->soffset + fi_len;
} } else {
else memcpy((uint8_t *) cfi, (uint8_t *) fi,
{ sizeof(struct fileIdentDesc));
memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
} }
} }
return fi; return fi;
} }
struct fileIdentDesc * struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset)
udf_get_fileident(void * buffer, int bufsize, int * offset)
{ {
struct fileIdentDesc *fi; struct fileIdentDesc *fi;
int lengthThisIdent; int lengthThisIdent;
uint8_t * ptr; uint8_t *ptr;
int padlen; int padlen;
if ( (!buffer) || (!offset) ) { if ((!buffer) || (!offset)) {
udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer, offset); udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer,
offset);
return NULL; return NULL;
} }
ptr = buffer; ptr = buffer;
if ( (*offset > 0) && (*offset < bufsize) ) { if ((*offset > 0) && (*offset < bufsize)) {
ptr += *offset; ptr += *offset;
} }
fi=(struct fileIdentDesc *)ptr; fi = (struct fileIdentDesc *)ptr;
if (le16_to_cpu(fi->descTag.tagIdent) != TAG_IDENT_FID) if (le16_to_cpu(fi->descTag.tagIdent) != TAG_IDENT_FID) {
{
udf_debug("0x%x != TAG_IDENT_FID\n", udf_debug("0x%x != TAG_IDENT_FID\n",
le16_to_cpu(fi->descTag.tagIdent)); le16_to_cpu(fi->descTag.tagIdent));
udf_debug("offset: %u sizeof: %lu bufsize: %u\n", udf_debug("offset: %u sizeof: %lu bufsize: %u\n",
*offset, (unsigned long)sizeof(struct fileIdentDesc), bufsize); *offset, (unsigned long)sizeof(struct fileIdentDesc),
bufsize);
return NULL; return NULL;
} }
if ( (*offset + sizeof(struct fileIdentDesc)) > bufsize ) if ((*offset + sizeof(struct fileIdentDesc)) > bufsize) {
{
lengthThisIdent = sizeof(struct fileIdentDesc); lengthThisIdent = sizeof(struct fileIdentDesc);
} } else
else
lengthThisIdent = sizeof(struct fileIdentDesc) + lengthThisIdent = sizeof(struct fileIdentDesc) +
fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse); fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
/* we need to figure padding, too! */ /* we need to figure padding, too! */
padlen = lengthThisIdent % UDF_NAME_PAD; padlen = lengthThisIdent % UDF_NAME_PAD;
...@@ -255,56 +251,53 @@ udf_get_fileident(void * buffer, int bufsize, int * offset) ...@@ -255,56 +251,53 @@ udf_get_fileident(void * buffer, int bufsize, int * offset)
} }
#if 0 #if 0
static extent_ad * static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
udf_get_fileextent(void * buffer, int bufsize, int * offset)
{ {
extent_ad * ext; extent_ad *ext;
struct fileEntry *fe; struct fileEntry *fe;
uint8_t * ptr; uint8_t *ptr;
if ( (!buffer) || (!offset) ) if ((!buffer) || (!offset)) {
{
printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n"); printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
return NULL; return NULL;
} }
fe = (struct fileEntry *)buffer; fe = (struct fileEntry *)buffer;
if ( le16_to_cpu(fe->descTag.tagIdent) != TAG_IDENT_FE ) if (le16_to_cpu(fe->descTag.tagIdent) != TAG_IDENT_FE) {
{
udf_debug("0x%x != TAG_IDENT_FE\n", udf_debug("0x%x != TAG_IDENT_FE\n",
le16_to_cpu(fe->descTag.tagIdent)); le16_to_cpu(fe->descTag.tagIdent));
return NULL; return NULL;
} }
ptr=(uint8_t *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr); ptr =
(uint8_t *) (fe->extendedAttr) +
le32_to_cpu(fe->lengthExtendedAttr);
if ( (*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)) ) if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs))) {
{
ptr += *offset; ptr += *offset;
} }
ext = (extent_ad *)ptr; ext = (extent_ad *) ptr;
*offset = *offset + sizeof(extent_ad); *offset = *offset + sizeof(extent_ad);
return ext; return ext;
} }
#endif #endif
short_ad * short_ad *udf_get_fileshortad(uint8_t * ptr, int maxoffset, int *offset,
udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset, int inc) int inc)
{ {
short_ad *sa; short_ad *sa;
if ( (!ptr) || (!offset) ) if ((!ptr) || (!offset)) {
{
printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n"); printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
return NULL; return NULL;
} }
if ( (*offset < 0) || ((*offset + sizeof(short_ad)) > maxoffset) ) if ((*offset < 0) || ((*offset + sizeof(short_ad)) > maxoffset))
return NULL; return NULL;
else if ((sa = (short_ad *)ptr)->extLength == 0) else if ((sa = (short_ad *) ptr)->extLength == 0)
return NULL; return NULL;
if (inc) if (inc)
...@@ -312,20 +305,18 @@ udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset, int inc) ...@@ -312,20 +305,18 @@ udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset, int inc)
return sa; return sa;
} }
long_ad * long_ad *udf_get_filelongad(uint8_t * ptr, int maxoffset, int *offset, int inc)
udf_get_filelongad(uint8_t *ptr, int maxoffset, int * offset, int inc)
{ {
long_ad *la; long_ad *la;
if ( (!ptr) || (!offset) ) if ((!ptr) || (!offset)) {
{
printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n"); printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
return NULL; return NULL;
} }
if ( (*offset < 0) || ((*offset + sizeof(long_ad)) > maxoffset) ) if ((*offset < 0) || ((*offset + sizeof(long_ad)) > maxoffset))
return NULL; return NULL;
else if ((la = (long_ad *)ptr)->extLength == 0) else if ((la = (long_ad *) ptr)->extLength == 0)
return NULL; return NULL;
if (inc) if (inc)
......
...@@ -38,10 +38,9 @@ ...@@ -38,10 +38,9 @@
#define _ECMA_167_H 1 #define _ECMA_167_H 1
/* Character set specification (ECMA 167r3 1/7.2.1) */ /* Character set specification (ECMA 167r3 1/7.2.1) */
typedef struct typedef struct {
{ uint8_t charSetType;
uint8_t charSetType; uint8_t charSetInfo[63];
uint8_t charSetInfo[63];
} __attribute__ ((packed)) charspec; } __attribute__ ((packed)) charspec;
/* Character Set Type (ECMA 167r3 1/7.2.1.1) */ /* Character Set Type (ECMA 167r3 1/7.2.1.1) */
...@@ -55,35 +54,33 @@ typedef struct ...@@ -55,35 +54,33 @@ typedef struct
#define CHARSPEC_TYPE_CS7 0x07 /* (1/7.2.9) */ #define CHARSPEC_TYPE_CS7 0x07 /* (1/7.2.9) */
#define CHARSPEC_TYPE_CS8 0x08 /* (1/7.2.10) */ #define CHARSPEC_TYPE_CS8 0x08 /* (1/7.2.10) */
typedef uint8_t dstring; typedef uint8_t dstring;
/* Timestamp (ECMA 167r3 1/7.3) */ /* Timestamp (ECMA 167r3 1/7.3) */
typedef struct typedef struct {
{ __le16 typeAndTimezone;
__le16 typeAndTimezone; __le16 year;
__le16 year; uint8_t month;
uint8_t month; uint8_t day;
uint8_t day; uint8_t hour;
uint8_t hour; uint8_t minute;
uint8_t minute; uint8_t second;
uint8_t second; uint8_t centiseconds;
uint8_t centiseconds; uint8_t hundredsOfMicroseconds;
uint8_t hundredsOfMicroseconds; uint8_t microseconds;
uint8_t microseconds;
} __attribute__ ((packed)) timestamp; } __attribute__ ((packed)) timestamp;
typedef struct typedef struct {
{ uint16_t typeAndTimezone;
uint16_t typeAndTimezone; int16_t year;
int16_t year; uint8_t month;
uint8_t month; uint8_t day;
uint8_t day; uint8_t hour;
uint8_t hour; uint8_t minute;
uint8_t minute; uint8_t second;
uint8_t second; uint8_t centiseconds;
uint8_t centiseconds; uint8_t hundredsOfMicroseconds;
uint8_t hundredsOfMicroseconds; uint8_t microseconds;
uint8_t microseconds;
} __attribute__ ((packed)) kernel_timestamp; } __attribute__ ((packed)) kernel_timestamp;
/* Type and Time Zone (ECMA 167r3 1/7.3.1) */ /* Type and Time Zone (ECMA 167r3 1/7.3.1) */
...@@ -94,11 +91,10 @@ typedef struct ...@@ -94,11 +91,10 @@ typedef struct
#define TIMESTAMP_TIMEZONE_MASK 0x0FFF #define TIMESTAMP_TIMEZONE_MASK 0x0FFF
/* Entity identifier (ECMA 167r3 1/7.4) */ /* Entity identifier (ECMA 167r3 1/7.4) */
typedef struct typedef struct {
{ uint8_t flags;
uint8_t flags; uint8_t ident[23];
uint8_t ident[23]; uint8_t identSuffix[8];
uint8_t identSuffix[8];
} __attribute__ ((packed)) regid; } __attribute__ ((packed)) regid;
/* Flags (ECMA 167r3 1/7.4.1) */ /* Flags (ECMA 167r3 1/7.4.1) */
...@@ -107,12 +103,11 @@ typedef struct ...@@ -107,12 +103,11 @@ typedef struct
/* Volume Structure Descriptor (ECMA 167r3 2/9.1) */ /* Volume Structure Descriptor (ECMA 167r3 2/9.1) */
#define VSD_STD_ID_LEN 5 #define VSD_STD_ID_LEN 5
struct volStructDesc struct volStructDesc {
{ uint8_t structType;
uint8_t structType; uint8_t stdIdent[VSD_STD_ID_LEN];
uint8_t stdIdent[VSD_STD_ID_LEN]; uint8_t structVersion;
uint8_t structVersion; uint8_t structData[2041];
uint8_t structData[2041];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Standard Identifier (EMCA 167r2 2/9.1.2) */ /* Standard Identifier (EMCA 167r2 2/9.1.2) */
...@@ -127,69 +122,63 @@ struct volStructDesc ...@@ -127,69 +122,63 @@ struct volStructDesc
#define VSD_STD_ID_TEA01 "TEA01" /* (2/9.3) */ #define VSD_STD_ID_TEA01 "TEA01" /* (2/9.3) */
/* Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) */ /* Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) */
struct beginningExtendedAreaDesc struct beginningExtendedAreaDesc {
{ uint8_t structType;
uint8_t structType; uint8_t stdIdent[VSD_STD_ID_LEN];
uint8_t stdIdent[VSD_STD_ID_LEN]; uint8_t structVersion;
uint8_t structVersion; uint8_t structData[2041];
uint8_t structData[2041];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */ /* Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */
struct terminatingExtendedAreaDesc struct terminatingExtendedAreaDesc {
{ uint8_t structType;
uint8_t structType; uint8_t stdIdent[VSD_STD_ID_LEN];
uint8_t stdIdent[VSD_STD_ID_LEN]; uint8_t structVersion;
uint8_t structVersion; uint8_t structData[2041];
uint8_t structData[2041];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Boot Descriptor (ECMA 167r3 2/9.4) */ /* Boot Descriptor (ECMA 167r3 2/9.4) */
struct bootDesc struct bootDesc {
{ uint8_t structType;
uint8_t structType; uint8_t stdIdent[VSD_STD_ID_LEN];
uint8_t stdIdent[VSD_STD_ID_LEN]; uint8_t structVersion;
uint8_t structVersion; uint8_t reserved1;
uint8_t reserved1; regid archType;
regid archType; regid bootIdent;
regid bootIdent; __le32 bootExtLocation;
__le32 bootExtLocation; __le32 bootExtLength;
__le32 bootExtLength; __le64 loadAddress;
__le64 loadAddress; __le64 startAddress;
__le64 startAddress; timestamp descCreationDateAndTime;
timestamp descCreationDateAndTime; __le16 flags;
__le16 flags; uint8_t reserved2[32];
uint8_t reserved2[32]; uint8_t bootUse[1906];
uint8_t bootUse[1906];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Flags (ECMA 167r3 2/9.4.12) */ /* Flags (ECMA 167r3 2/9.4.12) */
#define BOOT_FLAGS_ERASE 0x01 #define BOOT_FLAGS_ERASE 0x01
/* Extent Descriptor (ECMA 167r3 3/7.1) */ /* Extent Descriptor (ECMA 167r3 3/7.1) */
typedef struct typedef struct {
{ __le32 extLength;
__le32 extLength; __le32 extLocation;
__le32 extLocation;
} __attribute__ ((packed)) extent_ad; } __attribute__ ((packed)) extent_ad;
typedef struct typedef struct {
{ uint32_t extLength;
uint32_t extLength; uint32_t extLocation;
uint32_t extLocation;
} kernel_extent_ad; } kernel_extent_ad;
/* Descriptor Tag (ECMA 167r3 3/7.2) */ /* Descriptor Tag (ECMA 167r3 3/7.2) */
typedef struct typedef struct {
{ __le16 tagIdent;
__le16 tagIdent; __le16 descVersion;
__le16 descVersion; uint8_t tagChecksum;
uint8_t tagChecksum; uint8_t reserved;
uint8_t reserved; __le16 tagSerialNum;
__le16 tagSerialNum; __le16 descCRC;
__le16 descCRC; __le16 descCRCLength;
__le16 descCRCLength; __le32 tagLocation;
__le32 tagLocation;
} __attribute__ ((packed)) tag; } __attribute__ ((packed)) tag;
/* Tag Identifier (ECMA 167r3 3/7.2.1) */ /* Tag Identifier (ECMA 167r3 3/7.2.1) */
...@@ -204,87 +193,81 @@ typedef struct ...@@ -204,87 +193,81 @@ typedef struct
#define TAG_IDENT_LVID 0x0009 #define TAG_IDENT_LVID 0x0009
/* NSR Descriptor (ECMA 167r3 3/9.1) */ /* NSR Descriptor (ECMA 167r3 3/9.1) */
struct NSRDesc struct NSRDesc {
{ uint8_t structType;
uint8_t structType; uint8_t stdIdent[VSD_STD_ID_LEN];
uint8_t stdIdent[VSD_STD_ID_LEN]; uint8_t structVersion;
uint8_t structVersion; uint8_t reserved;
uint8_t reserved; uint8_t structData[2040];
uint8_t structData[2040]; } __attribute__ ((packed));
} __attribute__ ((packed));
/* Primary Volume Descriptor (ECMA 167r3 3/10.1) */ /* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
struct primaryVolDesc struct primaryVolDesc {
{ tag descTag;
tag descTag; __le32 volDescSeqNum;
__le32 volDescSeqNum; __le32 primaryVolDescNum;
__le32 primaryVolDescNum; dstring volIdent[32];
dstring volIdent[32]; __le16 volSeqNum;
__le16 volSeqNum; __le16 maxVolSeqNum;
__le16 maxVolSeqNum; __le16 interchangeLvl;
__le16 interchangeLvl; __le16 maxInterchangeLvl;
__le16 maxInterchangeLvl; __le32 charSetList;
__le32 charSetList; __le32 maxCharSetList;
__le32 maxCharSetList; dstring volSetIdent[128];
dstring volSetIdent[128]; charspec descCharSet;
charspec descCharSet; charspec explanatoryCharSet;
charspec explanatoryCharSet; extent_ad volAbstract;
extent_ad volAbstract; extent_ad volCopyright;
extent_ad volCopyright; regid appIdent;
regid appIdent; timestamp recordingDateAndTime;
timestamp recordingDateAndTime; regid impIdent;
regid impIdent; uint8_t impUse[64];
uint8_t impUse[64]; __le32 predecessorVolDescSeqLocation;
__le32 predecessorVolDescSeqLocation; __le16 flags;
__le16 flags; uint8_t reserved[22];
uint8_t reserved[22];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Flags (ECMA 167r3 3/10.1.21) */ /* Flags (ECMA 167r3 3/10.1.21) */
#define PVD_FLAGS_VSID_COMMON 0x0001 #define PVD_FLAGS_VSID_COMMON 0x0001
/* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */ /* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */
struct anchorVolDescPtr struct anchorVolDescPtr {
{ tag descTag;
tag descTag; extent_ad mainVolDescSeqExt;
extent_ad mainVolDescSeqExt; extent_ad reserveVolDescSeqExt;
extent_ad reserveVolDescSeqExt; uint8_t reserved[480];
uint8_t reserved[480];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */ /* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
struct volDescPtr struct volDescPtr {
{ tag descTag;
tag descTag; __le32 volDescSeqNum;
__le32 volDescSeqNum; extent_ad nextVolDescSeqExt;
extent_ad nextVolDescSeqExt; uint8_t reserved[484];
uint8_t reserved[484];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */ /* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
struct impUseVolDesc struct impUseVolDesc {
{ tag descTag;
tag descTag; __le32 volDescSeqNum;
__le32 volDescSeqNum; regid impIdent;
regid impIdent; uint8_t impUse[460];
uint8_t impUse[460];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Partition Descriptor (ECMA 167r3 3/10.5) */ /* Partition Descriptor (ECMA 167r3 3/10.5) */
struct partitionDesc struct partitionDesc {
{ tag descTag;
tag descTag; __le32 volDescSeqNum;
__le32 volDescSeqNum; __le16 partitionFlags;
__le16 partitionFlags; __le16 partitionNumber;
__le16 partitionNumber; regid partitionContents;
regid partitionContents; uint8_t partitionContentsUse[128];
uint8_t partitionContentsUse[128]; __le32 accessType;
__le32 accessType; __le32 partitionStartingLocation;
__le32 partitionStartingLocation; __le32 partitionLength;
__le32 partitionLength; regid impIdent;
regid impIdent; uint8_t impUse[128];
uint8_t impUse[128]; uint8_t reserved[156];
uint8_t reserved[156];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Partition Flags (ECMA 167r3 3/10.5.3) */ /* Partition Flags (ECMA 167r3 3/10.5.3) */
...@@ -307,29 +290,27 @@ struct partitionDesc ...@@ -307,29 +290,27 @@ struct partitionDesc
#define PD_ACCESS_TYPE_OVERWRITABLE 0x00000004 #define PD_ACCESS_TYPE_OVERWRITABLE 0x00000004
/* Logical Volume Descriptor (ECMA 167r3 3/10.6) */ /* Logical Volume Descriptor (ECMA 167r3 3/10.6) */
struct logicalVolDesc struct logicalVolDesc {
{ tag descTag;
tag descTag; __le32 volDescSeqNum;
__le32 volDescSeqNum; charspec descCharSet;
charspec descCharSet; dstring logicalVolIdent[128];
dstring logicalVolIdent[128]; __le32 logicalBlockSize;
__le32 logicalBlockSize; regid domainIdent;
regid domainIdent; uint8_t logicalVolContentsUse[16];
uint8_t logicalVolContentsUse[16]; __le32 mapTableLength;
__le32 mapTableLength; __le32 numPartitionMaps;
__le32 numPartitionMaps; regid impIdent;
regid impIdent; uint8_t impUse[128];
uint8_t impUse[128]; extent_ad integritySeqExt;
extent_ad integritySeqExt; uint8_t partitionMaps[0];
uint8_t partitionMaps[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Generic Partition Map (ECMA 167r3 3/10.7.1) */ /* Generic Partition Map (ECMA 167r3 3/10.7.1) */
struct genericPartitionMap struct genericPartitionMap {
{ uint8_t partitionMapType;
uint8_t partitionMapType; uint8_t partitionMapLength;
uint8_t partitionMapLength; uint8_t partitionMapping[0];
uint8_t partitionMapping[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Partition Map Type (ECMA 167r3 3/10.7.1.1) */ /* Partition Map Type (ECMA 167r3 3/10.7.1.1) */
...@@ -338,51 +319,46 @@ struct genericPartitionMap ...@@ -338,51 +319,46 @@ struct genericPartitionMap
#define GP_PARTITION_MAP_TYPE_2 0x02 #define GP_PARTITION_MAP_TYPE_2 0x02
/* Type 1 Partition Map (ECMA 167r3 3/10.7.2) */ /* Type 1 Partition Map (ECMA 167r3 3/10.7.2) */
struct genericPartitionMap1 struct genericPartitionMap1 {
{ uint8_t partitionMapType;
uint8_t partitionMapType; uint8_t partitionMapLength;
uint8_t partitionMapLength; __le16 volSeqNum;
__le16 volSeqNum; __le16 partitionNum;
__le16 partitionNum;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */ /* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */
struct genericPartitionMap2 struct genericPartitionMap2 {
{ uint8_t partitionMapType;
uint8_t partitionMapType; uint8_t partitionMapLength;
uint8_t partitionMapLength; uint8_t partitionIdent[62];
uint8_t partitionIdent[62];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */ /* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
struct unallocSpaceDesc struct unallocSpaceDesc {
{ tag descTag;
tag descTag; __le32 volDescSeqNum;
__le32 volDescSeqNum; __le32 numAllocDescs;
__le32 numAllocDescs; extent_ad allocDescs[0];
extent_ad allocDescs[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Terminating Descriptor (ECMA 167r3 3/10.9) */ /* Terminating Descriptor (ECMA 167r3 3/10.9) */
struct terminatingDesc struct terminatingDesc {
{ tag descTag;
tag descTag; uint8_t reserved[496];
uint8_t reserved[496];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */ /* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
struct logicalVolIntegrityDesc struct logicalVolIntegrityDesc {
{ tag descTag;
tag descTag; timestamp recordingDateAndTime;
timestamp recordingDateAndTime; __le32 integrityType;
__le32 integrityType; extent_ad nextIntegrityExt;
extent_ad nextIntegrityExt; uint8_t logicalVolContentsUse[32];
uint8_t logicalVolContentsUse[32]; __le32 numOfPartitions;
__le32 numOfPartitions; __le32 lengthOfImpUse;
__le32 lengthOfImpUse; __le32 freeSpaceTable[0];
__le32 freeSpaceTable[0]; __le32 sizeTable[0];
__le32 sizeTable[0]; uint8_t impUse[0];
uint8_t impUse[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Integrity Type (ECMA 167r3 3/10.10.3) */ /* Integrity Type (ECMA 167r3 3/10.10.3) */
...@@ -390,56 +366,49 @@ struct logicalVolIntegrityDesc ...@@ -390,56 +366,49 @@ struct logicalVolIntegrityDesc
#define LVID_INTEGRITY_TYPE_CLOSE 0x00000001 #define LVID_INTEGRITY_TYPE_CLOSE 0x00000001
/* Recorded Address (ECMA 167r3 4/7.1) */ /* Recorded Address (ECMA 167r3 4/7.1) */
typedef struct typedef struct {
{ __le32 logicalBlockNum;
__le32 logicalBlockNum; __le16 partitionReferenceNum;
__le16 partitionReferenceNum;
} __attribute__ ((packed)) lb_addr; } __attribute__ ((packed)) lb_addr;
/* ... and its in-core analog */ /* ... and its in-core analog */
typedef struct typedef struct {
{ uint32_t logicalBlockNum;
uint32_t logicalBlockNum; uint16_t partitionReferenceNum;
uint16_t partitionReferenceNum;
} kernel_lb_addr; } kernel_lb_addr;
/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */ /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
typedef struct typedef struct {
{ __le32 extLength;
__le32 extLength; __le32 extPosition;
__le32 extPosition;
} __attribute__ ((packed)) short_ad; } __attribute__ ((packed)) short_ad;
/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */ /* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
typedef struct typedef struct {
{ __le32 extLength;
__le32 extLength; lb_addr extLocation;
lb_addr extLocation; uint8_t impUse[6];
uint8_t impUse[6];
} __attribute__ ((packed)) long_ad; } __attribute__ ((packed)) long_ad;
typedef struct typedef struct {
{ uint32_t extLength;
uint32_t extLength; kernel_lb_addr extLocation;
kernel_lb_addr extLocation; uint8_t impUse[6];
uint8_t impUse[6];
} kernel_long_ad; } kernel_long_ad;
/* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */ /* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
typedef struct typedef struct {
{ __le32 extLength;
__le32 extLength; __le32 recordedLength;
__le32 recordedLength; __le32 informationLength;
__le32 informationLength; lb_addr extLocation;
lb_addr extLocation;
} __attribute__ ((packed)) ext_ad; } __attribute__ ((packed)) ext_ad;
typedef struct typedef struct {
{ uint32_t extLength;
uint32_t extLength; uint32_t recordedLength;
uint32_t recordedLength; uint32_t informationLength;
uint32_t informationLength; kernel_lb_addr extLocation;
kernel_lb_addr extLocation;
} kernel_ext_ad; } kernel_ext_ad;
/* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */ /* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */
...@@ -458,52 +427,49 @@ typedef struct ...@@ -458,52 +427,49 @@ typedef struct
#define TAG_IDENT_EFE 0x010A #define TAG_IDENT_EFE 0x010A
/* File Set Descriptor (ECMA 167r3 4/14.1) */ /* File Set Descriptor (ECMA 167r3 4/14.1) */
struct fileSetDesc struct fileSetDesc {
{ tag descTag;
tag descTag; timestamp recordingDateAndTime;
timestamp recordingDateAndTime; __le16 interchangeLvl;
__le16 interchangeLvl; __le16 maxInterchangeLvl;
__le16 maxInterchangeLvl; __le32 charSetList;
__le32 charSetList; __le32 maxCharSetList;
__le32 maxCharSetList; __le32 fileSetNum;
__le32 fileSetNum; __le32 fileSetDescNum;
__le32 fileSetDescNum; charspec logicalVolIdentCharSet;
charspec logicalVolIdentCharSet; dstring logicalVolIdent[128];
dstring logicalVolIdent[128]; charspec fileSetCharSet;
charspec fileSetCharSet; dstring fileSetIdent[32];
dstring fileSetIdent[32]; dstring copyrightFileIdent[32];
dstring copyrightFileIdent[32]; dstring abstractFileIdent[32];
dstring abstractFileIdent[32]; long_ad rootDirectoryICB;
long_ad rootDirectoryICB; regid domainIdent;
regid domainIdent; long_ad nextExt;
long_ad nextExt; long_ad streamDirectoryICB;
long_ad streamDirectoryICB; uint8_t reserved[32];
uint8_t reserved[32];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Partition Header Descriptor (ECMA 167r3 4/14.3) */ /* Partition Header Descriptor (ECMA 167r3 4/14.3) */
struct partitionHeaderDesc struct partitionHeaderDesc {
{ short_ad unallocSpaceTable;
short_ad unallocSpaceTable; short_ad unallocSpaceBitmap;
short_ad unallocSpaceBitmap; short_ad partitionIntegrityTable;
short_ad partitionIntegrityTable; short_ad freedSpaceTable;
short_ad freedSpaceTable; short_ad freedSpaceBitmap;
short_ad freedSpaceBitmap; uint8_t reserved[88];
uint8_t reserved[88];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* File Identifier Descriptor (ECMA 167r3 4/14.4) */ /* File Identifier Descriptor (ECMA 167r3 4/14.4) */
struct fileIdentDesc struct fileIdentDesc {
{ tag descTag;
tag descTag; __le16 fileVersionNum;
__le16 fileVersionNum; uint8_t fileCharacteristics;
uint8_t fileCharacteristics; uint8_t lengthFileIdent;
uint8_t lengthFileIdent; long_ad icb;
long_ad icb; __le16 lengthOfImpUse;
__le16 lengthOfImpUse; uint8_t impUse[0];
uint8_t impUse[0]; uint8_t fileIdent[0];
uint8_t fileIdent[0]; uint8_t padding[0];
uint8_t padding[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* File Characteristics (ECMA 167r3 4/14.4.3) */ /* File Characteristics (ECMA 167r3 4/14.4.3) */
...@@ -514,24 +480,22 @@ struct fileIdentDesc ...@@ -514,24 +480,22 @@ struct fileIdentDesc
#define FID_FILE_CHAR_METADATA 0x10 #define FID_FILE_CHAR_METADATA 0x10
/* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */ /* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */
struct allocExtDesc struct allocExtDesc {
{ tag descTag;
tag descTag; __le32 previousAllocExtLocation;
__le32 previousAllocExtLocation; __le32 lengthAllocDescs;
__le32 lengthAllocDescs;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* ICB Tag (ECMA 167r3 4/14.6) */ /* ICB Tag (ECMA 167r3 4/14.6) */
typedef struct typedef struct {
{ __le32 priorRecordedNumDirectEntries;
__le32 priorRecordedNumDirectEntries; __le16 strategyType;
__le16 strategyType; __le16 strategyParameter;
__le16 strategyParameter; __le16 numEntries;
__le16 numEntries; uint8_t reserved;
uint8_t reserved; uint8_t fileType;
uint8_t fileType; lb_addr parentICBLocation;
lb_addr parentICBLocation; __le16 flags;
__le16 flags;
} __attribute__ ((packed)) icbtag; } __attribute__ ((packed)) icbtag;
/* Strategy Type (ECMA 167r3 4/14.6.2) */ /* Strategy Type (ECMA 167r3 4/14.6.2) */
...@@ -576,45 +540,42 @@ typedef struct ...@@ -576,45 +540,42 @@ typedef struct
#define ICBTAG_FLAG_STREAM 0x2000 #define ICBTAG_FLAG_STREAM 0x2000
/* Indirect Entry (ECMA 167r3 4/14.7) */ /* Indirect Entry (ECMA 167r3 4/14.7) */
struct indirectEntry struct indirectEntry {
{ tag descTag;
tag descTag; icbtag icbTag;
icbtag icbTag; long_ad indirectICB;
long_ad indirectICB;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Terminal Entry (ECMA 167r3 4/14.8) */ /* Terminal Entry (ECMA 167r3 4/14.8) */
struct terminalEntry struct terminalEntry {
{ tag descTag;
tag descTag; icbtag icbTag;
icbtag icbTag;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* File Entry (ECMA 167r3 4/14.9) */ /* File Entry (ECMA 167r3 4/14.9) */
struct fileEntry struct fileEntry {
{ tag descTag;
tag descTag; icbtag icbTag;
icbtag icbTag; __le32 uid;
__le32 uid; __le32 gid;
__le32 gid; __le32 permissions;
__le32 permissions; __le16 fileLinkCount;
__le16 fileLinkCount; uint8_t recordFormat;
uint8_t recordFormat; uint8_t recordDisplayAttr;
uint8_t recordDisplayAttr; __le32 recordLength;
__le32 recordLength; __le64 informationLength;
__le64 informationLength; __le64 logicalBlocksRecorded;
__le64 logicalBlocksRecorded; timestamp accessTime;
timestamp accessTime; timestamp modificationTime;
timestamp modificationTime; timestamp attrTime;
timestamp attrTime; __le32 checkpoint;
__le32 checkpoint; long_ad extendedAttrICB;
long_ad extendedAttrICB; regid impIdent;
regid impIdent; __le64 uniqueID;
__le64 uniqueID; __le32 lengthExtendedAttr;
__le32 lengthExtendedAttr; __le32 lengthAllocDescs;
__le32 lengthAllocDescs; uint8_t extendedAttr[0];
uint8_t extendedAttr[0]; uint8_t allocDescs[0];
uint8_t allocDescs[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Permissions (ECMA 167r3 4/14.9.5) */ /* Permissions (ECMA 167r3 4/14.9.5) */
...@@ -655,57 +616,52 @@ struct fileEntry ...@@ -655,57 +616,52 @@ struct fileEntry
#define FE_RECORD_DISPLAY_ATTR_3 0x03 #define FE_RECORD_DISPLAY_ATTR_3 0x03
/* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */ /* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */
struct extendedAttrHeaderDesc struct extendedAttrHeaderDesc {
{ tag descTag;
tag descTag; __le32 impAttrLocation;
__le32 impAttrLocation; __le32 appAttrLocation;
__le32 appAttrLocation;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Generic Format (ECMA 167r3 4/14.10.2) */ /* Generic Format (ECMA 167r3 4/14.10.2) */
struct genericFormat struct genericFormat {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; uint8_t attrData[0];
uint8_t attrData[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Character Set Information (ECMA 167r3 4/14.10.3) */ /* Character Set Information (ECMA 167r3 4/14.10.3) */
struct charSetInfo struct charSetInfo {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; __le32 escapeSeqLength;
__le32 escapeSeqLength; uint8_t charSetType;
uint8_t charSetType; uint8_t escapeSeq[0];
uint8_t escapeSeq[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Alternate Permissions (ECMA 167r3 4/14.10.4) */ /* Alternate Permissions (ECMA 167r3 4/14.10.4) */
struct altPerms struct altPerms {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; __le16 ownerIdent;
__le16 ownerIdent; __le16 groupIdent;
__le16 groupIdent; __le16 permission;
__le16 permission;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* File Times Extended Attribute (ECMA 167r3 4/14.10.5) */ /* File Times Extended Attribute (ECMA 167r3 4/14.10.5) */
struct fileTimesExtAttr struct fileTimesExtAttr {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; __le32 dataLength;
__le32 dataLength; __le32 fileTimeExistence;
__le32 fileTimeExistence; uint8_t fileTimes;
uint8_t fileTimes;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* FileTimeExistence (ECMA 167r3 4/14.10.5.6) */ /* FileTimeExistence (ECMA 167r3 4/14.10.5.6) */
...@@ -715,52 +671,48 @@ struct fileTimesExtAttr ...@@ -715,52 +671,48 @@ struct fileTimesExtAttr
#define FTE_BACKUP 0x00000002 #define FTE_BACKUP 0x00000002
/* Information Times Extended Attribute (ECMA 167r3 4/14.10.6) */ /* Information Times Extended Attribute (ECMA 167r3 4/14.10.6) */
struct infoTimesExtAttr struct infoTimesExtAttr {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; __le32 dataLength;
__le32 dataLength; __le32 infoTimeExistence;
__le32 infoTimeExistence; uint8_t infoTimes[0];
uint8_t infoTimes[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Device Specification (ECMA 167r3 4/14.10.7) */ /* Device Specification (ECMA 167r3 4/14.10.7) */
struct deviceSpec struct deviceSpec {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; __le32 impUseLength;
__le32 impUseLength; __le32 majorDeviceIdent;
__le32 majorDeviceIdent; __le32 minorDeviceIdent;
__le32 minorDeviceIdent; uint8_t impUse[0];
uint8_t impUse[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */ /* Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */
struct impUseExtAttr struct impUseExtAttr {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; __le32 impUseLength;
__le32 impUseLength; regid impIdent;
regid impIdent; uint8_t impUse[0];
uint8_t impUse[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */ /* Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */
struct appUseExtAttr struct appUseExtAttr {
{ __le32 attrType;
__le32 attrType; uint8_t attrSubtype;
uint8_t attrSubtype; uint8_t reserved[3];
uint8_t reserved[3]; __le32 attrLength;
__le32 attrLength; __le32 appUseLength;
__le32 appUseLength; regid appIdent;
regid appIdent; uint8_t appUse[0];
uint8_t appUse[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define EXTATTR_CHAR_SET 1 #define EXTATTR_CHAR_SET 1
...@@ -771,35 +723,31 @@ struct appUseExtAttr ...@@ -771,35 +723,31 @@ struct appUseExtAttr
#define EXTATTR_IMP_USE 2048 #define EXTATTR_IMP_USE 2048
#define EXTATTR_APP_USE 65536 #define EXTATTR_APP_USE 65536
/* Unallocated Space Entry (ECMA 167r3 4/14.11) */ /* Unallocated Space Entry (ECMA 167r3 4/14.11) */
struct unallocSpaceEntry struct unallocSpaceEntry {
{ tag descTag;
tag descTag; icbtag icbTag;
icbtag icbTag; __le32 lengthAllocDescs;
__le32 lengthAllocDescs; uint8_t allocDescs[0];
uint8_t allocDescs[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */ /* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
struct spaceBitmapDesc struct spaceBitmapDesc {
{ tag descTag;
tag descTag; __le32 numOfBits;
__le32 numOfBits; __le32 numOfBytes;
__le32 numOfBytes; uint8_t bitmap[0];
uint8_t bitmap[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Partition Integrity Entry (ECMA 167r3 4/14.13) */ /* Partition Integrity Entry (ECMA 167r3 4/14.13) */
struct partitionIntegrityEntry struct partitionIntegrityEntry {
{ tag descTag;
tag descTag; icbtag icbTag;
icbtag icbTag; timestamp recordingDateAndTime;
timestamp recordingDateAndTime; uint8_t integrityType;
uint8_t integrityType; uint8_t reserved[175];
uint8_t reserved[175]; regid impIdent;
regid impIdent; uint8_t impUse[256];
uint8_t impUse[256];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */ /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
...@@ -815,50 +763,47 @@ struct partitionIntegrityEntry ...@@ -815,50 +763,47 @@ struct partitionIntegrityEntry
/* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */ /* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
/* Logical Volume Header Descriptor (ECMA 167r3 4/14.15) */ /* Logical Volume Header Descriptor (ECMA 167r3 4/14.15) */
struct logicalVolHeaderDesc struct logicalVolHeaderDesc {
{ __le64 uniqueID;
__le64 uniqueID; uint8_t reserved[24];
uint8_t reserved[24];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Path Component (ECMA 167r3 4/14.16.1) */ /* Path Component (ECMA 167r3 4/14.16.1) */
struct pathComponent struct pathComponent {
{ uint8_t componentType;
uint8_t componentType; uint8_t lengthComponentIdent;
uint8_t lengthComponentIdent; __le16 componentFileVersionNum;
__le16 componentFileVersionNum; dstring componentIdent[0];
dstring componentIdent[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* File Entry (ECMA 167r3 4/14.17) */ /* File Entry (ECMA 167r3 4/14.17) */
struct extendedFileEntry struct extendedFileEntry {
{ tag descTag;
tag descTag; icbtag icbTag;
icbtag icbTag; __le32 uid;
__le32 uid; __le32 gid;
__le32 gid; __le32 permissions;
__le32 permissions; __le16 fileLinkCount;
__le16 fileLinkCount; uint8_t recordFormat;
uint8_t recordFormat; uint8_t recordDisplayAttr;
uint8_t recordDisplayAttr; __le32 recordLength;
__le32 recordLength; __le64 informationLength;
__le64 informationLength; __le64 objectSize;
__le64 objectSize; __le64 logicalBlocksRecorded;
__le64 logicalBlocksRecorded; timestamp accessTime;
timestamp accessTime; timestamp modificationTime;
timestamp modificationTime; timestamp createTime;
timestamp createTime; timestamp attrTime;
timestamp attrTime; __le32 checkpoint;
__le32 checkpoint; __le32 reserved;
__le32 reserved; long_ad extendedAttrICB;
long_ad extendedAttrICB; long_ad streamDirectoryICB;
long_ad streamDirectoryICB; regid impIdent;
regid impIdent; __le64 uniqueID;
__le64 uniqueID; __le32 lengthExtendedAttr;
__le32 lengthExtendedAttr; __le32 lengthAllocDescs;
__le32 lengthAllocDescs; uint8_t extendedAttr[0];
uint8_t extendedAttr[0]; uint8_t allocDescs[0];
uint8_t allocDescs[0]; } __attribute__ ((packed));
} __attribute__ ((packed));
#endif /* _ECMA_167_H */
#endif /* _ECMA_167_H */
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/udf_fs.h> #include <linux/udf_fs.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> /* memset */ #include <linux/string.h> /* memset */
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
static int udf_adinicb_readpage(struct file *file, struct page * page) static int udf_adinicb_readpage(struct file *file, struct page *page)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
char *kaddr; char *kaddr;
...@@ -58,7 +58,8 @@ static int udf_adinicb_readpage(struct file *file, struct page * page) ...@@ -58,7 +58,8 @@ static int udf_adinicb_readpage(struct file *file, struct page * page)
return 0; return 0;
} }
static int udf_adinicb_writepage(struct page *page, struct writeback_control *wbc) static int udf_adinicb_writepage(struct page *page,
struct writeback_control *wbc)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
char *kaddr; char *kaddr;
...@@ -74,19 +75,21 @@ static int udf_adinicb_writepage(struct page *page, struct writeback_control *wb ...@@ -74,19 +75,21 @@ static int udf_adinicb_writepage(struct page *page, struct writeback_control *wb
return 0; return 0;
} }
static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) static int udf_adinicb_prepare_write(struct file *file, struct page *page,
unsigned offset, unsigned to)
{ {
kmap(page); kmap(page);
return 0; return 0;
} }
static int udf_adinicb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) static int udf_adinicb_commit_write(struct file *file, struct page *page,
unsigned offset, unsigned to)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
char *kaddr = page_address(page); char *kaddr = page_address(page);
memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset,
kaddr + offset, to - offset); kaddr + offset, to - offset);
mark_inode_dirty(inode); mark_inode_dirty(inode);
SetPageUptodate(page); SetPageUptodate(page);
kunmap(page); kunmap(page);
...@@ -97,15 +100,15 @@ static int udf_adinicb_commit_write(struct file *file, struct page *page, unsign ...@@ -97,15 +100,15 @@ static int udf_adinicb_commit_write(struct file *file, struct page *page, unsign
} }
const struct address_space_operations udf_adinicb_aops = { const struct address_space_operations udf_adinicb_aops = {
.readpage = udf_adinicb_readpage, .readpage = udf_adinicb_readpage,
.writepage = udf_adinicb_writepage, .writepage = udf_adinicb_writepage,
.sync_page = block_sync_page, .sync_page = block_sync_page,
.prepare_write = udf_adinicb_prepare_write, .prepare_write = udf_adinicb_prepare_write,
.commit_write = udf_adinicb_commit_write, .commit_write = udf_adinicb_commit_write,
}; };
static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t ppos) unsigned long nr_segs, loff_t ppos)
{ {
ssize_t retval; ssize_t retval;
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
...@@ -113,25 +116,20 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -113,25 +116,20 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
int err, pos; int err, pos;
size_t count = iocb->ki_left; size_t count = iocb->ki_left;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
{
if (file->f_flags & O_APPEND) if (file->f_flags & O_APPEND)
pos = inode->i_size; pos = inode->i_size;
else else
pos = ppos; pos = ppos;
if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + if (inode->i_sb->s_blocksize <
pos + count)) (udf_file_entry_alloc_offset(inode) + pos + count)) {
{
udf_expand_file_adinicb(inode, pos + count, &err); udf_expand_file_adinicb(inode, pos + count, &err);
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
{
udf_debug("udf_expand_adinicb: err=%d\n", err); udf_debug("udf_expand_adinicb: err=%d\n", err);
return err; return err;
} }
} } else {
else
{
if (pos + count > inode->i_size) if (pos + count > inode->i_size)
UDF_I_LENALLOC(inode) = pos + count; UDF_I_LENALLOC(inode) = pos + count;
else else
...@@ -181,48 +179,47 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -181,48 +179,47 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
* Written, tested, and released. * Written, tested, and released.
*/ */
int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
int result = -EINVAL; int result = -EINVAL;
if ( file_permission(filp, MAY_READ) != 0 ) if (file_permission(filp, MAY_READ) != 0) {
{ udf_debug("no permission to access inode %lu\n", inode->i_ino);
udf_debug("no permission to access inode %lu\n",
inode->i_ino);
return -EPERM; return -EPERM;
} }
if ( !arg ) if (!arg) {
{
udf_debug("invalid argument to udf_ioctl\n"); udf_debug("invalid argument to udf_ioctl\n");
return -EINVAL; return -EINVAL;
} }
switch (cmd) switch (cmd) {
{ case UDF_GETVOLIDENT:
case UDF_GETVOLIDENT: return copy_to_user((char __user *)arg,
return copy_to_user((char __user *)arg, UDF_SB_VOLIDENT(inode->i_sb),
UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0; 32) ? -EFAULT : 0;
case UDF_RELOCATE_BLOCKS: case UDF_RELOCATE_BLOCKS:
{ {
long old, new; long old, new;
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_ADMIN))
if (get_user(old, (long __user *)arg)) return -EFAULT; return -EACCES;
if (get_user(old, (long __user *)arg))
return -EFAULT;
if ((result = udf_relocate_blocks(inode->i_sb, if ((result = udf_relocate_blocks(inode->i_sb,
old, &new)) == 0) old, &new)) == 0)
result = put_user(new, (long __user *)arg); result = put_user(new, (long __user *)arg);
return result; return result;
} }
case UDF_GETEASIZE: case UDF_GETEASIZE:
result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg); result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg);
break; break;
case UDF_GETEABLOCK: case UDF_GETEABLOCK:
result = copy_to_user((char __user *)arg, UDF_I_DATA(inode), result = copy_to_user((char __user *)arg, UDF_I_DATA(inode),
UDF_I_LENEATTR(inode)) ? -EFAULT : 0; UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
break; break;
} }
return result; return result;
...@@ -240,10 +237,9 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -240,10 +237,9 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
* HISTORY * HISTORY
* *
*/ */
static int udf_release_file(struct inode * inode, struct file * filp) static int udf_release_file(struct inode *inode, struct file *filp)
{ {
if (filp->f_mode & FMODE_WRITE) if (filp->f_mode & FMODE_WRITE) {
{
lock_kernel(); lock_kernel();
udf_discard_prealloc(inode); udf_discard_prealloc(inode);
unlock_kernel(); unlock_kernel();
...@@ -252,18 +248,18 @@ static int udf_release_file(struct inode * inode, struct file * filp) ...@@ -252,18 +248,18 @@ static int udf_release_file(struct inode * inode, struct file * filp)
} }
const struct file_operations udf_file_operations = { const struct file_operations udf_file_operations = {
.read = do_sync_read, .read = do_sync_read,
.aio_read = generic_file_aio_read, .aio_read = generic_file_aio_read,
.ioctl = udf_ioctl, .ioctl = udf_ioctl,
.open = generic_file_open, .open = generic_file_open,
.mmap = generic_file_mmap, .mmap = generic_file_mmap,
.write = do_sync_write, .write = do_sync_write,
.aio_write = udf_file_aio_write, .aio_write = udf_file_aio_write,
.release = udf_release_file, .release = udf_release_file,
.fsync = udf_fsync_file, .fsync = udf_fsync_file,
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
}; };
const struct inode_operations udf_file_inode_operations = { const struct inode_operations udf_file_inode_operations = {
.truncate = udf_truncate, .truncate = udf_truncate,
}; };
...@@ -29,7 +29,7 @@ static int udf_fsync_inode(struct inode *, int); ...@@ -29,7 +29,7 @@ static int udf_fsync_inode(struct inode *, int);
* even pass file to fsync ? * even pass file to fsync ?
*/ */
int udf_fsync_file(struct file * file, struct dentry *dentry, int datasync) int udf_fsync_file(struct file *file, struct dentry *dentry, int datasync)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
return udf_fsync_inode(inode, datasync); return udf_fsync_inode(inode, datasync);
...@@ -45,6 +45,6 @@ static int udf_fsync_inode(struct inode *inode, int datasync) ...@@ -45,6 +45,6 @@ static int udf_fsync_inode(struct inode *inode, int datasync)
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
return err; return err;
err |= udf_sync_inode (inode); err |= udf_sync_inode(inode);
return err ? -EIO : 0; return err ? -EIO : 0;
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
void udf_free_inode(struct inode * inode) void udf_free_inode(struct inode *inode)
{ {
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
...@@ -46,10 +46,12 @@ void udf_free_inode(struct inode * inode) ...@@ -46,10 +46,12 @@ void udf_free_inode(struct inode * inode)
if (sbi->s_lvidbh) { if (sbi->s_lvidbh) {
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
UDF_SB_LVIDIU(sb)->numDirs = UDF_SB_LVIDIU(sb)->numDirs =
cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1); cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)
- 1);
else else
UDF_SB_LVIDIU(sb)->numFiles = UDF_SB_LVIDIU(sb)->numFiles =
cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1); cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles)
- 1);
mark_buffer_dirty(sbi->s_lvidbh); mark_buffer_dirty(sbi->s_lvidbh);
} }
...@@ -58,18 +60,17 @@ void udf_free_inode(struct inode * inode) ...@@ -58,18 +60,17 @@ void udf_free_inode(struct inode * inode)
udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1); udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
} }
struct inode * udf_new_inode (struct inode *dir, int mode, int * err) struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
{ {
struct super_block *sb = dir->i_sb; struct super_block *sb = dir->i_sb;
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct inode * inode; struct inode *inode;
int block; int block;
uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum; uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum;
inode = new_inode(sb); inode = new_inode(sb);
if (!inode) if (!inode) {
{
*err = -ENOMEM; *err = -ENOMEM;
return NULL; return NULL;
} }
...@@ -81,26 +82,30 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) ...@@ -81,26 +82,30 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
UDF_I_NEXT_ALLOC_GOAL(inode) = 0; UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
UDF_I_STRAT4096(inode) = 0; UDF_I_STRAT4096(inode) = 0;
block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum, block =
start, err); udf_new_block(dir->i_sb, NULL,
if (*err) UDF_I_LOCATION(dir).partitionReferenceNum, start,
{ err);
if (*err) {
iput(inode); iput(inode);
return NULL; return NULL;
} }
mutex_lock(&sbi->s_alloc_mutex); mutex_lock(&sbi->s_alloc_mutex);
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{
struct logicalVolHeaderDesc *lvhd; struct logicalVolHeaderDesc *lvhd;
uint64_t uniqueID; uint64_t uniqueID;
lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse); lvhd =
(struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->
logicalVolContentsUse);
if (S_ISDIR(mode)) if (S_ISDIR(mode))
UDF_SB_LVIDIU(sb)->numDirs = UDF_SB_LVIDIU(sb)->numDirs =
cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1); cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)
+ 1);
else else
UDF_SB_LVIDIU(sb)->numFiles = UDF_SB_LVIDIU(sb)->numFiles =
cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1); cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles)
+ 1);
UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID); UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID);
if (!(++uniqueID & 0x00000000FFFFFFFFUL)) if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16; uniqueID += 16;
...@@ -109,35 +114,34 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) ...@@ -109,35 +114,34 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
} }
inode->i_mode = mode; inode->i_mode = mode;
inode->i_uid = current->fsuid; inode->i_uid = current->fsuid;
if (dir->i_mode & S_ISGID) if (dir->i_mode & S_ISGID) {
{
inode->i_gid = dir->i_gid; inode->i_gid = dir->i_gid;
if (S_ISDIR(mode)) if (S_ISDIR(mode))
mode |= S_ISGID; mode |= S_ISGID;
} } else
else
inode->i_gid = current->fsgid; inode->i_gid = current->fsgid;
UDF_I_LOCATION(inode).logicalBlockNum = block; UDF_I_LOCATION(inode).logicalBlockNum = block;
UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; UDF_I_LOCATION(inode).partitionReferenceNum =
UDF_I_LOCATION(dir).partitionReferenceNum;
inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0); inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
inode->i_blocks = 0; inode->i_blocks = 0;
UDF_I_LENEATTR(inode) = 0; UDF_I_LENEATTR(inode) = 0;
UDF_I_LENALLOC(inode) = 0; UDF_I_LENALLOC(inode) = 0;
UDF_I_USE(inode) = 0; UDF_I_USE(inode) = 0;
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) {
{
UDF_I_EFE(inode) = 1; UDF_I_EFE(inode) = 1;
UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE); UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
UDF_I_DATA(inode) = kzalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL); UDF_I_DATA(inode) =
} kzalloc(inode->i_sb->s_blocksize -
else sizeof(struct extendedFileEntry), GFP_KERNEL);
{ } else {
UDF_I_EFE(inode) = 0; UDF_I_EFE(inode) = 0;
UDF_I_DATA(inode) = kzalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL); UDF_I_DATA(inode) =
kzalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry),
GFP_KERNEL);
} }
if (!UDF_I_DATA(inode)) if (!UDF_I_DATA(inode)) {
{
iput(inode); iput(inode);
*err = -ENOMEM; *err = -ENOMEM;
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
...@@ -150,13 +154,12 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) ...@@ -150,13 +154,12 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
else else
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG; UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
inode->i_mtime = inode->i_atime = inode->i_ctime = inode->i_mtime = inode->i_atime = inode->i_ctime =
UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb); UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb);
insert_inode_hash(inode); insert_inode_hash(inode);
mark_inode_dirty(inode); mark_inode_dirty(inode);
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
if (DQUOT_ALLOC_INODE(inode)) if (DQUOT_ALLOC_INODE(inode)) {
{
DQUOT_DROP(inode); DQUOT_DROP(inode);
inode->i_flags |= S_NOQUOTA; inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0; inode->i_nlink = 0;
......
...@@ -51,18 +51,18 @@ static int udf_update_inode(struct inode *, int); ...@@ -51,18 +51,18 @@ static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *); static void udf_fill_inode(struct inode *, struct buffer_head *);
static int udf_alloc_i_data(struct inode *inode, size_t size); static int udf_alloc_i_data(struct inode *inode, size_t size);
static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
long *, int *); long *, int *);
static int8_t udf_insert_aext(struct inode *, struct extent_position, static int8_t udf_insert_aext(struct inode *, struct extent_position,
kernel_lb_addr, uint32_t); kernel_lb_addr, uint32_t);
static void udf_split_extents(struct inode *, int *, int, int, static void udf_split_extents(struct inode *, int *, int, int,
kernel_long_ad [EXTENT_MERGE_SIZE], int *); kernel_long_ad[EXTENT_MERGE_SIZE], int *);
static void udf_prealloc_extents(struct inode *, int, int, static void udf_prealloc_extents(struct inode *, int, int,
kernel_long_ad [EXTENT_MERGE_SIZE], int *); kernel_long_ad[EXTENT_MERGE_SIZE], int *);
static void udf_merge_extents(struct inode *, static void udf_merge_extents(struct inode *,
kernel_long_ad [EXTENT_MERGE_SIZE], int *); kernel_long_ad[EXTENT_MERGE_SIZE], int *);
static void udf_update_extents(struct inode *, static void udf_update_extents(struct inode *,
kernel_long_ad [EXTENT_MERGE_SIZE], int, int, kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
struct extent_position *); struct extent_position *);
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
/* /*
...@@ -81,7 +81,7 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); ...@@ -81,7 +81,7 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
* *
* Called at the last iput() if i_nlink is zero. * Called at the last iput() if i_nlink is zero.
*/ */
void udf_delete_inode(struct inode * inode) void udf_delete_inode(struct inode *inode)
{ {
truncate_inode_pages(&inode->i_data, 0); truncate_inode_pages(&inode->i_data, 0);
...@@ -97,7 +97,7 @@ void udf_delete_inode(struct inode * inode) ...@@ -97,7 +97,7 @@ void udf_delete_inode(struct inode * inode)
unlock_kernel(); unlock_kernel();
return; return;
no_delete: no_delete:
clear_inode(inode); clear_inode(inode);
} }
...@@ -132,26 +132,27 @@ static int udf_readpage(struct file *file, struct page *page) ...@@ -132,26 +132,27 @@ static int udf_readpage(struct file *file, struct page *page)
return block_read_full_page(page, udf_get_block); return block_read_full_page(page, udf_get_block);
} }
static int udf_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) static int udf_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{ {
return block_prepare_write(page, from, to, udf_get_block); return block_prepare_write(page, from, to, udf_get_block);
} }
static sector_t udf_bmap(struct address_space *mapping, sector_t block) static sector_t udf_bmap(struct address_space *mapping, sector_t block)
{ {
return generic_block_bmap(mapping,block,udf_get_block); return generic_block_bmap(mapping, block, udf_get_block);
} }
const struct address_space_operations udf_aops = { const struct address_space_operations udf_aops = {
.readpage = udf_readpage, .readpage = udf_readpage,
.writepage = udf_writepage, .writepage = udf_writepage,
.sync_page = block_sync_page, .sync_page = block_sync_page,
.prepare_write = udf_prepare_write, .prepare_write = udf_prepare_write,
.commit_write = generic_commit_write, .commit_write = generic_commit_write,
.bmap = udf_bmap, .bmap = udf_bmap,
}; };
void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) void udf_expand_file_adinicb(struct inode *inode, int newsize, int *err)
{ {
struct page *page; struct page *page;
char *kaddr; char *kaddr;
...@@ -163,8 +164,7 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) ...@@ -163,8 +164,7 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
/* from now on we have normal address_space methods */ /* from now on we have normal address_space methods */
inode->i_data.a_ops = &udf_aops; inode->i_data.a_ops = &udf_aops;
if (!UDF_I_LENALLOC(inode)) if (!UDF_I_LENALLOC(inode)) {
{
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT; UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
else else
...@@ -176,19 +176,18 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) ...@@ -176,19 +176,18 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
page = grab_cache_page(inode->i_mapping, 0); page = grab_cache_page(inode->i_mapping, 0);
BUG_ON(!PageLocked(page)); BUG_ON(!PageLocked(page));
if (!PageUptodate(page)) if (!PageUptodate(page)) {
{
kaddr = kmap(page); kaddr = kmap(page);
memset(kaddr + UDF_I_LENALLOC(inode), 0x00, memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode)); PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode),
UDF_I_LENALLOC(inode)); UDF_I_LENALLOC(inode));
flush_dcache_page(page); flush_dcache_page(page);
SetPageUptodate(page); SetPageUptodate(page);
kunmap(page); kunmap(page);
} }
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00, memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00,
UDF_I_LENALLOC(inode)); UDF_I_LENALLOC(inode));
UDF_I_LENALLOC(inode) = 0; UDF_I_LENALLOC(inode) = 0;
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT; UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
...@@ -201,7 +200,8 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) ...@@ -201,7 +200,8 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
int *err)
{ {
int newblock; int newblock;
struct buffer_head *dbh = NULL; struct buffer_head *dbh = NULL;
...@@ -220,8 +220,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -220,8 +220,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
else else
alloctype = ICBTAG_FLAG_AD_LONG; alloctype = ICBTAG_FLAG_AD_LONG;
if (!inode->i_size) if (!inode->i_size) {
{
UDF_I_ALLOCTYPE(inode) = alloctype; UDF_I_ALLOCTYPE(inode) = alloctype;
mark_inode_dirty(inode); mark_inode_dirty(inode);
return NULL; return NULL;
...@@ -229,13 +228,14 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -229,13 +228,14 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
/* alloc block, and copy data to it */ /* alloc block, and copy data to it */
*block = udf_new_block(inode->i_sb, inode, *block = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum, UDF_I_LOCATION(inode).partitionReferenceNum,
UDF_I_LOCATION(inode).logicalBlockNum, err); UDF_I_LOCATION(inode).logicalBlockNum, err);
if (!(*block)) if (!(*block))
return NULL; return NULL;
newblock = udf_get_pblock(inode->i_sb, *block, newblock = udf_get_pblock(inode->i_sb, *block,
UDF_I_LOCATION(inode).partitionReferenceNum, 0); UDF_I_LOCATION(inode).partitionReferenceNum,
0);
if (!newblock) if (!newblock)
return NULL; return NULL;
dbh = udf_tgetblk(inode->i_sb, newblock); dbh = udf_tgetblk(inode->i_sb, newblock);
...@@ -247,16 +247,17 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -247,16 +247,17 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
unlock_buffer(dbh); unlock_buffer(dbh);
mark_buffer_dirty_inode(dbh, inode); mark_buffer_dirty_inode(dbh, inode);
sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; sfibh.soffset = sfibh.eoffset =
(f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
sfibh.sbh = sfibh.ebh = NULL; sfibh.sbh = sfibh.ebh = NULL;
dfibh.soffset = dfibh.eoffset = 0; dfibh.soffset = dfibh.eoffset = 0;
dfibh.sbh = dfibh.ebh = dbh; dfibh.sbh = dfibh.ebh = dbh;
while ( (f_pos < size) ) while ((f_pos < size)) {
{
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); sfi =
if (!sfi) udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL,
{ NULL, NULL);
if (!sfi) {
brelse(dbh); brelse(dbh);
return NULL; return NULL;
} }
...@@ -266,8 +267,8 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -266,8 +267,8 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
dfibh.eoffset += (sfibh.eoffset - sfibh.soffset); dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset); dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse, if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) sfi->fileIdent +
{ le16_to_cpu(sfi->lengthOfImpUse))) {
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
brelse(dbh); brelse(dbh);
return NULL; return NULL;
...@@ -275,10 +276,12 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -275,10 +276,12 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
} }
mark_buffer_dirty_inode(dbh, inode); mark_buffer_dirty_inode(dbh, inode);
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0,
UDF_I_LENALLOC(inode));
UDF_I_LENALLOC(inode) = 0; UDF_I_LENALLOC(inode) = 0;
eloc.logicalBlockNum = *block; eloc.logicalBlockNum = *block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; eloc.partitionReferenceNum =
UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_size; elen = inode->i_size;
UDF_I_LENEXTENTS(inode) = elen; UDF_I_LENEXTENTS(inode) = elen;
epos.bh = NULL; epos.bh = NULL;
...@@ -292,14 +295,14 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -292,14 +295,14 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
return dbh; return dbh;
} }
static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) static int udf_get_block(struct inode *inode, sector_t block,
struct buffer_head *bh_result, int create)
{ {
int err, new; int err, new;
struct buffer_head *bh; struct buffer_head *bh;
unsigned long phys; unsigned long phys;
if (!create) if (!create) {
{
phys = udf_block_map(inode, block); phys = udf_block_map(inode, block);
if (phys) if (phys)
map_bh(bh_result, inode->i_sb, phys); map_bh(bh_result, inode->i_sb, phys);
...@@ -315,10 +318,9 @@ static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head ...@@ -315,10 +318,9 @@ static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head
if (block < 0) if (block < 0)
goto abort_negative; goto abort_negative;
if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) {
{ UDF_I_NEXT_ALLOC_BLOCK(inode)++;
UDF_I_NEXT_ALLOC_BLOCK(inode) ++; UDF_I_NEXT_ALLOC_GOAL(inode)++;
UDF_I_NEXT_ALLOC_GOAL(inode) ++;
} }
err = 0; err = 0;
...@@ -332,29 +334,27 @@ static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head ...@@ -332,29 +334,27 @@ static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head
if (new) if (new)
set_buffer_new(bh_result); set_buffer_new(bh_result);
map_bh(bh_result, inode->i_sb, phys); map_bh(bh_result, inode->i_sb, phys);
abort: abort:
unlock_kernel(); unlock_kernel();
return err; return err;
abort_negative: abort_negative:
udf_warning(inode->i_sb, "udf_get_block", "block < 0"); udf_warning(inode->i_sb, "udf_get_block", "block < 0");
goto abort; goto abort;
} }
static struct buffer_head * static struct buffer_head *udf_getblk(struct inode *inode, long block,
udf_getblk(struct inode *inode, long block, int create, int *err) int create, int *err)
{ {
struct buffer_head dummy; struct buffer_head dummy;
dummy.b_state = 0; dummy.b_state = 0;
dummy.b_blocknr = -1000; dummy.b_blocknr = -1000;
*err = udf_get_block(inode, block, &dummy, create); *err = udf_get_block(inode, block, &dummy, create);
if (!*err && buffer_mapped(&dummy)) if (!*err && buffer_mapped(&dummy)) {
{
struct buffer_head *bh; struct buffer_head *bh;
bh = sb_getblk(inode->i_sb, dummy.b_blocknr); bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
if (buffer_new(&dummy)) if (buffer_new(&dummy)) {
{
lock_buffer(bh); lock_buffer(bh);
memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
...@@ -368,12 +368,12 @@ udf_getblk(struct inode *inode, long block, int create, int *err) ...@@ -368,12 +368,12 @@ udf_getblk(struct inode *inode, long block, int create, int *err)
/* Extend the file by 'blocks' blocks, return the number of extents added */ /* Extend the file by 'blocks' blocks, return the number of extents added */
int udf_extend_file(struct inode *inode, struct extent_position *last_pos, int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
kernel_long_ad *last_ext, sector_t blocks) kernel_long_ad * last_ext, sector_t blocks)
{ {
sector_t add; sector_t add;
int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
kernel_lb_addr prealloc_loc = {0, 0}; kernel_lb_addr prealloc_loc = { 0, 0 };
int prealloc_len = 0; int prealloc_len = 0;
/* The previous extent is fake and we should not extend by anything /* The previous extent is fake and we should not extend by anything
...@@ -383,28 +383,32 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, ...@@ -383,28 +383,32 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
/* Round the last extent up to a multiple of block size */ /* Round the last extent up to a multiple of block size */
if (last_ext->extLength & (sb->s_blocksize - 1)) { if (last_ext->extLength & (sb->s_blocksize - 1)) {
last_ext->extLength = last_ext->extLength =
(last_ext->extLength & UDF_EXTENT_FLAG_MASK) | (last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
(((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) + (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
sb->s_blocksize - 1) & ~(sb->s_blocksize - 1)); sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
UDF_I_LENEXTENTS(inode) = UDF_I_LENEXTENTS(inode) =
(UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) & (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) &
~(sb->s_blocksize - 1); ~(sb->s_blocksize - 1);
} }
/* Last extent are just preallocated blocks? */ /* Last extent are just preallocated blocks? */
if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) { if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
EXT_NOT_RECORDED_ALLOCATED) {
/* Save the extent so that we can reattach it to the end */ /* Save the extent so that we can reattach it to the end */
prealloc_loc = last_ext->extLocation; prealloc_loc = last_ext->extLocation;
prealloc_len = last_ext->extLength; prealloc_len = last_ext->extLength;
/* Mark the extent as a hole */ /* Mark the extent as a hole */
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
last_ext->extLocation.logicalBlockNum = 0; last_ext->extLocation.logicalBlockNum = 0;
last_ext->extLocation.partitionReferenceNum = 0; last_ext->extLocation.partitionReferenceNum = 0;
} }
/* Can we merge with the previous extent? */ /* Can we merge with the previous extent? */
if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) { if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
add = ((1<<30) - sb->s_blocksize - (last_ext->extLength & EXT_NOT_RECORDED_NOT_ALLOCATED) {
UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits; add =
((1 << 30) - sb->s_blocksize -
(last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >> sb->
s_blocksize_bits;
if (add > blocks) if (add > blocks)
add = blocks; add = blocks;
blocks -= add; blocks -= add;
...@@ -413,40 +417,42 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, ...@@ -413,40 +417,42 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
if (fake) { if (fake) {
udf_add_aext(inode, last_pos, last_ext->extLocation, udf_add_aext(inode, last_pos, last_ext->extLocation,
last_ext->extLength, 1); last_ext->extLength, 1);
count++; count++;
} } else
else udf_write_aext(inode, last_pos, last_ext->extLocation,
udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1); last_ext->extLength, 1);
/* Managed to do everything necessary? */ /* Managed to do everything necessary? */
if (!blocks) if (!blocks)
goto out; goto out;
/* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
last_ext->extLocation.logicalBlockNum = 0; last_ext->extLocation.logicalBlockNum = 0;
last_ext->extLocation.partitionReferenceNum = 0; last_ext->extLocation.partitionReferenceNum = 0;
add = (1 << (30-sb->s_blocksize_bits)) - 1; add = (1 << (30 - sb->s_blocksize_bits)) - 1;
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits); last_ext->extLength =
EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits);
/* Create enough extents to cover the whole hole */ /* Create enough extents to cover the whole hole */
while (blocks > add) { while (blocks > add) {
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) last_ext->extLength, 1) == -1)
return -1; return -1;
count++; count++;
} }
if (blocks) { if (blocks) {
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
(blocks << sb->s_blocksize_bits); (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) last_ext->extLength, 1) == -1)
return -1; return -1;
count++; count++;
} }
out: out:
/* Do we have some preallocated blocks saved? */ /* Do we have some preallocated blocks saved? */
if (prealloc_len) { if (prealloc_len) {
if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1) if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1)
== -1)
return -1; return -1;
last_ext->extLocation = prealloc_loc; last_ext->extLocation = prealloc_loc;
last_ext->extLength = prealloc_len; last_ext->extLength = prealloc_len;
...@@ -462,8 +468,8 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos, ...@@ -462,8 +468,8 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
return count; return count;
} }
static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
int *err, long *phys, int *new) int *err, long *phys, int *new)
{ {
static sector_t last_block; static sector_t last_block;
struct buffer_head *result = NULL; struct buffer_head *result = NULL;
...@@ -484,21 +490,18 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -484,21 +490,18 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
prev_epos.block = UDF_I_LOCATION(inode); prev_epos.block = UDF_I_LOCATION(inode);
prev_epos.bh = NULL; prev_epos.bh = NULL;
cur_epos = next_epos = prev_epos; cur_epos = next_epos = prev_epos;
b_off = (loff_t)block << inode->i_sb->s_blocksize_bits; b_off = (loff_t) block << inode->i_sb->s_blocksize_bits;
/* find the extent which contains the block we are looking for. /* find the extent which contains the block we are looking for.
alternate between laarr[0] and laarr[1] for locations of the alternate between laarr[0] and laarr[1] for locations of the
current extent, and the previous extent */ current extent, and the previous extent */
do do {
{ if (prev_epos.bh != cur_epos.bh) {
if (prev_epos.bh != cur_epos.bh)
{
brelse(prev_epos.bh); brelse(prev_epos.bh);
get_bh(cur_epos.bh); get_bh(cur_epos.bh);
prev_epos.bh = cur_epos.bh; prev_epos.bh = cur_epos.bh;
} }
if (cur_epos.bh != next_epos.bh) if (cur_epos.bh != next_epos.bh) {
{
brelse(cur_epos.bh); brelse(cur_epos.bh);
get_bh(next_epos.bh); get_bh(next_epos.bh);
cur_epos.bh = next_epos.bh; cur_epos.bh = next_epos.bh;
...@@ -512,7 +515,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -512,7 +515,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
prev_epos.offset = cur_epos.offset; prev_epos.offset = cur_epos.offset;
cur_epos.offset = next_epos.offset; cur_epos.offset = next_epos.offset;
if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1) if ((etype =
udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
break; break;
c = !c; c = !c;
...@@ -522,10 +526,10 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -522,10 +526,10 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
pgoal = eloc.logicalBlockNum + pgoal = eloc.logicalBlockNum +
((elen + inode->i_sb->s_blocksize - 1) >> ((elen + inode->i_sb->s_blocksize - 1) >>
inode->i_sb->s_blocksize_bits); inode->i_sb->s_blocksize_bits);
count ++; count++;
} while (lbcount + elen <= b_off); } while (lbcount + elen <= b_off);
b_off -= lbcount; b_off -= lbcount;
...@@ -538,15 +542,13 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -538,15 +542,13 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0);
/* if the extent is allocated and recorded, return the block /* if the extent is allocated and recorded, return the block
if the extent is not a multiple of the blocksize, round up */ if the extent is not a multiple of the blocksize, round up */
if (etype == (EXT_RECORDED_ALLOCATED >> 30)) if (etype == (EXT_RECORDED_ALLOCATED >> 30)) {
{ if (elen & (inode->i_sb->s_blocksize - 1)) {
if (elen & (inode->i_sb->s_blocksize - 1))
{
elen = EXT_RECORDED_ALLOCATED | elen = EXT_RECORDED_ALLOCATED |
((elen + inode->i_sb->s_blocksize - 1) & ((elen + inode->i_sb->s_blocksize - 1) &
~(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(prev_epos.bh);
...@@ -559,18 +561,17 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -559,18 +561,17 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
last_block = block; last_block = block;
/* Are we beyond EOF? */ /* Are we beyond EOF? */
if (etype == -1) if (etype == -1) {
{
int ret; int ret;
if (count) { if (count) {
if (c) if (c)
laarr[0] = laarr[1]; laarr[0] = laarr[1];
startnum = 1; startnum = 1;
} } else {
else {
/* Create a fake extent when there's not one */ /* Create a fake extent when there's not one */
memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr)); memset(&laarr[0].extLocation, 0x00,
sizeof(kernel_lb_addr));
laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
/* Will udf_extend_file() create real extent from a fake one? */ /* Will udf_extend_file() create real extent from a fake one? */
startnum = (offset > 0); startnum = (offset > 0);
...@@ -590,26 +591,26 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -590,26 +591,26 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
offset = 0; offset = 0;
count += ret; count += ret;
/* We are not covered by a preallocated extent? */ /* We are not covered by a preallocated extent? */
if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) { if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
EXT_NOT_RECORDED_ALLOCATED) {
/* Is there any real extent? - otherwise we overwrite /* Is there any real extent? - otherwise we overwrite
* the fake one... */ * the fake one... */
if (count) if (count)
c = !c; c = !c;
laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
inode->i_sb->s_blocksize; inode->i_sb->s_blocksize;
memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr)); memset(&laarr[c].extLocation, 0x00,
count ++; sizeof(kernel_lb_addr));
endnum ++; count++;
endnum++;
} }
endnum = c+1; endnum = c + 1;
lastblock = 1; lastblock = 1;
} } else {
else {
endnum = startnum = ((count > 2) ? 2 : count); endnum = startnum = ((count > 2) ? 2 : count);
/* if the current extent is in position 0, swap it with the previous */ /* if the current extent is in position 0, swap it with the previous */
if (!c && count != 1) if (!c && count != 1) {
{
laarr[2] = laarr[0]; laarr[2] = laarr[0];
laarr[0] = laarr[1]; laarr[0] = laarr[1];
laarr[1] = laarr[2]; laarr[1] = laarr[2];
...@@ -617,37 +618,37 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -617,37 +618,37 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
} }
/* if the current block is located in an extent, read the next extent */ /* if the current block is located in an extent, read the next extent */
if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) if ((etype =
{ udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) {
laarr[c+1].extLength = (etype << 30) | elen; laarr[c + 1].extLength = (etype << 30) | elen;
laarr[c+1].extLocation = eloc; laarr[c + 1].extLocation = eloc;
count ++; count++;
startnum ++; startnum++;
endnum ++; endnum++;
} } else {
else {
lastblock = 1; lastblock = 1;
} }
} }
/* if the current extent is not recorded but allocated, get the /* if the current extent is not recorded but allocated, get the
block in the extent corresponding to the requested block */ block in the extent corresponding to the requested block */
if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
newblocknum = laarr[c].extLocation.logicalBlockNum + offset; newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
else /* otherwise, allocate a new block */ else { /* otherwise, allocate a new block */
{
if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block) if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
goal = UDF_I_NEXT_ALLOC_GOAL(inode); goal = UDF_I_NEXT_ALLOC_GOAL(inode);
if (!goal) if (!goal) {
{
if (!(goal = pgoal)) if (!(goal = pgoal))
goal = UDF_I_LOCATION(inode).logicalBlockNum + 1; goal =
UDF_I_LOCATION(inode).logicalBlockNum + 1;
} }
if (!(newblocknum = udf_new_block(inode->i_sb, inode, if (!(newblocknum = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) UDF_I_LOCATION(inode).
{ partitionReferenceNum, goal,
err))) {
brelse(prev_epos.bh); brelse(prev_epos.bh);
*err = -ENOSPC; *err = -ENOSPC;
return NULL; return NULL;
...@@ -656,8 +657,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -656,8 +657,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
} }
/* if the extent the requsted block is located in contains multiple blocks, /* if the extent the requsted block is located in contains multiple blocks,
split the extent into at most three extents. blocks prior to requested split the extent into at most three extents. blocks prior to requested
block, requested block, and blocks after requested block */ block, requested block, and blocks after requested block */
udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum); udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
#ifdef UDF_PREALLOCATE #ifdef UDF_PREALLOCATE
...@@ -669,15 +670,15 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -669,15 +670,15 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
udf_merge_extents(inode, laarr, &endnum); udf_merge_extents(inode, laarr, &endnum);
/* write back the new extents, inserting new extents if the new number /* write back the new extents, inserting new extents if the new number
of extents is greater than the old number, and deleting extents if of extents is greater than the old number, and deleting extents if
the new number of extents is less than the old number */ the new number of extents is less than the old number */
udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
brelse(prev_epos.bh); brelse(prev_epos.bh);
if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
UDF_I_LOCATION(inode).partitionReferenceNum, 0))) UDF_I_LOCATION(inode).
{ partitionReferenceNum, 0))) {
return NULL; return NULL;
} }
*phys = newblock; *phys = newblock;
...@@ -694,283 +695,329 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -694,283 +695,329 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
return result; return result;
} }
static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum, static void udf_split_extents(struct inode *inode, int *c, int offset,
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) int newblocknum,
kernel_long_ad laarr[EXTENT_MERGE_SIZE],
int *endnum)
{ {
if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) || if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
(laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) (laarr[*c].extLength >> 30) ==
{ (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
int curr = *c; int curr = *c;
int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) + int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; inode->i_sb->s_blocksize -
1) >> inode->i_sb->s_blocksize_bits;
int8_t etype = (laarr[curr].extLength >> 30); int8_t etype = (laarr[curr].extLength >> 30);
if (blen == 1) if (blen == 1) ;
; else if (!offset || blen == offset + 1) {
else if (!offset || blen == offset + 1) laarr[curr + 2] = laarr[curr + 1];
{ laarr[curr + 1] = laarr[curr];
laarr[curr+2] = laarr[curr+1]; } else {
laarr[curr+1] = laarr[curr]; laarr[curr + 3] = laarr[curr + 1];
} laarr[curr + 2] = laarr[curr + 1] = laarr[curr];
else }
{
laarr[curr+3] = laarr[curr+1]; if (offset) {
laarr[curr+2] = laarr[curr+1] = laarr[curr]; if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
} udf_free_blocks(inode->i_sb, inode,
laarr[curr].extLocation, 0,
if (offset) offset);
{ laarr[curr].extLength =
if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) EXT_NOT_RECORDED_NOT_ALLOCATED | (offset <<
{ inode->
udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset); i_sb->
laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | s_blocksize_bits);
(offset << inode->i_sb->s_blocksize_bits);
laarr[curr].extLocation.logicalBlockNum = 0; laarr[curr].extLocation.logicalBlockNum = 0;
laarr[curr].extLocation.partitionReferenceNum = 0; laarr[curr].extLocation.partitionReferenceNum =
} 0;
else } else
laarr[curr].extLength = (etype << 30) | laarr[curr].extLength = (etype << 30) |
(offset << inode->i_sb->s_blocksize_bits); (offset << inode->i_sb->s_blocksize_bits);
curr ++; curr++;
(*c) ++; (*c)++;
(*endnum) ++; (*endnum)++;
} }
laarr[curr].extLocation.logicalBlockNum = newblocknum; laarr[curr].extLocation.logicalBlockNum = newblocknum;
if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
laarr[curr].extLocation.partitionReferenceNum = laarr[curr].extLocation.partitionReferenceNum =
UDF_I_LOCATION(inode).partitionReferenceNum; UDF_I_LOCATION(inode).partitionReferenceNum;
laarr[curr].extLength = EXT_RECORDED_ALLOCATED | laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
inode->i_sb->s_blocksize; inode->i_sb->s_blocksize;
curr ++; curr++;
if (blen != offset + 1) if (blen != offset + 1) {
{
if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
laarr[curr].extLocation.logicalBlockNum += (offset + 1); laarr[curr].extLocation.logicalBlockNum +=
laarr[curr].extLength = (etype << 30) | (offset + 1);
((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits); laarr[curr].extLength =
curr ++; (etype << 30) | ((blen - (offset + 1)) << inode->
(*endnum) ++; i_sb->s_blocksize_bits);
curr++;
(*endnum)++;
} }
} }
} }
static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) kernel_long_ad laarr[EXTENT_MERGE_SIZE],
int *endnum)
{ {
int start, length = 0, currlength = 0, i; int start, length = 0, currlength = 0, i;
if (*endnum >= (c+1)) if (*endnum >= (c + 1)) {
{
if (!lastblock) if (!lastblock)
return; return;
else else
start = c; start = c;
} } else {
else if ((laarr[c + 1].extLength >> 30) ==
{ (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
if ((laarr[c+1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) start = c + 1;
{ length = currlength =
start = c+1; (((laarr[c + 1].
length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) + extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); inode->i_sb->s_blocksize -
} 1) >> inode->i_sb->s_blocksize_bits);
else } else
start = c; start = c;
} }
for (i=start+1; i<=*endnum; i++) for (i = start + 1; i <= *endnum; i++) {
{ if (i == *endnum) {
if (i == *endnum)
{
if (lastblock) if (lastblock)
length += UDF_DEFAULT_PREALLOC_BLOCKS; length += UDF_DEFAULT_PREALLOC_BLOCKS;
} } else if ((laarr[i].extLength >> 30) ==
else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + length +=
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize -
1) >> inode->i_sb->s_blocksize_bits);
else else
break; break;
} }
if (length) if (length) {
{
int next = laarr[start].extLocation.logicalBlockNum + int next = laarr[start].extLocation.logicalBlockNum +
(((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) + (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); inode->i_sb->s_blocksize -
1) >> inode->i_sb->s_blocksize_bits);
int numalloc = udf_prealloc_blocks(inode->i_sb, inode, int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
laarr[start].extLocation.partitionReferenceNum, laarr[start].extLocation.
next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length : partitionReferenceNum,
UDF_DEFAULT_PREALLOC_BLOCKS) - currlength); next,
(UDF_DEFAULT_PREALLOC_BLOCKS
if (numalloc) >
{ length ? length :
if (start == (c+1)) UDF_DEFAULT_PREALLOC_BLOCKS)
- currlength);
if (numalloc) {
if (start == (c + 1))
laarr[start].extLength += laarr[start].extLength +=
(numalloc << inode->i_sb->s_blocksize_bits); (numalloc << inode->i_sb->s_blocksize_bits);
else else {
{ memmove(&laarr[c + 2], &laarr[c + 1],
memmove(&laarr[c+2], &laarr[c+1], sizeof(long_ad) * (*endnum - (c + 1)));
sizeof(long_ad) * (*endnum - (c+1))); (*endnum)++;
(*endnum) ++; laarr[c + 1].extLocation.logicalBlockNum = next;
laarr[c+1].extLocation.logicalBlockNum = next; laarr[c + 1].extLocation.partitionReferenceNum =
laarr[c+1].extLocation.partitionReferenceNum = laarr[c].extLocation.partitionReferenceNum;
laarr[c].extLocation.partitionReferenceNum; laarr[c + 1].extLength =
laarr[c+1].extLength = EXT_NOT_RECORDED_ALLOCATED | EXT_NOT_RECORDED_ALLOCATED | (numalloc <<
(numalloc << inode->i_sb->s_blocksize_bits); inode->i_sb->
start = c+1; s_blocksize_bits);
start = c + 1;
} }
for (i=start+1; numalloc && i<*endnum; i++) for (i = start + 1; numalloc && i < *endnum; i++) {
{ int elen =
int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + ((laarr[i].
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize -
1) >> inode->i_sb->s_blocksize_bits;
if (elen > numalloc) if (elen > numalloc) {
{
laarr[i].extLength -= laarr[i].extLength -=
(numalloc << inode->i_sb->s_blocksize_bits); (numalloc << inode->i_sb->
s_blocksize_bits);
numalloc = 0; numalloc = 0;
} } else {
else
{
numalloc -= elen; numalloc -= elen;
if (*endnum > (i+1)) if (*endnum > (i + 1))
memmove(&laarr[i], &laarr[i+1], memmove(&laarr[i],
sizeof(long_ad) * (*endnum - (i+1))); &laarr[i + 1],
i --; sizeof(long_ad) *
(*endnum) --; (*endnum - (i + 1)));
i--;
(*endnum)--;
} }
} }
UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits; UDF_I_LENEXTENTS(inode) +=
numalloc << inode->i_sb->s_blocksize_bits;
} }
} }
} }
static void udf_merge_extents(struct inode *inode, static void udf_merge_extents(struct inode *inode,
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum) kernel_long_ad laarr[EXTENT_MERGE_SIZE],
int *endnum)
{ {
int i; int i;
for (i=0; i<(*endnum-1); i++) for (i = 0; i < (*endnum - 1); i++) {
{ if ((laarr[i].extLength >> 30) ==
if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30)) (laarr[i + 1].extLength >> 30)) {
{ if (((laarr[i].extLength >> 30) ==
if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) || (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) == ||
(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + ((laarr[i + 1].extLocation.logicalBlockNum -
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits))) laarr[i].extLocation.logicalBlockNum) ==
{ (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + inode->i_sb->s_blocksize -
(laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) + 1) >> inode->i_sb->s_blocksize_bits))) {
inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) if (((laarr[i].
{ extLength & UDF_EXTENT_LENGTH_MASK) +
laarr[i+1].extLength = (laarr[i+1].extLength - (laarr[i + 1].
(laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + extLength & UDF_EXTENT_LENGTH_MASK) +
UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1); inode->i_sb->s_blocksize -
laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) + 1) & ~UDF_EXTENT_LENGTH_MASK) {
(UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize; laarr[i + 1].extLength =
laarr[i+1].extLocation.logicalBlockNum = (laarr[i + 1].extLength -
laarr[i].extLocation.logicalBlockNum + (laarr[i].
((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >> extLength &
inode->i_sb->s_blocksize_bits); UDF_EXTENT_LENGTH_MASK) +
} UDF_EXTENT_LENGTH_MASK) & ~(inode->
else i_sb->
{ s_blocksize
laarr[i].extLength = laarr[i+1].extLength + - 1);
(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + laarr[i].extLength =
inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1)); (laarr[i].
if (*endnum > (i+2)) extLength & UDF_EXTENT_FLAG_MASK) +
memmove(&laarr[i+1], &laarr[i+2], (UDF_EXTENT_LENGTH_MASK + 1) -
sizeof(long_ad) * (*endnum - (i+2))); inode->i_sb->s_blocksize;
i --; laarr[i +
(*endnum) --; 1].extLocation.logicalBlockNum =
laarr[i].extLocation.
logicalBlockNum +
((laarr[i].
extLength &
UDF_EXTENT_LENGTH_MASK) >> inode->
i_sb->s_blocksize_bits);
} else {
laarr[i].extLength =
laarr[i + 1].extLength +
(((laarr[i].
extLength &
UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize -
1) & ~(inode->i_sb->s_blocksize -
1));
if (*endnum > (i + 2))
memmove(&laarr[i + 1],
&laarr[i + 2],
sizeof(long_ad) *
(*endnum - (i + 2)));
i--;
(*endnum)--;
} }
} }
} } else
else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) && if (((laarr[i].extLength >> 30) ==
((laarr[i+1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) (EXT_NOT_RECORDED_ALLOCATED >> 30))
{ && ((laarr[i + 1].extLength >> 30) ==
udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0, (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + udf_free_blocks(inode->i_sb, inode,
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); laarr[i].extLocation, 0,
((laarr[i].
extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize -
1) >> inode->i_sb->s_blocksize_bits);
laarr[i].extLocation.logicalBlockNum = 0; laarr[i].extLocation.logicalBlockNum = 0;
laarr[i].extLocation.partitionReferenceNum = 0; laarr[i].extLocation.partitionReferenceNum = 0;
if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
(laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) + (laarr[i + 1].extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) inode->i_sb->s_blocksize -
{ 1) & ~UDF_EXTENT_LENGTH_MASK) {
laarr[i+1].extLength = (laarr[i+1].extLength - laarr[i + 1].extLength =
(laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + (laarr[i + 1].extLength -
UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1); (laarr[i].
laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) + extLength & UDF_EXTENT_LENGTH_MASK) +
(UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize; UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->
s_blocksize -
1);
laarr[i].extLength =
(laarr[i].
extLength & UDF_EXTENT_FLAG_MASK) +
(UDF_EXTENT_LENGTH_MASK + 1) -
inode->i_sb->s_blocksize;
} else {
laarr[i].extLength = laarr[i + 1].extLength +
(((laarr[i].
extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize -
1) & ~(inode->i_sb->s_blocksize - 1));
if (*endnum > (i + 2))
memmove(&laarr[i + 1], &laarr[i + 2],
sizeof(long_ad) * (*endnum -
(i + 2)));
i--;
(*endnum)--;
} }
else } else if ((laarr[i].extLength >> 30) ==
{ (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
laarr[i].extLength = laarr[i+1].extLength + udf_free_blocks(inode->i_sb, inode,
(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + laarr[i].extLocation, 0,
inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1)); ((laarr[i].
if (*endnum > (i+2)) extLength & UDF_EXTENT_LENGTH_MASK) +
memmove(&laarr[i+1], &laarr[i+2], inode->i_sb->s_blocksize -
sizeof(long_ad) * (*endnum - (i+2))); 1) >> inode->i_sb->s_blocksize_bits);
i --;
(*endnum) --;
}
}
else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
{
udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
laarr[i].extLocation.logicalBlockNum = 0; laarr[i].extLocation.logicalBlockNum = 0;
laarr[i].extLocation.partitionReferenceNum = 0; laarr[i].extLocation.partitionReferenceNum = 0;
laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) | laarr[i].extLength =
EXT_NOT_RECORDED_NOT_ALLOCATED; (laarr[i].
extLength & UDF_EXTENT_LENGTH_MASK) |
EXT_NOT_RECORDED_NOT_ALLOCATED;
} }
} }
} }
static void udf_update_extents(struct inode *inode, static void udf_update_extents(struct inode *inode,
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, kernel_long_ad laarr[EXTENT_MERGE_SIZE],
struct extent_position *epos) int startnum, int endnum,
struct extent_position *epos)
{ {
int start = 0, i; int start = 0, i;
kernel_lb_addr tmploc; kernel_lb_addr tmploc;
uint32_t tmplen; uint32_t tmplen;
if (startnum > endnum) if (startnum > endnum) {
{ for (i = 0; i < (startnum - endnum); i++)
for (i=0; i<(startnum-endnum); i++)
udf_delete_aext(inode, *epos, laarr[i].extLocation, udf_delete_aext(inode, *epos, laarr[i].extLocation,
laarr[i].extLength); laarr[i].extLength);
} } else if (startnum < endnum) {
else if (startnum < endnum) for (i = 0; i < (endnum - startnum); i++) {
{
for (i=0; i<(endnum-startnum); i++)
{
udf_insert_aext(inode, *epos, laarr[i].extLocation, udf_insert_aext(inode, *epos, laarr[i].extLocation,
laarr[i].extLength); laarr[i].extLength);
udf_next_aext(inode, epos, &laarr[i].extLocation, udf_next_aext(inode, epos, &laarr[i].extLocation,
&laarr[i].extLength, 1); &laarr[i].extLength, 1);
start ++; start++;
} }
} }
for (i=start; i<endnum; i++) for (i = start; i < endnum; i++) {
{
udf_next_aext(inode, epos, &tmploc, &tmplen, 0); 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); laarr[i].extLength, 1);
} }
} }
struct buffer_head * udf_bread(struct inode * inode, int block, struct buffer_head *udf_bread(struct inode *inode, int block,
int create, int * err) int create, int *err)
{ {
struct buffer_head * bh = NULL; struct buffer_head *bh = NULL;
bh = udf_getblk(inode, block, create, err); bh = udf_getblk(inode, block, create, err);
if (!bh) if (!bh)
...@@ -987,56 +1034,51 @@ struct buffer_head * udf_bread(struct inode * inode, int block, ...@@ -987,56 +1034,51 @@ struct buffer_head * udf_bread(struct inode * inode, int block,
return NULL; return NULL;
} }
void udf_truncate(struct inode * inode) void udf_truncate(struct inode *inode)
{ {
int offset; int offset;
int err; int err;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode))) S_ISLNK(inode->i_mode)))
return; return;
if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return; return;
lock_kernel(); lock_kernel();
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
{ if (inode->i_sb->s_blocksize <
if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + (udf_file_entry_alloc_offset(inode) + inode->i_size)) {
inode->i_size))
{
udf_expand_file_adinicb(inode, inode->i_size, &err); udf_expand_file_adinicb(inode, inode->i_size, &err);
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
{
inode->i_size = UDF_I_LENALLOC(inode); inode->i_size = UDF_I_LENALLOC(inode);
unlock_kernel(); unlock_kernel();
return; return;
} } else
else
udf_truncate_extents(inode); udf_truncate_extents(inode);
} } else {
else
{
offset = inode->i_size & (inode->i_sb->s_blocksize - 1); offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 0x00, inode->i_sb->s_blocksize - offset - udf_file_entry_alloc_offset(inode)); memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) +
offset, 0x00,
inode->i_sb->s_blocksize - offset -
udf_file_entry_alloc_offset(inode));
UDF_I_LENALLOC(inode) = inode->i_size; UDF_I_LENALLOC(inode) = inode->i_size;
} }
} } else {
else block_truncate_page(inode->i_mapping, inode->i_size,
{ udf_get_block);
block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
udf_truncate_extents(inode); udf_truncate_extents(inode);
} }
inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
if (IS_SYNC(inode)) if (IS_SYNC(inode))
udf_sync_inode (inode); udf_sync_inode(inode);
else else
mark_inode_dirty(inode); mark_inode_dirty(inode);
unlock_kernel(); unlock_kernel();
} }
static void static void __udf_read_inode(struct inode *inode)
__udf_read_inode(struct inode *inode)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
struct fileEntry *fe; struct fileEntry *fe;
...@@ -1056,19 +1098,18 @@ __udf_read_inode(struct inode *inode) ...@@ -1056,19 +1098,18 @@ __udf_read_inode(struct inode *inode)
*/ */
bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident); bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
if (!bh) if (!bh) {
{
printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n", printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
inode->i_ino); inode->i_ino);
make_bad_inode(inode); make_bad_inode(inode);
return; return;
} }
if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE && if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
ident != TAG_IDENT_USE) ident != TAG_IDENT_USE) {
{ printk(KERN_ERR
printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n", "udf: udf_read_inode(ino %ld) failed ident=%d\n",
inode->i_ino, ident); inode->i_ino, ident);
brelse(bh); brelse(bh);
make_bad_inode(inode); make_bad_inode(inode);
return; return;
...@@ -1076,51 +1117,46 @@ __udf_read_inode(struct inode *inode) ...@@ -1076,51 +1117,46 @@ __udf_read_inode(struct inode *inode)
fe = (struct fileEntry *)bh->b_data; fe = (struct fileEntry *)bh->b_data;
if (le16_to_cpu(fe->icbTag.strategyType) == 4096) if (le16_to_cpu(fe->icbTag.strategyType) == 4096) {
{
struct buffer_head *ibh = NULL, *nbh = NULL; struct buffer_head *ibh = NULL, *nbh = NULL;
struct indirectEntry *ie; struct indirectEntry *ie;
ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident); ibh =
if (ident == TAG_IDENT_IE) udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1,
{ &ident);
if (ibh) if (ident == TAG_IDENT_IE) {
{ if (ibh) {
kernel_lb_addr loc; kernel_lb_addr loc;
ie = (struct indirectEntry *)ibh->b_data; ie = (struct indirectEntry *)ibh->b_data;
loc = lelb_to_cpu(ie->indirectICB.extLocation); loc = lelb_to_cpu(ie->indirectICB.extLocation);
if (ie->indirectICB.extLength && if (ie->indirectICB.extLength &&
(nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident))) (nbh =
{ udf_read_ptagged(inode->i_sb, loc, 0,
if (ident == TAG_IDENT_FE || &ident))) {
ident == TAG_IDENT_EFE) if (ident == TAG_IDENT_FE
{ || ident == TAG_IDENT_EFE) {
memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr)); memcpy(&UDF_I_LOCATION(inode),
&loc,
sizeof(kernel_lb_addr));
brelse(bh); brelse(bh);
brelse(ibh); brelse(ibh);
brelse(nbh); brelse(nbh);
__udf_read_inode(inode); __udf_read_inode(inode);
return; return;
} } else {
else
{
brelse(nbh); brelse(nbh);
brelse(ibh); brelse(ibh);
} }
} } else
else
brelse(ibh); brelse(ibh);
} }
} } else
else
brelse(ibh); brelse(ibh);
} } else if (le16_to_cpu(fe->icbTag.strategyType) != 4) {
else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
{
printk(KERN_ERR "udf: unsupported strategy type: %d\n", printk(KERN_ERR "udf: unsupported strategy type: %d\n",
le16_to_cpu(fe->icbTag.strategyType)); le16_to_cpu(fe->icbTag.strategyType));
brelse(bh); brelse(bh);
make_bad_inode(inode); make_bad_inode(inode);
return; return;
...@@ -1143,62 +1179,70 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) ...@@ -1143,62 +1179,70 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
if (le16_to_cpu(fe->icbTag.strategyType) == 4) if (le16_to_cpu(fe->icbTag.strategyType) == 4)
UDF_I_STRAT4096(inode) = 0; UDF_I_STRAT4096(inode) = 0;
else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */ else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
UDF_I_STRAT4096(inode) = 1; UDF_I_STRAT4096(inode) = 1;
UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK; UDF_I_ALLOCTYPE(inode) =
le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
UDF_I_UNIQUE(inode) = 0; UDF_I_UNIQUE(inode) = 0;
UDF_I_LENEATTR(inode) = 0; UDF_I_LENEATTR(inode) = 0;
UDF_I_LENEXTENTS(inode) = 0; UDF_I_LENEXTENTS(inode) = 0;
UDF_I_LENALLOC(inode) = 0; UDF_I_LENALLOC(inode) = 0;
UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
UDF_I_NEXT_ALLOC_GOAL(inode) = 0; UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE) if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE) {
{
UDF_I_EFE(inode) = 1; UDF_I_EFE(inode) = 1;
UDF_I_USE(inode) = 0; UDF_I_USE(inode) = 0;
if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry))) if (udf_alloc_i_data
{ (inode,
inode->i_sb->s_blocksize -
sizeof(struct extendedFileEntry))) {
make_bad_inode(inode); make_bad_inode(inode);
return; return;
} }
memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); memcpy(UDF_I_DATA(inode),
} bh->b_data + sizeof(struct extendedFileEntry),
else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE) inode->i_sb->s_blocksize -
{ sizeof(struct extendedFileEntry));
} else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE) {
UDF_I_EFE(inode) = 0; UDF_I_EFE(inode) = 0;
UDF_I_USE(inode) = 0; UDF_I_USE(inode) = 0;
if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct fileEntry))) if (udf_alloc_i_data
{ (inode,
inode->i_sb->s_blocksize - sizeof(struct fileEntry))) {
make_bad_inode(inode); make_bad_inode(inode);
return; return;
} }
memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry)); memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry),
} inode->i_sb->s_blocksize - sizeof(struct fileEntry));
else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) } else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) {
{
UDF_I_EFE(inode) = 0; UDF_I_EFE(inode) = 0;
UDF_I_USE(inode) = 1; UDF_I_USE(inode) = 1;
UDF_I_LENALLOC(inode) = UDF_I_LENALLOC(inode) =
le32_to_cpu( le32_to_cpu(((struct unallocSpaceEntry *)bh->b_data)->
((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs); lengthAllocDescs);
if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry))) if (udf_alloc_i_data
{ (inode,
inode->i_sb->s_blocksize -
sizeof(struct unallocSpaceEntry))) {
make_bad_inode(inode); make_bad_inode(inode);
return; return;
} }
memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)); memcpy(UDF_I_DATA(inode),
bh->b_data + sizeof(struct unallocSpaceEntry),
inode->i_sb->s_blocksize -
sizeof(struct unallocSpaceEntry));
return; return;
} }
inode->i_uid = le32_to_cpu(fe->uid); inode->i_uid = le32_to_cpu(fe->uid);
if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb, if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb,
UDF_FLAG_UID_IGNORE)) UDF_FLAG_UID_IGNORE))
inode->i_uid = UDF_SB(inode->i_sb)->s_uid; inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
inode->i_gid = le32_to_cpu(fe->gid); inode->i_gid = le32_to_cpu(fe->gid);
if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb, if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb,
UDF_FLAG_GID_IGNORE)) UDF_FLAG_GID_IGNORE))
inode->i_gid = UDF_SB(inode->i_sb)->s_gid; inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
inode->i_nlink = le16_to_cpu(fe->fileLinkCount); inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
...@@ -1211,41 +1255,31 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) ...@@ -1211,41 +1255,31 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_mode = udf_convert_permissions(fe); inode->i_mode = udf_convert_permissions(fe);
inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask; inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
if (UDF_I_EFE(inode) == 0) if (UDF_I_EFE(inode) == 0) {
{
inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9); (inode->i_sb->s_blocksize_bits - 9);
if ( udf_stamp_to_time(&convtime, &convtime_usec, if (udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(fe->accessTime)) ) lets_to_cpu(fe->accessTime))) {
{
inode->i_atime.tv_sec = convtime; inode->i_atime.tv_sec = convtime;
inode->i_atime.tv_nsec = convtime_usec * 1000; inode->i_atime.tv_nsec = convtime_usec * 1000;
} } else {
else
{
inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb); inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
} }
if ( udf_stamp_to_time(&convtime, &convtime_usec, if (udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(fe->modificationTime)) ) lets_to_cpu(fe->modificationTime))) {
{
inode->i_mtime.tv_sec = convtime; inode->i_mtime.tv_sec = convtime;
inode->i_mtime.tv_nsec = convtime_usec * 1000; inode->i_mtime.tv_nsec = convtime_usec * 1000;
} } else {
else
{
inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb); inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
} }
if ( udf_stamp_to_time(&convtime, &convtime_usec, if (udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(fe->attrTime)) ) lets_to_cpu(fe->attrTime))) {
{
inode->i_ctime.tv_sec = convtime; inode->i_ctime.tv_sec = convtime;
inode->i_ctime.tv_nsec = convtime_usec * 1000; inode->i_ctime.tv_nsec = convtime_usec * 1000;
} } else {
else
{
inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb); inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
} }
...@@ -1253,65 +1287,51 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) ...@@ -1253,65 +1287,51 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr); UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs); UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode); offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
} } else {
else
{
inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9); (inode->i_sb->s_blocksize_bits - 9);
if ( udf_stamp_to_time(&convtime, &convtime_usec, if (udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->accessTime)) ) lets_to_cpu(efe->accessTime))) {
{
inode->i_atime.tv_sec = convtime; inode->i_atime.tv_sec = convtime;
inode->i_atime.tv_nsec = convtime_usec * 1000; inode->i_atime.tv_nsec = convtime_usec * 1000;
} } else {
else
{
inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb); inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
} }
if ( udf_stamp_to_time(&convtime, &convtime_usec, if (udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->modificationTime)) ) lets_to_cpu(efe->modificationTime))) {
{
inode->i_mtime.tv_sec = convtime; inode->i_mtime.tv_sec = convtime;
inode->i_mtime.tv_nsec = convtime_usec * 1000; inode->i_mtime.tv_nsec = convtime_usec * 1000;
} } else {
else
{
inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb); inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
} }
if ( udf_stamp_to_time(&convtime, &convtime_usec, if (udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->createTime)) ) lets_to_cpu(efe->createTime))) {
{
UDF_I_CRTIME(inode).tv_sec = convtime; UDF_I_CRTIME(inode).tv_sec = convtime;
UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000; UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;
} } else {
else
{
UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb); UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);
} }
if ( udf_stamp_to_time(&convtime, &convtime_usec, if (udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->attrTime)) ) lets_to_cpu(efe->attrTime))) {
{
inode->i_ctime.tv_sec = convtime; inode->i_ctime.tv_sec = convtime;
inode->i_ctime.tv_nsec = convtime_usec * 1000; inode->i_ctime.tv_nsec = convtime_usec * 1000;
} } else {
else
{
inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb); inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
} }
UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID); UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr); UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs); UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode); offset =
sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
} }
switch (fe->icbTag.fileType) switch (fe->icbTag.fileType) {
{ case ICBTAG_FILE_TYPE_DIRECTORY:
case ICBTAG_FILE_TYPE_DIRECTORY:
{ {
inode->i_op = &udf_dir_inode_operations; inode->i_op = &udf_dir_inode_operations;
inode->i_fop = &udf_dir_operations; inode->i_fop = &udf_dir_operations;
...@@ -1319,9 +1339,9 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) ...@@ -1319,9 +1339,9 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inc_nlink(inode); inc_nlink(inode);
break; break;
} }
case ICBTAG_FILE_TYPE_REALTIME: case ICBTAG_FILE_TYPE_REALTIME:
case ICBTAG_FILE_TYPE_REGULAR: case ICBTAG_FILE_TYPE_REGULAR:
case ICBTAG_FILE_TYPE_UNDEF: case ICBTAG_FILE_TYPE_UNDEF:
{ {
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
inode->i_data.a_ops = &udf_adinicb_aops; inode->i_data.a_ops = &udf_adinicb_aops;
...@@ -1332,56 +1352,54 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) ...@@ -1332,56 +1352,54 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_mode |= S_IFREG; inode->i_mode |= S_IFREG;
break; break;
} }
case ICBTAG_FILE_TYPE_BLOCK: case ICBTAG_FILE_TYPE_BLOCK:
{ {
inode->i_mode |= S_IFBLK; inode->i_mode |= S_IFBLK;
break; break;
} }
case ICBTAG_FILE_TYPE_CHAR: case ICBTAG_FILE_TYPE_CHAR:
{ {
inode->i_mode |= S_IFCHR; inode->i_mode |= S_IFCHR;
break; break;
} }
case ICBTAG_FILE_TYPE_FIFO: case ICBTAG_FILE_TYPE_FIFO:
{ {
init_special_inode(inode, inode->i_mode | S_IFIFO, 0); init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
break; break;
} }
case ICBTAG_FILE_TYPE_SOCKET: case ICBTAG_FILE_TYPE_SOCKET:
{ {
init_special_inode(inode, inode->i_mode | S_IFSOCK, 0); init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
break; break;
} }
case ICBTAG_FILE_TYPE_SYMLINK: case ICBTAG_FILE_TYPE_SYMLINK:
{ {
inode->i_data.a_ops = &udf_symlink_aops; inode->i_data.a_ops = &udf_symlink_aops;
inode->i_op = &page_symlink_inode_operations; inode->i_op = &page_symlink_inode_operations;
inode->i_mode = S_IFLNK|S_IRWXUGO; inode->i_mode = S_IFLNK | S_IRWXUGO;
break; break;
} }
default: default:
{ {
printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n", printk(KERN_ERR
inode->i_ino, fe->icbTag.fileType); "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
inode->i_ino, fe->icbTag.fileType);
make_bad_inode(inode); make_bad_inode(inode);
return; return;
} }
} }
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
{ struct deviceSpec *dsea = (struct deviceSpec *)
struct deviceSpec *dsea = udf_get_extendedattr(inode, 12, 1);
(struct deviceSpec *)
udf_get_extendedattr(inode, 12, 1);
if (dsea) if (dsea) {
{ init_special_inode(inode, inode->i_mode,
init_special_inode(inode, inode->i_mode, MKDEV( MKDEV(le32_to_cpu
le32_to_cpu(dsea->majorDeviceIdent), (dsea->majorDeviceIdent),
le32_to_cpu(dsea->minorDeviceIdent))); le32_to_cpu(dsea->
minorDeviceIdent)));
/* Developer ID ??? */ /* Developer ID ??? */
} } else {
else
{
make_bad_inode(inode); make_bad_inode(inode);
} }
} }
...@@ -1391,9 +1409,9 @@ static int udf_alloc_i_data(struct inode *inode, size_t size) ...@@ -1391,9 +1409,9 @@ static int udf_alloc_i_data(struct inode *inode, size_t size)
{ {
UDF_I_DATA(inode) = kmalloc(size, GFP_KERNEL); UDF_I_DATA(inode) = kmalloc(size, GFP_KERNEL);
if (!UDF_I_DATA(inode)) if (!UDF_I_DATA(inode)) {
{ printk(KERN_ERR
printk(KERN_ERR "udf:udf_alloc_i_data (ino %ld) no free memory\n", "udf:udf_alloc_i_data (ino %ld) no free memory\n",
inode->i_ino); inode->i_ino);
return -ENOMEM; return -ENOMEM;
} }
...@@ -1401,8 +1419,7 @@ static int udf_alloc_i_data(struct inode *inode, size_t size) ...@@ -1401,8 +1419,7 @@ static int udf_alloc_i_data(struct inode *inode, size_t size)
return 0; return 0;
} }
static mode_t static mode_t udf_convert_permissions(struct fileEntry *fe)
udf_convert_permissions(struct fileEntry *fe)
{ {
mode_t mode; mode_t mode;
uint32_t permissions; uint32_t permissions;
...@@ -1411,12 +1428,12 @@ udf_convert_permissions(struct fileEntry *fe) ...@@ -1411,12 +1428,12 @@ udf_convert_permissions(struct fileEntry *fe)
permissions = le32_to_cpu(fe->permissions); permissions = le32_to_cpu(fe->permissions);
flags = le16_to_cpu(fe->icbTag.flags); flags = le16_to_cpu(fe->icbTag.flags);
mode = (( permissions ) & S_IRWXO) | mode = ((permissions) & S_IRWXO) |
(( permissions >> 2 ) & S_IRWXG) | ((permissions >> 2) & S_IRWXG) |
(( permissions >> 4 ) & S_IRWXU) | ((permissions >> 4) & S_IRWXU) |
(( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) | ((flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
(( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) | ((flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
(( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0); ((flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
return mode; return mode;
} }
...@@ -1436,7 +1453,7 @@ udf_convert_permissions(struct fileEntry *fe) ...@@ -1436,7 +1453,7 @@ udf_convert_permissions(struct fileEntry *fe)
* Written, tested, and released. * Written, tested, and released.
*/ */
int udf_write_inode(struct inode * inode, int sync) int udf_write_inode(struct inode *inode, int sync)
{ {
int ret; int ret;
lock_kernel(); lock_kernel();
...@@ -1445,13 +1462,12 @@ int udf_write_inode(struct inode * inode, int sync) ...@@ -1445,13 +1462,12 @@ int udf_write_inode(struct inode * inode, int sync)
return ret; return ret;
} }
int udf_sync_inode(struct inode * inode) int udf_sync_inode(struct inode *inode)
{ {
return udf_update_inode(inode, 1); return udf_update_inode(inode, 1);
} }
static int static int udf_update_inode(struct inode *inode, int do_sync)
udf_update_inode(struct inode *inode, int do_sync)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
struct fileEntry *fe; struct fileEntry *fe;
...@@ -1464,10 +1480,10 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1464,10 +1480,10 @@ udf_update_inode(struct inode *inode, int do_sync)
int err = 0; int err = 0;
bh = udf_tread(inode->i_sb, bh = udf_tread(inode->i_sb,
udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0)); udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode),
0));
if (!bh) if (!bh) {
{
udf_debug("bread failure\n"); udf_debug("bread failure\n");
return -EIO; return -EIO;
} }
...@@ -1477,23 +1493,29 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1477,23 +1493,29 @@ udf_update_inode(struct inode *inode, int do_sync)
fe = (struct fileEntry *)bh->b_data; fe = (struct fileEntry *)bh->b_data;
efe = (struct extendedFileEntry *)bh->b_data; efe = (struct extendedFileEntry *)bh->b_data;
if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) {
{
struct unallocSpaceEntry *use = struct unallocSpaceEntry *use =
(struct unallocSpaceEntry *)bh->b_data; (struct unallocSpaceEntry *)bh->b_data;
use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)); memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),
crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) - UDF_I_DATA(inode),
sizeof(tag); inode->i_sb->s_blocksize -
use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); sizeof(struct unallocSpaceEntry));
crclen =
sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
sizeof(tag);
use->descTag.tagLocation =
cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
use->descTag.descCRCLength = cpu_to_le16(crclen); use->descTag.descCRCLength = cpu_to_le16(crclen);
use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0)); use->descTag.descCRC =
cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
use->descTag.tagChecksum = 0; use->descTag.tagChecksum = 0;
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
if (i != 4) if (i != 4)
use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i]; use->descTag.tagChecksum +=
((uint8_t *) & (use->descTag))[i];
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
...@@ -1502,20 +1524,21 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1502,20 +1524,21 @@ udf_update_inode(struct inode *inode, int do_sync)
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
fe->uid = cpu_to_le32(-1); fe->uid = cpu_to_le32(-1);
else fe->uid = cpu_to_le32(inode->i_uid); else
fe->uid = cpu_to_le32(inode->i_uid);
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
fe->gid = cpu_to_le32(-1); fe->gid = cpu_to_le32(-1);
else fe->gid = cpu_to_le32(inode->i_gid); else
fe->gid = cpu_to_le32(inode->i_gid);
udfperms = ((inode->i_mode & S_IRWXO) ) | udfperms = ((inode->i_mode & S_IRWXO)) |
((inode->i_mode & S_IRWXG) << 2) | ((inode->i_mode & S_IRWXG) << 2) | ((inode->i_mode & S_IRWXU) << 4);
((inode->i_mode & S_IRWXU) << 4);
udfperms |= (le32_to_cpu(fe->permissions) & udfperms |= (le32_to_cpu(fe->permissions) &
(FE_PERM_O_DELETE | FE_PERM_O_CHATTR | (FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
FE_PERM_G_DELETE | FE_PERM_G_CHATTR | FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
fe->permissions = cpu_to_le32(udfperms); fe->permissions = cpu_to_le32(udfperms);
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
...@@ -1525,26 +1548,24 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1525,26 +1548,24 @@ udf_update_inode(struct inode *inode, int do_sync)
fe->informationLength = cpu_to_le64(inode->i_size); fe->informationLength = cpu_to_le64(inode->i_size);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
{
regid *eid; regid *eid;
struct deviceSpec *dsea = struct deviceSpec *dsea = (struct deviceSpec *)
(struct deviceSpec *) udf_get_extendedattr(inode, 12, 1);
udf_get_extendedattr(inode, 12, 1);
if (!dsea) if (!dsea) {
{
dsea = (struct deviceSpec *) dsea = (struct deviceSpec *)
udf_add_extendedattr(inode, udf_add_extendedattr(inode,
sizeof(struct deviceSpec) + sizeof(struct deviceSpec) +
sizeof(regid), 12, 0x3); sizeof(regid), 12, 0x3);
dsea->attrType = cpu_to_le32(12); dsea->attrType = cpu_to_le32(12);
dsea->attrSubtype = 1; dsea->attrSubtype = 1;
dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) + dsea->attrLength =
sizeof(regid)); cpu_to_le32(sizeof(struct deviceSpec) +
sizeof(regid));
dsea->impUseLength = cpu_to_le32(sizeof(regid)); dsea->impUseLength = cpu_to_le32(sizeof(regid));
} }
eid = (regid *)dsea->impUse; eid = (regid *) dsea->impUse;
memset(eid, 0, sizeof(regid)); memset(eid, 0, sizeof(regid));
strcpy(eid->ident, UDF_ID_DEVELOPER); strcpy(eid->ident, UDF_ID_DEVELOPER);
eid->identSuffix[0] = UDF_OS_CLASS_UNIX; eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
...@@ -1553,12 +1574,13 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1553,12 +1574,13 @@ udf_update_inode(struct inode *inode, int do_sync)
dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
} }
if (UDF_I_EFE(inode) == 0) if (UDF_I_EFE(inode) == 0) {
{ memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode),
memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct fileEntry)); inode->i_sb->s_blocksize - sizeof(struct fileEntry));
fe->logicalBlocksRecorded = cpu_to_le64( fe->logicalBlocksRecorded =
(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >> cpu_to_le64((inode->i_blocks +
(inode->i_sb->s_blocksize_bits - 9)); (1 << (inode->i_sb->s_blocksize_bits - 9)) -
1) >> (inode->i_sb->s_blocksize_bits - 9));
if (udf_time_to_stamp(&cpu_time, inode->i_atime)) if (udf_time_to_stamp(&cpu_time, inode->i_atime))
fe->accessTime = cpu_to_lets(cpu_time); fe->accessTime = cpu_to_lets(cpu_time);
...@@ -1575,31 +1597,34 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1575,31 +1597,34 @@ udf_update_inode(struct inode *inode, int do_sync)
fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
crclen = sizeof(struct fileEntry); crclen = sizeof(struct fileEntry);
} } else {
else memcpy(bh->b_data + sizeof(struct extendedFileEntry),
{ UDF_I_DATA(inode),
memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); inode->i_sb->s_blocksize -
sizeof(struct extendedFileEntry));
efe->objectSize = cpu_to_le64(inode->i_size); efe->objectSize = cpu_to_le64(inode->i_size);
efe->logicalBlocksRecorded = cpu_to_le64( efe->logicalBlocksRecorded = cpu_to_le64((inode->i_blocks +
(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >> (1 <<
(inode->i_sb->s_blocksize_bits - 9)); (inode->i_sb->
s_blocksize_bits -
9)) -
1) >> (inode->i_sb->
s_blocksize_bits
- 9));
if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec || if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
(UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec && (UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec)) UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec)) {
{
UDF_I_CRTIME(inode) = inode->i_atime; UDF_I_CRTIME(inode) = inode->i_atime;
} }
if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec || if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||
(UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec && (UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&
UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec)) UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec)) {
{
UDF_I_CRTIME(inode) = inode->i_mtime; UDF_I_CRTIME(inode) = inode->i_mtime;
} }
if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec || if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||
(UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec && (UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&
UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec)) UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec)) {
{
UDF_I_CRTIME(inode) = inode->i_ctime; UDF_I_CRTIME(inode) = inode->i_ctime;
} }
...@@ -1622,14 +1647,11 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1622,14 +1647,11 @@ udf_update_inode(struct inode *inode, int do_sync)
efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
crclen = sizeof(struct extendedFileEntry); crclen = sizeof(struct extendedFileEntry);
} }
if (UDF_I_STRAT4096(inode)) if (UDF_I_STRAT4096(inode)) {
{
fe->icbTag.strategyType = cpu_to_le16(4096); fe->icbTag.strategyType = cpu_to_le16(4096);
fe->icbTag.strategyParameter = cpu_to_le16(1); fe->icbTag.strategyParameter = cpu_to_le16(1);
fe->icbTag.numEntries = cpu_to_le16(2); fe->icbTag.numEntries = cpu_to_le16(2);
} } else {
else
{
fe->icbTag.strategyType = cpu_to_le16(4); fe->icbTag.strategyType = cpu_to_le16(4);
fe->icbTag.numEntries = cpu_to_le16(1); fe->icbTag.numEntries = cpu_to_le16(1);
} }
...@@ -1649,13 +1671,13 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1649,13 +1671,13 @@ udf_update_inode(struct inode *inode, int do_sync)
else if (S_ISSOCK(inode->i_mode)) else if (S_ISSOCK(inode->i_mode))
fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET; fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;
icbflags = UDF_I_ALLOCTYPE(inode) | icbflags = UDF_I_ALLOCTYPE(inode) |
((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) | ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) | ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) | ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
(le16_to_cpu(fe->icbTag.flags) & (le16_to_cpu(fe->icbTag.flags) &
~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID | ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY)); ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
fe->icbTag.flags = cpu_to_le16(icbflags); fe->icbTag.flags = cpu_to_le16(icbflags);
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
...@@ -1663,25 +1685,26 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1663,25 +1685,26 @@ udf_update_inode(struct inode *inode, int do_sync)
else else
fe->descTag.descVersion = cpu_to_le16(2); fe->descTag.descVersion = cpu_to_le16(2);
fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); fe->descTag.tagLocation =
cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag); crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
fe->descTag.descCRCLength = cpu_to_le16(crclen); fe->descTag.descCRCLength = cpu_to_le16(crclen);
fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0)); fe->descTag.descCRC =
cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
fe->descTag.tagChecksum = 0; fe->descTag.tagChecksum = 0;
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
if (i != 4) if (i != 4)
fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i]; fe->descTag.tagChecksum +=
((uint8_t *) & (fe->descTag))[i];
/* write the data blocks */ /* write the data blocks */
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
if (do_sync) if (do_sync) {
{
sync_dirty_buffer(bh); sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh)) if (buffer_req(bh) && !buffer_uptodate(bh)) {
{
printk("IO error syncing udf inode [%s:%08lx]\n", printk("IO error syncing udf inode [%s:%08lx]\n",
inode->i_sb->s_id, inode->i_ino); inode->i_sb->s_id, inode->i_ino);
err = -EIO; err = -EIO;
} }
} }
...@@ -1689,8 +1712,7 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1689,8 +1712,7 @@ udf_update_inode(struct inode *inode, int do_sync)
return err; return err;
} }
struct inode * struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
udf_iget(struct super_block *sb, kernel_lb_addr ino)
{ {
unsigned long block = udf_get_lb_pblock(sb, ino, 0); unsigned long block = udf_get_lb_pblock(sb, ino, 0);
struct inode *inode = iget_locked(sb, block); struct inode *inode = iget_locked(sb, block);
...@@ -1707,22 +1729,23 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino) ...@@ -1707,22 +1729,23 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino)
if (is_bad_inode(inode)) if (is_bad_inode(inode))
goto out_iput; goto out_iput;
if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) { if (ino.logicalBlockNum >=
UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
udf_debug("block=%d, partition=%d out of range\n", udf_debug("block=%d, partition=%d out of range\n",
ino.logicalBlockNum, ino.partitionReferenceNum); ino.logicalBlockNum, ino.partitionReferenceNum);
make_bad_inode(inode); make_bad_inode(inode);
goto out_iput; goto out_iput;
} }
return inode; return inode;
out_iput: out_iput:
iput(inode); iput(inode);
return NULL; return NULL;
} }
int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
kernel_lb_addr eloc, uint32_t elen, int inc) kernel_lb_addr eloc, uint32_t elen, int inc)
{ {
int adsize; int adsize;
short_ad *sad = NULL; short_ad *sad = NULL;
...@@ -1732,7 +1755,9 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, ...@@ -1732,7 +1755,9 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
uint8_t *ptr; uint8_t *ptr;
if (!epos->bh) if (!epos->bh)
ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); ptr =
UDF_I_DATA(inode) + epos->offset -
udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else else
ptr = epos->bh->b_data + epos->offset; ptr = epos->bh->b_data + epos->offset;
...@@ -1743,21 +1768,24 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, ...@@ -1743,21 +1768,24 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
else else
return -1; return -1;
if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) {
{
char *sptr, *dptr; char *sptr, *dptr;
struct buffer_head *nbh; struct buffer_head *nbh;
int err, loffset; int err, loffset;
kernel_lb_addr obloc = epos->block; kernel_lb_addr obloc = epos->block;
if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, if (!
obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) (epos->block.logicalBlockNum =
{ udf_new_block(inode->i_sb, NULL,
obloc.partitionReferenceNum,
obloc.logicalBlockNum, &err))) {
return -1; return -1;
} }
if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, if (!
epos->block, 0)))) (nbh =
{ udf_tgetblk(inode->i_sb,
udf_get_lb_pblock(inode->i_sb, epos->block,
0)))) {
return -1; return -1;
} }
lock_buffer(nbh); lock_buffer(nbh);
...@@ -1768,144 +1796,142 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, ...@@ -1768,144 +1796,142 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
aed = (struct allocExtDesc *)(nbh->b_data); aed = (struct allocExtDesc *)(nbh->b_data);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); aed->previousAllocExtLocation =
if (epos->offset + adsize > inode->i_sb->s_blocksize) cpu_to_le32(obloc.logicalBlockNum);
{ if (epos->offset + adsize > inode->i_sb->s_blocksize) {
loffset = epos->offset; loffset = epos->offset;
aed->lengthAllocDescs = cpu_to_le32(adsize); aed->lengthAllocDescs = cpu_to_le32(adsize);
sptr = ptr - adsize; sptr = ptr - adsize;
dptr = nbh->b_data + sizeof(struct allocExtDesc); dptr = nbh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize); memcpy(dptr, sptr, adsize);
epos->offset = sizeof(struct allocExtDesc) + adsize; epos->offset = sizeof(struct allocExtDesc) + adsize;
} } else {
else
{
loffset = epos->offset + adsize; loffset = epos->offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0); aed->lengthAllocDescs = cpu_to_le32(0);
sptr = ptr; sptr = ptr;
epos->offset = sizeof(struct allocExtDesc); epos->offset = sizeof(struct allocExtDesc);
if (epos->bh) if (epos->bh) {
{
aed = (struct allocExtDesc *)epos->bh->b_data; aed = (struct allocExtDesc *)epos->bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); cpu_to_le32(le32_to_cpu
} (aed->lengthAllocDescs) +
else adsize);
{ } else {
UDF_I_LENALLOC(inode) += adsize; UDF_I_LENALLOC(inode) += adsize;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
} }
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
epos->block.logicalBlockNum, sizeof(tag)); epos->block.logicalBlockNum, sizeof(tag));
else else
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
epos->block.logicalBlockNum, sizeof(tag)); epos->block.logicalBlockNum, sizeof(tag));
switch (UDF_I_ALLOCTYPE(inode)) switch (UDF_I_ALLOCTYPE(inode)) {
{ case ICBTAG_FLAG_AD_SHORT:
case ICBTAG_FLAG_AD_SHORT:
{ {
sad = (short_ad *)sptr; sad = (short_ad *) sptr;
sad->extLength = cpu_to_le32( sad->extLength =
EXT_NEXT_EXTENT_ALLOCDECS | cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize); inode->i_sb->s_blocksize);
sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum); sad->extPosition =
cpu_to_le32(epos->block.logicalBlockNum);
break; break;
} }
case ICBTAG_FLAG_AD_LONG: case ICBTAG_FLAG_AD_LONG:
{ {
lad = (long_ad *)sptr; lad = (long_ad *) sptr;
lad->extLength = cpu_to_le32( lad->extLength =
EXT_NEXT_EXTENT_ALLOCDECS | cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize); inode->i_sb->s_blocksize);
lad->extLocation = cpu_to_lelb(epos->block); lad->extLocation = cpu_to_lelb(epos->block);
memset(lad->impUse, 0x00, sizeof(lad->impUse)); memset(lad->impUse, 0x00, sizeof(lad->impUse));
break; break;
} }
} }
if (epos->bh) if (epos->bh) {
{ if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(epos->bh->b_data, loffset); udf_update_tag(epos->bh->b_data, loffset);
else else
udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos->bh->b_data,
sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(epos->bh, inode); mark_buffer_dirty_inode(epos->bh, inode);
brelse(epos->bh); brelse(epos->bh);
} } else
else
mark_inode_dirty(inode); mark_inode_dirty(inode);
epos->bh = nbh; epos->bh = nbh;
} }
etype = udf_write_aext(inode, epos, eloc, elen, inc); etype = udf_write_aext(inode, epos, eloc, elen, inc);
if (!epos->bh) if (!epos->bh) {
{
UDF_I_LENALLOC(inode) += adsize; UDF_I_LENALLOC(inode) += adsize;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} } else {
else
{
aed = (struct allocExtDesc *)epos->bh->b_data; aed = (struct allocExtDesc *)epos->bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize)); || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(epos->bh->b_data,
epos->offset + (inc ? 0 : adsize));
else else
udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos->bh->b_data,
sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(epos->bh, inode); mark_buffer_dirty_inode(epos->bh, inode);
} }
return etype; return etype;
} }
int8_t udf_write_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) kernel_lb_addr eloc, uint32_t elen, int inc)
{ {
int adsize; int adsize;
uint8_t *ptr; uint8_t *ptr;
if (!epos->bh) if (!epos->bh)
ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); ptr =
UDF_I_DATA(inode) + epos->offset -
udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else else
ptr = epos->bh->b_data + epos->offset; ptr = epos->bh->b_data + epos->offset;
switch (UDF_I_ALLOCTYPE(inode)) switch (UDF_I_ALLOCTYPE(inode)) {
{ case ICBTAG_FLAG_AD_SHORT:
case ICBTAG_FLAG_AD_SHORT:
{ {
short_ad *sad = (short_ad *)ptr; short_ad *sad = (short_ad *) ptr;
sad->extLength = cpu_to_le32(elen); sad->extLength = cpu_to_le32(elen);
sad->extPosition = cpu_to_le32(eloc.logicalBlockNum); sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
adsize = sizeof(short_ad); adsize = sizeof(short_ad);
break; break;
} }
case ICBTAG_FLAG_AD_LONG: case ICBTAG_FLAG_AD_LONG:
{ {
long_ad *lad = (long_ad *)ptr; long_ad *lad = (long_ad *) ptr;
lad->extLength = cpu_to_le32(elen); 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)); memset(lad->impUse, 0x00, sizeof(lad->impUse));
adsize = sizeof(long_ad); adsize = sizeof(long_ad);
break; break;
} }
default: default:
return -1; return -1;
} }
if (epos->bh) if (epos->bh) {
{ if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) {
{ struct allocExtDesc *aed =
struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data; (struct allocExtDesc *)epos->bh->b_data;
udf_update_tag(epos->bh->b_data, udf_update_tag(epos->bh->b_data,
le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); le32_to_cpu(aed->lengthAllocDescs) +
sizeof(struct allocExtDesc));
} }
mark_buffer_dirty_inode(epos->bh, inode); mark_buffer_dirty_inode(epos->bh, inode);
} } else
else
mark_inode_dirty(inode); mark_inode_dirty(inode);
if (inc) if (inc)
...@@ -1913,21 +1939,24 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos, ...@@ -1913,21 +1939,24 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
return (elen >> 30); return (elen >> 30);
} }
int8_t udf_next_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) kernel_lb_addr * eloc, uint32_t * elen, int inc)
{ {
int8_t etype; int8_t etype;
while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
(EXT_NEXT_EXTENT_ALLOCDECS >> 30)) (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
{
epos->block = *eloc; epos->block = *eloc;
epos->offset = sizeof(struct allocExtDesc); epos->offset = sizeof(struct allocExtDesc);
brelse(epos->bh); brelse(epos->bh);
if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0)))) if (!
{ (epos->bh =
udf_tread(inode->i_sb,
udf_get_lb_pblock(inode->i_sb, epos->block,
0)))) {
udf_debug("reading block %d failed!\n", udf_debug("reading block %d failed!\n",
udf_get_lb_pblock(inode->i_sb, epos->block, 0)); udf_get_lb_pblock(inode->i_sb, epos->block,
0));
return -1; return -1;
} }
} }
...@@ -1935,58 +1964,71 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, ...@@ -1935,58 +1964,71 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
return etype; return etype;
} }
int8_t udf_current_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) kernel_lb_addr * eloc, uint32_t * elen, int inc)
{ {
int alen; int alen;
int8_t etype; int8_t etype;
uint8_t *ptr; uint8_t *ptr;
if (!epos->bh) if (!epos->bh) {
{
if (!epos->offset) if (!epos->offset)
epos->offset = udf_file_entry_alloc_offset(inode); epos->offset = udf_file_entry_alloc_offset(inode);
ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); ptr =
alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode); UDF_I_DATA(inode) + epos->offset -
} udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else alen =
{ udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
} else {
if (!epos->offset) if (!epos->offset)
epos->offset = sizeof(struct allocExtDesc); epos->offset = sizeof(struct allocExtDesc);
ptr = epos->bh->b_data + epos->offset; ptr = epos->bh->b_data + epos->offset;
alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs); alen =
sizeof(struct allocExtDesc) +
le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->
lengthAllocDescs);
} }
switch (UDF_I_ALLOCTYPE(inode)) switch (UDF_I_ALLOCTYPE(inode)) {
{ case ICBTAG_FLAG_AD_SHORT:
case ICBTAG_FLAG_AD_SHORT:
{ {
short_ad *sad; short_ad *sad;
if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc))) if (!
(sad =
udf_get_fileshortad(ptr, alen, &epos->offset,
inc)))
return -1; return -1;
etype = le32_to_cpu(sad->extLength) >> 30; etype = le32_to_cpu(sad->extLength) >> 30;
eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; eloc->partitionReferenceNum =
*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK; UDF_I_LOCATION(inode).partitionReferenceNum;
*elen =
le32_to_cpu(sad->
extLength) & UDF_EXTENT_LENGTH_MASK;
break; break;
} }
case ICBTAG_FLAG_AD_LONG: case ICBTAG_FLAG_AD_LONG:
{ {
long_ad *lad; long_ad *lad;
if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc))) if (!
(lad =
udf_get_filelongad(ptr, alen, &epos->offset, inc)))
return -1; return -1;
etype = le32_to_cpu(lad->extLength) >> 30; etype = le32_to_cpu(lad->extLength) >> 30;
*eloc = lelb_to_cpu(lad->extLocation); *eloc = lelb_to_cpu(lad->extLocation);
*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; *elen =
le32_to_cpu(lad->
extLength) & UDF_EXTENT_LENGTH_MASK;
break; break;
} }
default: default:
{ {
udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode)); udf_debug("alloc_type = %d unsupported\n",
UDF_I_ALLOCTYPE(inode));
return -1; return -1;
} }
} }
...@@ -2005,8 +2047,7 @@ udf_insert_aext(struct inode *inode, struct extent_position epos, ...@@ -2005,8 +2047,7 @@ udf_insert_aext(struct inode *inode, struct extent_position epos,
if (epos.bh) if (epos.bh)
get_bh(epos.bh); get_bh(epos.bh);
while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) 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; neloc = oeloc;
...@@ -2017,16 +2058,15 @@ udf_insert_aext(struct inode *inode, struct extent_position epos, ...@@ -2017,16 +2058,15 @@ udf_insert_aext(struct inode *inode, struct extent_position epos,
return (nelen >> 30); return (nelen >> 30);
} }
int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, int8_t udf_delete_aext(struct inode * inode, struct extent_position epos,
kernel_lb_addr eloc, uint32_t elen) kernel_lb_addr eloc, uint32_t elen)
{ {
struct extent_position oepos; struct extent_position oepos;
int adsize; int adsize;
int8_t etype; int8_t etype;
struct allocExtDesc *aed; struct allocExtDesc *aed;
if (epos.bh) if (epos.bh) {
{
get_bh(epos.bh); get_bh(epos.bh);
get_bh(epos.bh); get_bh(epos.bh);
} }
...@@ -2042,11 +2082,9 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, ...@@ -2042,11 +2082,9 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
return -1; return -1;
while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -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) if (oepos.bh != epos.bh) {
{
oepos.block = epos.block; oepos.block = epos.block;
brelse(oepos.bh); brelse(oepos.bh);
get_bh(epos.bh); get_bh(epos.bh);
...@@ -2057,45 +2095,44 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, ...@@ -2057,45 +2095,44 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
memset(&eloc, 0x00, sizeof(kernel_lb_addr)); memset(&eloc, 0x00, sizeof(kernel_lb_addr));
elen = 0; elen = 0;
if (epos.bh != oepos.bh) if (epos.bh != oepos.bh) {
{
udf_free_blocks(inode->i_sb, inode, epos.block, 0, 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);
udf_write_aext(inode, &oepos, eloc, elen, 1); udf_write_aext(inode, &oepos, eloc, elen, 1);
if (!oepos.bh) if (!oepos.bh) {
{
UDF_I_LENALLOC(inode) -= (adsize * 2); UDF_I_LENALLOC(inode) -= (adsize * 2);
mark_inode_dirty(inode); mark_inode_dirty(inode);
} } else {
else
{
aed = (struct allocExtDesc *)oepos.bh->b_data; aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) (2 * adsize));
udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize)); if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
|| UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(oepos.bh->b_data,
oepos.offset - (2 * adsize));
else else
udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(oepos.bh->b_data,
sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(oepos.bh, inode); mark_buffer_dirty_inode(oepos.bh, inode);
} }
} } else {
else
{
udf_write_aext(inode, &oepos, eloc, elen, 1); udf_write_aext(inode, &oepos, eloc, elen, 1);
if (!oepos.bh) if (!oepos.bh) {
{
UDF_I_LENALLOC(inode) -= adsize; UDF_I_LENALLOC(inode) -= adsize;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} } else {
else
{
aed = (struct allocExtDesc *)oepos.bh->b_data; aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) adsize);
udf_update_tag(oepos.bh->b_data, epos.offset - adsize); if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
|| UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(oepos.bh->b_data,
epos.offset - adsize);
else else
udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(oepos.bh->b_data,
sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(oepos.bh, inode); mark_buffer_dirty_inode(oepos.bh, inode);
} }
} }
...@@ -2105,14 +2142,15 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, ...@@ -2105,14 +2142,15 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
return (elen >> 30); return (elen >> 30);
} }
int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos, int8_t inode_bmap(struct inode * inode, sector_t block,
kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset) struct extent_position * pos, kernel_lb_addr * eloc,
uint32_t * elen, sector_t * offset)
{ {
loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits; loff_t lbcount = 0, bcount =
(loff_t) block << inode->i_sb->s_blocksize_bits;
int8_t etype; int8_t etype;
if (block < 0) if (block < 0) {
{
printk(KERN_ERR "udf: inode_bmap: block < 0\n"); printk(KERN_ERR "udf: inode_bmap: block < 0\n");
return -1; return -1;
} }
...@@ -2122,11 +2160,10 @@ int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *p ...@@ -2122,11 +2160,10 @@ int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *p
pos->bh = NULL; pos->bh = NULL;
*elen = 0; *elen = 0;
do do {
{ if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) {
if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) *offset =
{ (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
*offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
UDF_I_LENEXTENTS(inode) = lbcount; UDF_I_LENEXTENTS(inode) = lbcount;
return -1; return -1;
} }
...@@ -2143,12 +2180,13 @@ long udf_block_map(struct inode *inode, sector_t block) ...@@ -2143,12 +2180,13 @@ long udf_block_map(struct inode *inode, sector_t block)
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen; uint32_t elen;
sector_t offset; sector_t offset;
struct extent_position epos = { NULL, 0, { 0, 0}}; struct extent_position epos = { NULL, 0, {0, 0} };
int ret; int ret;
lock_kernel(); lock_kernel();
if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) 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 else
ret = 0; ret = 0;
......
...@@ -26,43 +26,38 @@ ...@@ -26,43 +26,38 @@
#include <linux/udf_fs.h> #include <linux/udf_fs.h>
#include "udf_sb.h" #include "udf_sb.h"
unsigned int unsigned int udf_get_last_session(struct super_block *sb)
udf_get_last_session(struct super_block *sb)
{ {
struct cdrom_multisession ms_info; struct cdrom_multisession ms_info;
unsigned int vol_desc_start; unsigned int vol_desc_start;
struct block_device *bdev = sb->s_bdev; struct block_device *bdev = sb->s_bdev;
int i; int i;
vol_desc_start=0; vol_desc_start = 0;
ms_info.addr_format=CDROM_LBA; ms_info.addr_format = CDROM_LBA;
i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info); i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info);
#define WE_OBEY_THE_WRITTEN_STANDARDS 1 #define WE_OBEY_THE_WRITTEN_STANDARDS 1
if (i == 0) if (i == 0) {
{
udf_debug("XA disk: %s, vol_desc_start=%d\n", udf_debug("XA disk: %s, vol_desc_start=%d\n",
(ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba); (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba);
#if WE_OBEY_THE_WRITTEN_STANDARDS #if WE_OBEY_THE_WRITTEN_STANDARDS
if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
#endif #endif
vol_desc_start = ms_info.addr.lba; vol_desc_start = ms_info.addr.lba;
} } else {
else
{
udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
} }
return vol_desc_start; return vol_desc_start;
} }
unsigned long unsigned long udf_get_last_block(struct super_block *sb)
udf_get_last_block(struct super_block *sb)
{ {
struct block_device *bdev = sb->s_bdev; struct block_device *bdev = sb->s_bdev;
unsigned long lblock = 0; unsigned long lblock = 0;
if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock)) if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long)&lblock))
lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits; lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits;
if (lblock) if (lblock)
......
...@@ -29,8 +29,7 @@ ...@@ -29,8 +29,7 @@
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
struct buffer_head * struct buffer_head *udf_tgetblk(struct super_block *sb, int block)
udf_tgetblk(struct super_block *sb, int block)
{ {
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
return sb_getblk(sb, udf_fixed_to_variable(block)); return sb_getblk(sb, udf_fixed_to_variable(block));
...@@ -38,8 +37,7 @@ udf_tgetblk(struct super_block *sb, int block) ...@@ -38,8 +37,7 @@ udf_tgetblk(struct super_block *sb, int block)
return sb_getblk(sb, block); return sb_getblk(sb, block);
} }
struct buffer_head * struct buffer_head *udf_tread(struct super_block *sb, int block)
udf_tread(struct super_block *sb, int block)
{ {
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
return sb_bread(sb, udf_fixed_to_variable(block)); return sb_bread(sb, udf_fixed_to_variable(block));
...@@ -47,9 +45,8 @@ udf_tread(struct super_block *sb, int block) ...@@ -47,9 +45,8 @@ udf_tread(struct super_block *sb, int block)
return sb_bread(sb, block); return sb_bread(sb, block);
} }
struct genericFormat * struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type, uint32_t type, uint8_t loc)
uint8_t loc)
{ {
uint8_t *ea = NULL, *ad = NULL; uint8_t *ea = NULL, *ad = NULL;
int offset; int offset;
...@@ -59,78 +56,76 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type, ...@@ -59,78 +56,76 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
ea = UDF_I_DATA(inode); ea = UDF_I_DATA(inode);
if (UDF_I_LENEATTR(inode)) if (UDF_I_LENEATTR(inode))
ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
else else {
{
ad = ea; ad = ea;
size += sizeof(struct extendedAttrHeaderDesc); size += sizeof(struct extendedAttrHeaderDesc);
} }
offset = inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) - offset = inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) -
UDF_I_LENALLOC(inode); UDF_I_LENALLOC(inode);
/* TODO - Check for FreeEASpace */ /* TODO - Check for FreeEASpace */
if (loc & 0x01 && offset >= size) if (loc & 0x01 && offset >= size) {
{
struct extendedAttrHeaderDesc *eahd; struct extendedAttrHeaderDesc *eahd;
eahd = (struct extendedAttrHeaderDesc *)ea; eahd = (struct extendedAttrHeaderDesc *)ea;
if (UDF_I_LENALLOC(inode)) if (UDF_I_LENALLOC(inode)) {
{
memmove(&ad[size], ad, UDF_I_LENALLOC(inode)); memmove(&ad[size], ad, UDF_I_LENALLOC(inode));
} }
if (UDF_I_LENEATTR(inode)) if (UDF_I_LENEATTR(inode)) {
{
/* check checksum/crc */ /* check checksum/crc */
if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || if (le16_to_cpu(eahd->descTag.tagIdent) !=
le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) TAG_IDENT_EAHD
{ || le32_to_cpu(eahd->descTag.tagLocation) !=
UDF_I_LOCATION(inode).logicalBlockNum) {
return NULL; return NULL;
} }
} } else {
else
{
size -= sizeof(struct extendedAttrHeaderDesc); size -= sizeof(struct extendedAttrHeaderDesc);
UDF_I_LENEATTR(inode) += sizeof(struct extendedAttrHeaderDesc); UDF_I_LENEATTR(inode) +=
sizeof(struct extendedAttrHeaderDesc);
eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD); eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD);
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
eahd->descTag.descVersion = cpu_to_le16(3); eahd->descTag.descVersion = cpu_to_le16(3);
else else
eahd->descTag.descVersion = cpu_to_le16(2); eahd->descTag.descVersion = cpu_to_le16(2);
eahd->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); eahd->descTag.tagSerialNum =
eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
eahd->descTag.tagLocation =
cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF); eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF);
eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF); eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF);
} }
offset = UDF_I_LENEATTR(inode); offset = UDF_I_LENEATTR(inode);
if (type < 2048) if (type < 2048) {
{ if (le32_to_cpu(eahd->appAttrLocation) <
if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) UDF_I_LENEATTR(inode)) {
{ uint32_t aal =
uint32_t aal = le32_to_cpu(eahd->appAttrLocation); le32_to_cpu(eahd->appAttrLocation);
memmove(&ea[offset - aal + size], memmove(&ea[offset - aal + size], &ea[aal],
&ea[aal], offset - aal); offset - aal);
offset -= aal; offset -= aal;
eahd->appAttrLocation = cpu_to_le32(aal + size); eahd->appAttrLocation = cpu_to_le32(aal + size);
} }
if (le32_to_cpu(eahd->impAttrLocation) < UDF_I_LENEATTR(inode)) if (le32_to_cpu(eahd->impAttrLocation) <
{ UDF_I_LENEATTR(inode)) {
uint32_t ial = le32_to_cpu(eahd->impAttrLocation); uint32_t ial =
memmove(&ea[offset - ial + size], le32_to_cpu(eahd->impAttrLocation);
&ea[ial], offset - ial); memmove(&ea[offset - ial + size], &ea[ial],
offset - ial);
offset -= ial; offset -= ial;
eahd->impAttrLocation = cpu_to_le32(ial + size); eahd->impAttrLocation = cpu_to_le32(ial + size);
} }
} } else if (type < 65536) {
else if (type < 65536) if (le32_to_cpu(eahd->appAttrLocation) <
{ UDF_I_LENEATTR(inode)) {
if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) uint32_t aal =
{ le32_to_cpu(eahd->appAttrLocation);
uint32_t aal = le32_to_cpu(eahd->appAttrLocation); memmove(&ea[offset - aal + size], &ea[aal],
memmove(&ea[offset - aal + size], offset - aal);
&ea[aal], offset - aal);
offset -= aal; offset -= aal;
eahd->appAttrLocation = cpu_to_le32(aal + size); eahd->appAttrLocation = cpu_to_le32(aal + size);
} }
...@@ -138,22 +133,23 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type, ...@@ -138,22 +133,23 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
/* rewrite CRC + checksum of eahd */ /* rewrite CRC + checksum of eahd */
crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag);
eahd->descTag.descCRCLength = cpu_to_le16(crclen); eahd->descTag.descCRCLength = cpu_to_le16(crclen);
eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0)); eahd->descTag.descCRC =
cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0));
eahd->descTag.tagChecksum = 0; eahd->descTag.tagChecksum = 0;
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
if (i != 4) if (i != 4)
eahd->descTag.tagChecksum += ((uint8_t *)&(eahd->descTag))[i]; eahd->descTag.tagChecksum +=
((uint8_t *) & (eahd->descTag))[i];
UDF_I_LENEATTR(inode) += size; UDF_I_LENEATTR(inode) += size;
return (struct genericFormat *)&ea[offset]; return (struct genericFormat *)&ea[offset];
} }
if (loc & 0x02) if (loc & 0x02) {
{
} }
return NULL; return NULL;
} }
struct genericFormat * struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype) uint8_t subtype)
{ {
struct genericFormat *gaf; struct genericFormat *gaf;
uint8_t *ea = NULL; uint8_t *ea = NULL;
...@@ -161,18 +157,17 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype) ...@@ -161,18 +157,17 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
ea = UDF_I_DATA(inode); ea = UDF_I_DATA(inode);
if (UDF_I_LENEATTR(inode)) if (UDF_I_LENEATTR(inode)) {
{
struct extendedAttrHeaderDesc *eahd; struct extendedAttrHeaderDesc *eahd;
eahd = (struct extendedAttrHeaderDesc *)ea; eahd = (struct extendedAttrHeaderDesc *)ea;
/* check checksum/crc */ /* check checksum/crc */
if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) le32_to_cpu(eahd->descTag.tagLocation) !=
{ UDF_I_LOCATION(inode).logicalBlockNum) {
return NULL; return NULL;
} }
if (type < 2048) if (type < 2048)
offset = sizeof(struct extendedAttrHeaderDesc); offset = sizeof(struct extendedAttrHeaderDesc);
else if (type < 65536) else if (type < 65536)
...@@ -180,10 +175,10 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype) ...@@ -180,10 +175,10 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
else else
offset = le32_to_cpu(eahd->appAttrLocation); offset = le32_to_cpu(eahd->appAttrLocation);
while (offset < UDF_I_LENEATTR(inode)) while (offset < UDF_I_LENEATTR(inode)) {
{
gaf = (struct genericFormat *)&ea[offset]; gaf = (struct genericFormat *)&ea[offset];
if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype) if (le32_to_cpu(gaf->attrType) == type
&& gaf->attrSubtype == subtype)
return gaf; return gaf;
else else
offset += le32_to_cpu(gaf->attrLength); offset += le32_to_cpu(gaf->attrLength);
...@@ -202,8 +197,8 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype) ...@@ -202,8 +197,8 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
* July 1, 1997 - Andrew E. Mileski * July 1, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
struct buffer_head * struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint16_t *ident) uint32_t location, uint16_t * ident)
{ {
tag *tag_p; tag *tag_p;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
...@@ -215,29 +210,29 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1 ...@@ -215,29 +210,29 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1
return NULL; return NULL;
bh = udf_tread(sb, block + UDF_SB_SESSION(sb)); bh = udf_tread(sb, block + UDF_SB_SESSION(sb));
if (!bh) if (!bh) {
{ udf_debug("block=%d, location=%d: read failed\n",
udf_debug("block=%d, location=%d: read failed\n", block + UDF_SB_SESSION(sb), location); block + UDF_SB_SESSION(sb), location);
return NULL; return NULL;
} }
tag_p = (tag *)(bh->b_data); tag_p = (tag *) (bh->b_data);
*ident = le16_to_cpu(tag_p->tagIdent); *ident = le16_to_cpu(tag_p->tagIdent);
if ( location != le32_to_cpu(tag_p->tagLocation) ) if (location != le32_to_cpu(tag_p->tagLocation)) {
{
udf_debug("location mismatch block %u, tag %u != %u\n", udf_debug("location mismatch block %u, tag %u != %u\n",
block + UDF_SB_SESSION(sb), le32_to_cpu(tag_p->tagLocation), location); block + UDF_SB_SESSION(sb),
le32_to_cpu(tag_p->tagLocation), location);
goto error_out; goto error_out;
} }
/* Verify the tag checksum */ /* Verify the tag checksum */
checksum = 0U; checksum = 0U;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
checksum += (uint8_t)(bh->b_data[i]); checksum += (uint8_t) (bh->b_data[i]);
for (i = 5; i < 16; i++) for (i = 5; i < 16; i++)
checksum += (uint8_t)(bh->b_data[i]); checksum += (uint8_t) (bh->b_data[i]);
if (checksum != tag_p->tagChecksum) { if (checksum != tag_p->tagChecksum) {
printk(KERN_ERR "udf: tag checksum failed block %d\n", block); printk(KERN_ERR "udf: tag checksum failed block %d\n", block);
goto error_out; goto error_out;
...@@ -245,38 +240,39 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1 ...@@ -245,38 +240,39 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1
/* Verify the tag version */ /* Verify the tag version */
if (le16_to_cpu(tag_p->descVersion) != 0x0002U && if (le16_to_cpu(tag_p->descVersion) != 0x0002U &&
le16_to_cpu(tag_p->descVersion) != 0x0003U) le16_to_cpu(tag_p->descVersion) != 0x0003U) {
{
udf_debug("tag version 0x%04x != 0x0002 || 0x0003 block %d\n", udf_debug("tag version 0x%04x != 0x0002 || 0x0003 block %d\n",
le16_to_cpu(tag_p->descVersion), block); le16_to_cpu(tag_p->descVersion), block);
goto error_out; goto error_out;
} }
/* Verify the descriptor CRC */ /* Verify the descriptor CRC */
if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag), le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag),
le16_to_cpu(tag_p->descCRCLength), 0)) le16_to_cpu(tag_p->
{ descCRCLength),
0)) {
return bh; return bh;
} }
udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", udf_debug("Crc failure block %d: crc = %d, crclen = %d\n",
block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength)); block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC),
le16_to_cpu(tag_p->descCRCLength));
error_out: error_out:
brelse(bh); brelse(bh);
return NULL; return NULL;
} }
struct buffer_head * struct buffer_head *udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc,
udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, uint32_t offset, uint16_t *ident) uint32_t offset, uint16_t * ident)
{ {
return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset), 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) void udf_update_tag(char *data, int length)
{ {
tag *tptr = (tag *)data; tag *tptr = (tag *) data;
int i; int i;
length -= sizeof(tag); length -= sizeof(tag);
...@@ -285,15 +281,15 @@ void udf_update_tag(char *data, int length) ...@@ -285,15 +281,15 @@ void udf_update_tag(char *data, int length)
tptr->descCRCLength = cpu_to_le16(length); tptr->descCRCLength = cpu_to_le16(length);
tptr->descCRC = cpu_to_le16(udf_crc(data + sizeof(tag), length, 0)); tptr->descCRC = cpu_to_le16(udf_crc(data + sizeof(tag), length, 0));
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
if (i != 4) if (i != 4)
tptr->tagChecksum += (uint8_t)(data[i]); tptr->tagChecksum += (uint8_t) (data[i]);
} }
void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum, void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
uint32_t loc, int length) uint32_t loc, int length)
{ {
tag *tptr = (tag *)data; tag *tptr = (tag *) data;
tptr->tagIdent = cpu_to_le16(ident); tptr->tagIdent = cpu_to_le16(ident);
tptr->descVersion = cpu_to_le16(version); tptr->descVersion = cpu_to_le16(version);
tptr->tagSerialNum = cpu_to_le16(snum); tptr->tagSerialNum = cpu_to_le16(snum);
......
...@@ -32,7 +32,8 @@ ...@@ -32,7 +32,8 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/sched.h> #include <linux/sched.h>
static inline int udf_match(int len1, const char *name1, int len2, const char *name2) static inline int udf_match(int len1, const char *name1, int len2,
const char *name2)
{ {
if (len1 != len2) if (len1 != len2)
return 0; return 0;
...@@ -40,8 +41,8 @@ static inline int udf_match(int len1, const char *name1, int len2, const char *n ...@@ -40,8 +41,8 @@ static inline int udf_match(int len1, const char *name1, int len2, const char *n
} }
int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh, struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh,
uint8_t *impuse, uint8_t *fileident) uint8_t * impuse, uint8_t * fileident)
{ {
uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag); uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
uint16_t crc; uint16_t crc;
...@@ -51,7 +52,7 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, ...@@ -51,7 +52,7 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse); uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
uint8_t lfi = cfi->lengthFileIdent; uint8_t lfi = cfi->lengthFileIdent;
int padlen = fibh->eoffset - fibh->soffset - liu - lfi - int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
sizeof(struct fileIdentDesc); sizeof(struct fileIdentDesc);
int adinicb = 0; int adinicb = 0;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
...@@ -59,83 +60,86 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, ...@@ -59,83 +60,86 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
offset = fibh->soffset + sizeof(struct fileIdentDesc); offset = fibh->soffset + sizeof(struct fileIdentDesc);
if (impuse) if (impuse) {
{
if (adinicb || (offset + liu < 0)) if (adinicb || (offset + liu < 0))
memcpy((uint8_t *)sfi->impUse, impuse, liu); memcpy((uint8_t *) sfi->impUse, impuse, liu);
else if (offset >= 0) else if (offset >= 0)
memcpy(fibh->ebh->b_data + offset, impuse, liu); memcpy(fibh->ebh->b_data + offset, impuse, liu);
else else {
{ memcpy((uint8_t *) sfi->impUse, impuse, -offset);
memcpy((uint8_t *)sfi->impUse, impuse, -offset); memcpy(fibh->ebh->b_data, impuse - offset,
memcpy(fibh->ebh->b_data, impuse - offset, liu + offset); liu + offset);
} }
} }
offset += liu; offset += liu;
if (fileident) if (fileident) {
{
if (adinicb || (offset + lfi < 0)) if (adinicb || (offset + lfi < 0))
memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi); memcpy((uint8_t *) sfi->fileIdent + liu, fileident,
lfi);
else if (offset >= 0) else if (offset >= 0)
memcpy(fibh->ebh->b_data + offset, fileident, lfi); memcpy(fibh->ebh->b_data + offset, fileident, lfi);
else else {
{ memcpy((uint8_t *) sfi->fileIdent + liu, fileident,
memcpy((uint8_t *)sfi->fileIdent + liu, fileident, -offset); -offset);
memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset); memcpy(fibh->ebh->b_data, fileident - offset,
lfi + offset);
} }
} }
offset += lfi; offset += lfi;
if (adinicb || (offset + padlen < 0)) if (adinicb || (offset + padlen < 0))
memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen); memset((uint8_t *) sfi->padding + liu + lfi, 0x00, padlen);
else if (offset >= 0) else if (offset >= 0)
memset(fibh->ebh->b_data + offset, 0x00, padlen); memset(fibh->ebh->b_data + offset, 0x00, padlen);
else else {
{ memset((uint8_t *) sfi->padding + liu + lfi, 0x00, -offset);
memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset);
memset(fibh->ebh->b_data, 0x00, padlen + offset); memset(fibh->ebh->b_data, 0x00, padlen + offset);
} }
crc = udf_crc((uint8_t *)cfi + sizeof(tag), sizeof(struct fileIdentDesc) - crc =
sizeof(tag), 0); udf_crc((uint8_t *) cfi + sizeof(tag),
sizeof(struct fileIdentDesc) - sizeof(tag), 0);
if (fibh->sbh == fibh->ebh) if (fibh->sbh == fibh->ebh)
crc = udf_crc((uint8_t *)sfi->impUse, crc = udf_crc((uint8_t *) sfi->impUse,
crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc); crclen + sizeof(tag) -
sizeof(struct fileIdentDesc), crc);
else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) else if (sizeof(struct fileIdentDesc) >= -fibh->soffset)
crc = udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) + fibh->soffset, crc =
crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc); udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) +
else fibh->soffset,
{ crclen + sizeof(tag) - sizeof(struct fileIdentDesc),
crc = udf_crc((uint8_t *)sfi->impUse, crc);
-fibh->soffset - sizeof(struct fileIdentDesc), crc); else {
crc = udf_crc((uint8_t *) sfi->impUse,
-fibh->soffset - sizeof(struct fileIdentDesc),
crc);
crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc); crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc);
} }
cfi->descTag.descCRC = cpu_to_le16(crc); cfi->descTag.descCRC = cpu_to_le16(crc);
cfi->descTag.descCRCLength = cpu_to_le16(crclen); cfi->descTag.descCRCLength = cpu_to_le16(crclen);
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
if (i != 4) if (i != 4)
checksum += ((uint8_t *)&cfi->descTag)[i]; checksum += ((uint8_t *) & cfi->descTag)[i];
cfi->descTag.tagChecksum = checksum; cfi->descTag.tagChecksum = checksum;
if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset)) if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset))
memcpy((uint8_t *)sfi, (uint8_t *)cfi, sizeof(struct fileIdentDesc)); memcpy((uint8_t *) sfi, (uint8_t *) cfi,
else sizeof(struct fileIdentDesc));
{ else {
memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset); memcpy((uint8_t *) sfi, (uint8_t *) cfi, -fibh->soffset);
memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset, memcpy(fibh->ebh->b_data, (uint8_t *) cfi - fibh->soffset,
sizeof(struct fileIdentDesc) + fibh->soffset); sizeof(struct fileIdentDesc) + fibh->soffset);
} }
if (adinicb) if (adinicb)
mark_inode_dirty(inode); mark_inode_dirty(inode);
else else {
{
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
mark_buffer_dirty_inode(fibh->ebh, inode); mark_buffer_dirty_inode(fibh->ebh, inode);
mark_buffer_dirty_inode(fibh->sbh, inode); mark_buffer_dirty_inode(fibh->sbh, inode);
...@@ -143,12 +147,12 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, ...@@ -143,12 +147,12 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
return 0; return 0;
} }
static struct fileIdentDesc * static struct fileIdentDesc *udf_find_entry(struct inode *dir,
udf_find_entry(struct inode *dir, struct dentry *dentry, struct dentry *dentry,
struct udf_fileident_bh *fibh, struct udf_fileident_bh *fibh,
struct fileIdentDesc *cfi) struct fileIdentDesc *cfi)
{ {
struct fileIdentDesc *fi=NULL; struct fileIdentDesc *fi = NULL;
loff_t f_pos; loff_t f_pos;
int block, flen; int block, flen;
char fname[UDF_NAME_LEN]; char fname[UDF_NAME_LEN];
...@@ -159,46 +163,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, ...@@ -159,46 +163,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen; uint32_t elen;
sector_t offset; sector_t offset;
struct extent_position epos = { NULL, 0, { 0, 0}}; struct extent_position epos = { NULL, 0, {0, 0} };
size = (udf_ext0_offset(dir) + dir->i_size) >> 2; size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
f_pos = (udf_ext0_offset(dir) >> 2); f_pos = (udf_ext0_offset(dir) >> 2);
fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; fibh->soffset = fibh->eoffset =
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL; fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
&epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) &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 ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
epos.offset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
epos.offset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} } else
else
offset = 0; offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) {
{
brelse(epos.bh); brelse(epos.bh);
return NULL; return NULL;
} }
} } else {
else
{
brelse(epos.bh); brelse(epos.bh);
return NULL; return NULL;
} }
while ( (f_pos < size) ) while ((f_pos < size)) {
{ fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset); &elen, &offset);
if (!fi) if (!fi) {
{
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
brelse(fibh->ebh); brelse(fibh->ebh);
brelse(fibh->sbh); brelse(fibh->sbh);
...@@ -209,45 +208,45 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, ...@@ -209,45 +208,45 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
liu = le16_to_cpu(cfi->lengthOfImpUse); liu = le16_to_cpu(cfi->lengthOfImpUse);
lfi = cfi->lengthFileIdent; lfi = cfi->lengthFileIdent;
if (fibh->sbh == fibh->ebh) if (fibh->sbh == fibh->ebh) {
{
nameptr = fi->fileIdent + liu; nameptr = fi->fileIdent + liu;
} } else {
else
{
int poffset; /* Unpaded ending offset */ int poffset; /* Unpaded ending offset */
poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi; poffset =
fibh->soffset + sizeof(struct fileIdentDesc) + liu +
lfi;
if (poffset >= lfi) if (poffset >= lfi)
nameptr = (uint8_t *)(fibh->ebh->b_data + poffset - lfi); nameptr =
else (uint8_t *) (fibh->ebh->b_data + poffset -
{ lfi);
else {
nameptr = fname; nameptr = fname;
memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); memcpy(nameptr, fi->fileIdent + liu,
memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset); lfi - poffset);
memcpy(nameptr + lfi - poffset,
fibh->ebh->b_data, poffset);
} }
} }
if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 ) if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
{ if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE))
if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
continue; continue;
} }
if ( (cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 ) if ((cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) {
{ if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE))
if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
continue; continue;
} }
if (!lfi) if (!lfi)
continue; continue;
if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi))) if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi))) {
{ if (udf_match
if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) (flen, fname, dentry->d_name.len,
{ dentry->d_name.name)) {
brelse(epos.bh); brelse(epos.bh);
return fi; return fi;
} }
...@@ -293,41 +292,37 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, ...@@ -293,41 +292,37 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
* Written, tested, and released. * Written, tested, and released.
*/ */
static struct dentry * static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) struct nameidata *nd)
{ {
struct inode *inode = NULL; struct inode *inode = NULL;
struct fileIdentDesc cfi; struct fileIdentDesc cfi;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
if (dentry->d_name.len > UDF_NAME_LEN-2) if (dentry->d_name.len > UDF_NAME_LEN - 2)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel(); lock_kernel();
#ifdef UDF_RECOVERY #ifdef UDF_RECOVERY
/* temporary shorthand for specifying files by inode number */ /* temporary shorthand for specifying files by inode number */
if (!strncmp(dentry->d_name.name, ".B=", 3) ) if (!strncmp(dentry->d_name.name, ".B=", 3)) {
{ kernel_lb_addr lb =
kernel_lb_addr lb = { 0, simple_strtoul(dentry->d_name.name+3, NULL, 0) }; { 0, simple_strtoul(dentry->d_name.name + 3, NULL, 0) };
inode = udf_iget(dir->i_sb, lb); inode = udf_iget(dir->i_sb, lb);
if (!inode) if (!inode) {
{
unlock_kernel(); unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
} } else
else #endif /* UDF_RECOVERY */
#endif /* UDF_RECOVERY */
if (udf_find_entry(dir, dentry, &fibh, &cfi)) if (udf_find_entry(dir, dentry, &fibh, &cfi)) {
{
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
if ( !inode ) if (!inode) {
{
unlock_kernel(); unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
...@@ -337,13 +332,13 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) ...@@ -337,13 +332,13 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
return NULL; return NULL;
} }
static struct fileIdentDesc * static struct fileIdentDesc *udf_add_entry(struct inode *dir,
udf_add_entry(struct inode *dir, struct dentry *dentry, struct dentry *dentry,
struct udf_fileident_bh *fibh, struct udf_fileident_bh *fibh,
struct fileIdentDesc *cfi, int *err) struct fileIdentDesc *cfi, int *err)
{ {
struct super_block *sb; struct super_block *sb;
struct fileIdentDesc *fi=NULL; struct fileIdentDesc *fi = NULL;
char name[UDF_NAME_LEN], fname[UDF_NAME_LEN]; char name[UDF_NAME_LEN], fname[UDF_NAME_LEN];
int namelen; int namelen;
loff_t f_pos; loff_t f_pos;
...@@ -357,50 +352,47 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -357,50 +352,47 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen; uint32_t elen;
sector_t offset; sector_t offset;
struct extent_position epos = { NULL, 0, { 0, 0 }}; struct extent_position epos = { NULL, 0, {0, 0} };
sb = dir->i_sb; sb = dir->i_sb;
if (dentry) if (dentry) {
{ if (!dentry->d_name.len) {
if (!dentry->d_name.len)
{
*err = -EINVAL; *err = -EINVAL;
return NULL; return NULL;
} }
if ( !(namelen = udf_put_filename(sb, dentry->d_name.name, name, dentry->d_name.len))) if (!
{ (namelen =
udf_put_filename(sb, dentry->d_name.name, name,
dentry->d_name.len))) {
*err = -ENAMETOOLONG; *err = -ENAMETOOLONG;
return NULL; return NULL;
} }
} } else
else
namelen = 0; namelen = 0;
nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3; nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
f_pos = (udf_ext0_offset(dir) >> 2); f_pos = (udf_ext0_offset(dir) >> 2);
fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; fibh->soffset = fibh->eoffset =
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL; fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
&epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) &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 ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
epos.offset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
epos.offset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} } else
else
offset = 0; offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) {
{
brelse(epos.bh); brelse(epos.bh);
*err = -EIO; *err = -EIO;
return NULL; return NULL;
...@@ -408,21 +400,18 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -408,21 +400,18 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
block = UDF_I_LOCATION(dir).logicalBlockNum; block = UDF_I_LOCATION(dir).logicalBlockNum;
} } else {
else
{
block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0); block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0);
fibh->sbh = fibh->ebh = NULL; fibh->sbh = fibh->ebh = NULL;
fibh->soffset = fibh->eoffset = sb->s_blocksize; fibh->soffset = fibh->eoffset = sb->s_blocksize;
goto add; goto add;
} }
while ( (f_pos < size) ) while ((f_pos < size)) {
{ fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset); &elen, &offset);
if (!fi) if (!fi) {
{
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
brelse(fibh->ebh); brelse(fibh->ebh);
brelse(fibh->sbh); brelse(fibh->sbh);
...@@ -436,36 +425,38 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -436,36 +425,38 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (fibh->sbh == fibh->ebh) if (fibh->sbh == fibh->ebh)
nameptr = fi->fileIdent + liu; nameptr = fi->fileIdent + liu;
else else {
{
int poffset; /* Unpaded ending offset */ int poffset; /* Unpaded ending offset */
poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi; poffset =
fibh->soffset + sizeof(struct fileIdentDesc) + liu +
lfi;
if (poffset >= lfi) if (poffset >= lfi)
nameptr = (char *)(fibh->ebh->b_data + poffset - lfi); nameptr =
else (char *)(fibh->ebh->b_data + poffset - lfi);
{ else {
nameptr = fname; nameptr = fname;
memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); memcpy(nameptr, fi->fileIdent + liu,
memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset); lfi - poffset);
memcpy(nameptr + lfi - poffset,
fibh->ebh->b_data, poffset);
} }
} }
if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 ) if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
{ if (((sizeof(struct fileIdentDesc) + liu + lfi +
if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) 3) & ~3) == nfidlen) {
{
brelse(epos.bh); brelse(epos.bh);
cfi->descTag.tagSerialNum = cpu_to_le16(1); cfi->descTag.tagSerialNum = cpu_to_le16(1);
cfi->fileVersionNum = cpu_to_le16(1); cfi->fileVersionNum = cpu_to_le16(1);
cfi->fileCharacteristics = 0; cfi->fileCharacteristics = 0;
cfi->lengthFileIdent = namelen; cfi->lengthFileIdent = namelen;
cfi->lengthOfImpUse = cpu_to_le16(0); cfi->lengthOfImpUse = cpu_to_le16(0);
if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) if (!udf_write_fi
(dir, cfi, fi, fibh, NULL, name))
return fi; return fi;
else else {
{
*err = -EIO; *err = -EIO;
return NULL; return NULL;
} }
...@@ -476,8 +467,8 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -476,8 +467,8 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
continue; continue;
if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) && if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) &&
udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) udf_match(flen, fname, dentry->d_name.len,
{ dentry->d_name.name)) {
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
brelse(fibh->ebh); brelse(fibh->ebh);
brelse(fibh->sbh); brelse(fibh->sbh);
...@@ -487,12 +478,11 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -487,12 +478,11 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
} }
} }
add: add:
f_pos += nfidlen; f_pos += nfidlen;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB && if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
sb->s_blocksize - fibh->eoffset < nfidlen) sb->s_blocksize - fibh->eoffset < nfidlen) {
{
brelse(epos.bh); brelse(epos.bh);
epos.bh = NULL; epos.bh = NULL;
fibh->soffset -= udf_ext0_offset(dir); fibh->soffset -= udf_ext0_offset(dir);
...@@ -501,11 +491,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -501,11 +491,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
brelse(fibh->ebh); brelse(fibh->ebh);
brelse(fibh->sbh); brelse(fibh->sbh);
if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) if (!
(fibh->sbh = fibh->ebh =
udf_expand_dir_adinicb(dir, &block, err)))
return NULL; return NULL;
epos.block = UDF_I_LOCATION(dir); epos.block = UDF_I_LOCATION(dir);
eloc.logicalBlockNum = block; eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; eloc.partitionReferenceNum =
UDF_I_LOCATION(dir).partitionReferenceNum;
elen = dir->i_sb->s_blocksize; elen = dir->i_sb->s_blocksize;
epos.offset = udf_file_entry_alloc_offset(dir); epos.offset = udf_file_entry_alloc_offset(dir);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
...@@ -514,89 +507,84 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -514,89 +507,84 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
epos.offset += sizeof(long_ad); epos.offset += sizeof(long_ad);
} }
if (sb->s_blocksize - fibh->eoffset >= nfidlen) if (sb->s_blocksize - fibh->eoffset >= nfidlen) {
{
fibh->soffset = fibh->eoffset; fibh->soffset = fibh->eoffset;
fibh->eoffset += nfidlen; fibh->eoffset += nfidlen;
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh) {
{
brelse(fibh->sbh); brelse(fibh->sbh);
fibh->sbh = fibh->ebh; fibh->sbh = fibh->ebh;
} }
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
{
block = UDF_I_LOCATION(dir).logicalBlockNum; block = UDF_I_LOCATION(dir).logicalBlockNum;
fi = (struct fileIdentDesc *)(UDF_I_DATA(dir) + fibh->soffset - udf_ext0_offset(dir) + UDF_I_LENEATTR(dir)); fi = (struct fileIdentDesc *)(UDF_I_DATA(dir) +
} fibh->soffset -
else udf_ext0_offset(dir) +
{ UDF_I_LENEATTR(dir));
} else {
block = eloc.logicalBlockNum + ((elen - 1) >> block = eloc.logicalBlockNum + ((elen - 1) >>
dir->i_sb->s_blocksize_bits); dir->i_sb->
fi = (struct fileIdentDesc *)(fibh->sbh->b_data + fibh->soffset); s_blocksize_bits);
fi = (struct fileIdentDesc *)(fibh->sbh->b_data +
fibh->soffset);
} }
} } else {
else
{
fibh->soffset = fibh->eoffset - sb->s_blocksize; fibh->soffset = fibh->eoffset - sb->s_blocksize;
fibh->eoffset += nfidlen - sb->s_blocksize; fibh->eoffset += nfidlen - sb->s_blocksize;
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh) {
{
brelse(fibh->sbh); brelse(fibh->sbh);
fibh->sbh = fibh->ebh; fibh->sbh = fibh->ebh;
} }
block = eloc.logicalBlockNum + ((elen - 1) >> block = eloc.logicalBlockNum + ((elen - 1) >>
dir->i_sb->s_blocksize_bits); dir->i_sb->s_blocksize_bits);
if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err))) if (!
{ (fibh->ebh =
udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
1, err))) {
brelse(epos.bh); brelse(epos.bh);
brelse(fibh->sbh); brelse(fibh->sbh);
return NULL; return NULL;
} }
if (!(fibh->soffset)) if (!(fibh->soffset)) {
{
if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
(EXT_RECORDED_ALLOCATED >> 30)) (EXT_RECORDED_ALLOCATED >> 30)) {
{
block = eloc.logicalBlockNum + ((elen - 1) >> block = eloc.logicalBlockNum + ((elen - 1) >>
dir->i_sb->s_blocksize_bits); dir->i_sb->
} s_blocksize_bits);
else } else
block ++; block++;
brelse(fibh->sbh); brelse(fibh->sbh);
fibh->sbh = fibh->ebh; fibh->sbh = fibh->ebh;
fi = (struct fileIdentDesc *)(fibh->sbh->b_data); fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
} } else {
else
{
fi = (struct fileIdentDesc *) fi = (struct fileIdentDesc *)
(fibh->sbh->b_data + sb->s_blocksize + fibh->soffset); (fibh->sbh->b_data + sb->s_blocksize +
fibh->soffset);
} }
} }
memset(cfi, 0, sizeof(struct fileIdentDesc)); memset(cfi, 0, sizeof(struct fileIdentDesc));
if (UDF_SB_UDFREV(sb) >= 0x0200) if (UDF_SB_UDFREV(sb) >= 0x0200)
udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, sizeof(tag)); udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block,
sizeof(tag));
else else
udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, sizeof(tag)); udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block,
sizeof(tag));
cfi->fileVersionNum = cpu_to_le16(1); cfi->fileVersionNum = cpu_to_le16(1);
cfi->lengthFileIdent = namelen; cfi->lengthFileIdent = namelen;
cfi->lengthOfImpUse = cpu_to_le16(0); cfi->lengthOfImpUse = cpu_to_le16(0);
if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
{
brelse(epos.bh); brelse(epos.bh);
dir->i_size += nfidlen; dir->i_size += nfidlen;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(dir) += nfidlen; UDF_I_LENALLOC(dir) += nfidlen;
mark_inode_dirty(dir); mark_inode_dirty(dir);
return fi; return fi;
} } else {
else
{
brelse(epos.bh); brelse(epos.bh);
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
brelse(fibh->ebh); brelse(fibh->ebh);
...@@ -607,7 +595,8 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -607,7 +595,8 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
} }
static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
struct udf_fileident_bh *fibh, struct fileIdentDesc *cfi) struct udf_fileident_bh *fibh,
struct fileIdentDesc *cfi)
{ {
cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED; cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
...@@ -615,7 +604,8 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, ...@@ -615,7 +604,8 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
} }
static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
struct nameidata *nd)
{ {
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct inode *inode; struct inode *inode;
...@@ -624,8 +614,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct ...@@ -624,8 +614,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct
lock_kernel(); lock_kernel();
inode = udf_new_inode(dir, mode, &err); inode = udf_new_inode(dir, mode, &err);
if (!inode) if (!inode) {
{
unlock_kernel(); unlock_kernel();
return err; return err;
} }
...@@ -639,9 +628,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct ...@@ -639,9 +628,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct
inode->i_mode = mode; inode->i_mode = mode;
mark_inode_dirty(inode); mark_inode_dirty(inode);
if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
{ inode->i_nlink--;
inode->i_nlink --;
mark_inode_dirty(inode); mark_inode_dirty(inode);
iput(inode); iput(inode);
unlock_kernel(); unlock_kernel();
...@@ -649,11 +637,10 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct ...@@ -649,11 +637,10 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct
} }
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
{
mark_inode_dirty(dir); mark_inode_dirty(dir);
} }
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
...@@ -664,9 +651,10 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct ...@@ -664,9 +651,10 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct
return 0; return 0;
} }
static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev) static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
dev_t rdev)
{ {
struct inode * inode; struct inode *inode;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct fileIdentDesc cfi, *fi; struct fileIdentDesc cfi, *fi;
int err; int err;
...@@ -682,9 +670,8 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t ...@@ -682,9 +670,8 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t
inode->i_uid = current->fsuid; inode->i_uid = current->fsuid;
init_special_inode(inode, mode, rdev); init_special_inode(inode, mode, rdev);
if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
{ inode->i_nlink--;
inode->i_nlink --;
mark_inode_dirty(inode); mark_inode_dirty(inode);
iput(inode); iput(inode);
unlock_kernel(); unlock_kernel();
...@@ -692,11 +679,10 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t ...@@ -692,11 +679,10 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t
} }
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
{
mark_inode_dirty(dir); mark_inode_dirty(dir);
} }
mark_inode_dirty(inode); mark_inode_dirty(inode);
...@@ -706,21 +692,21 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t ...@@ -706,21 +692,21 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t
brelse(fibh.sbh); brelse(fibh.sbh);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
err = 0; err = 0;
out: out:
unlock_kernel(); unlock_kernel();
return err; return err;
} }
static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{ {
struct inode * inode; struct inode *inode;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct fileIdentDesc cfi, *fi; struct fileIdentDesc cfi, *fi;
int err; int err;
lock_kernel(); lock_kernel();
err = -EMLINK; err = -EMLINK;
if (dir->i_nlink >= (256<<sizeof(dir->i_nlink))-1) if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1)
goto out; goto out;
err = -EIO; err = -EIO;
...@@ -730,8 +716,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) ...@@ -730,8 +716,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
inode->i_op = &udf_dir_inode_operations; inode->i_op = &udf_dir_inode_operations;
inode->i_fop = &udf_dir_operations; inode->i_fop = &udf_dir_operations;
if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err))) if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err))) {
{
inode->i_nlink--; inode->i_nlink--;
mark_inode_dirty(inode); mark_inode_dirty(inode);
iput(inode); iput(inode);
...@@ -740,9 +725,10 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) ...@@ -740,9 +725,10 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
inode->i_nlink = 2; inode->i_nlink = 2;
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir)); cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir));
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL); cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; cfi.fileCharacteristics =
FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
brelse(fibh.sbh); brelse(fibh.sbh);
inode->i_mode = S_IFDIR | mode; inode->i_mode = S_IFDIR | mode;
...@@ -750,8 +736,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) ...@@ -750,8 +736,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
inode->i_mode |= S_ISGID; inode->i_mode |= S_ISGID;
mark_inode_dirty(inode); mark_inode_dirty(inode);
if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
{
inode->i_nlink = 0; inode->i_nlink = 0;
mark_inode_dirty(inode); mark_inode_dirty(inode);
iput(inode); iput(inode);
...@@ -759,8 +744,8 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) ...@@ -759,8 +744,8 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
} }
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
inc_nlink(dir); inc_nlink(dir);
...@@ -770,7 +755,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) ...@@ -770,7 +755,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
err = 0; err = 0;
out: out:
unlock_kernel(); unlock_kernel();
return err; return err;
} }
...@@ -785,47 +770,41 @@ static int empty_dir(struct inode *dir) ...@@ -785,47 +770,41 @@ static int empty_dir(struct inode *dir)
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen; uint32_t elen;
sector_t offset; sector_t offset;
struct extent_position epos = { NULL, 0, { 0, 0}}; struct extent_position epos = { NULL, 0, {0, 0} };
f_pos = (udf_ext0_offset(dir) >> 2); f_pos = (udf_ext0_offset(dir) >> 2);
fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; fibh.soffset = fibh.eoffset =
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL; fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
&epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) &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 ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
epos.offset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
epos.offset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} } else
else
offset = 0; offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) {
{
brelse(epos.bh); brelse(epos.bh);
return 0; return 0;
} }
} } else {
else
{
brelse(epos.bh); brelse(epos.bh);
return 0; return 0;
} }
while ((f_pos < size)) {
fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc,
&elen, &offset);
while ( (f_pos < size) ) if (!fi) {
{
fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
...@@ -833,8 +812,8 @@ static int empty_dir(struct inode *dir) ...@@ -833,8 +812,8 @@ static int empty_dir(struct inode *dir)
return 0; return 0;
} }
if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) if (cfi.lengthFileIdent
{ && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) {
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
...@@ -849,10 +828,10 @@ static int empty_dir(struct inode *dir) ...@@ -849,10 +828,10 @@ static int empty_dir(struct inode *dir)
return 1; return 1;
} }
static int udf_rmdir(struct inode * dir, struct dentry * dentry) static int udf_rmdir(struct inode *dir, struct dentry *dentry)
{ {
int retval; int retval;
struct inode * inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct fileIdentDesc *fi, cfi; struct fileIdentDesc *fi, cfi;
kernel_lb_addr tloc; kernel_lb_addr tloc;
...@@ -875,27 +854,28 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) ...@@ -875,27 +854,28 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry)
goto end_rmdir; goto end_rmdir;
if (inode->i_nlink != 2) if (inode->i_nlink != 2)
udf_warning(inode->i_sb, "udf_rmdir", udf_warning(inode->i_sb, "udf_rmdir",
"empty directory has nlink != 2 (%d)", "empty directory has nlink != 2 (%d)",
inode->i_nlink); inode->i_nlink);
clear_nlink(inode); clear_nlink(inode);
inode->i_size = 0; inode->i_size = 0;
inode_dec_link_count(dir); inode_dec_link_count(dir);
inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); inode->i_ctime = dir->i_ctime = dir->i_mtime =
current_fs_time(dir->i_sb);
mark_inode_dirty(dir); mark_inode_dirty(dir);
end_rmdir: end_rmdir:
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
out: out:
unlock_kernel(); unlock_kernel();
return retval; return retval;
} }
static int udf_unlink(struct inode * dir, struct dentry * dentry) static int udf_unlink(struct inode *dir, struct dentry *dentry)
{ {
int retval; int retval;
struct inode * inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct fileIdentDesc *fi; struct fileIdentDesc *fi;
struct fileIdentDesc cfi; struct fileIdentDesc cfi;
...@@ -912,10 +892,9 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry) ...@@ -912,10 +892,9 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry)
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; goto end_unlink;
if (!inode->i_nlink) if (!inode->i_nlink) {
{
udf_debug("Deleting nonexistent file (%lu), %d\n", udf_debug("Deleting nonexistent file (%lu), %d\n",
inode->i_ino, inode->i_nlink); inode->i_ino, inode->i_nlink);
inode->i_nlink = 1; inode->i_nlink = 1;
} }
retval = udf_delete_entry(dir, fi, &fibh, &cfi); retval = udf_delete_entry(dir, fi, &fibh, &cfi);
...@@ -927,22 +906,23 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry) ...@@ -927,22 +906,23 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry)
inode->i_ctime = dir->i_ctime; inode->i_ctime = dir->i_ctime;
retval = 0; retval = 0;
end_unlink: end_unlink:
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh); brelse(fibh.ebh);
brelse(fibh.sbh); brelse(fibh.sbh);
out: out:
unlock_kernel(); unlock_kernel();
return retval; return retval;
} }
static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname) static int udf_symlink(struct inode *dir, struct dentry *dentry,
const char *symname)
{ {
struct inode * inode; struct inode *inode;
struct pathComponent *pc; struct pathComponent *pc;
char *compstart; char *compstart;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct extent_position epos = { NULL, 0, {0, 0}}; struct extent_position epos = { NULL, 0, {0, 0} };
int eoffset, elen = 0; int eoffset, elen = 0;
struct fileIdentDesc *fi; struct fileIdentDesc *fi;
struct fileIdentDesc cfi; struct fileIdentDesc cfi;
...@@ -960,28 +940,31 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -960,28 +940,31 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
inode->i_data.a_ops = &udf_symlink_aops; inode->i_data.a_ops = &udf_symlink_aops;
inode->i_op = &page_symlink_inode_operations; inode->i_op = &page_symlink_inode_operations;
if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) {
{
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen; uint32_t elen;
block = udf_new_block(inode->i_sb, inode, block = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum, UDF_I_LOCATION(inode).
UDF_I_LOCATION(inode).logicalBlockNum, &err); partitionReferenceNum,
UDF_I_LOCATION(inode).logicalBlockNum,
&err);
if (!block) if (!block)
goto out_no_entry; goto out_no_entry;
epos.block = UDF_I_LOCATION(inode); epos.block = UDF_I_LOCATION(inode);
epos.offset = udf_file_entry_alloc_offset(inode); epos.offset = udf_file_entry_alloc_offset(inode);
epos.bh = NULL; epos.bh = NULL;
eloc.logicalBlockNum = block; eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; eloc.partitionReferenceNum =
UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_sb->s_blocksize; elen = inode->i_sb->s_blocksize;
UDF_I_LENEXTENTS(inode) = elen; UDF_I_LENEXTENTS(inode) = elen;
udf_add_aext(inode, &epos, eloc, elen, 0); udf_add_aext(inode, &epos, eloc, elen, 0);
brelse(epos.bh); brelse(epos.bh);
block = udf_get_pblock(inode->i_sb, block, block = udf_get_pblock(inode->i_sb, block,
UDF_I_LOCATION(inode).partitionReferenceNum, 0); UDF_I_LOCATION(inode).
partitionReferenceNum, 0);
epos.bh = udf_tread(inode->i_sb, block); epos.bh = udf_tread(inode->i_sb, block);
lock_buffer(epos.bh); lock_buffer(epos.bh);
memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
...@@ -989,17 +972,14 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -989,17 +972,14 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
unlock_buffer(epos.bh); unlock_buffer(epos.bh);
mark_buffer_dirty_inode(epos.bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
ea = epos.bh->b_data + udf_ext0_offset(inode); ea = epos.bh->b_data + udf_ext0_offset(inode);
} } else
else
ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode); eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
pc = (struct pathComponent *)ea; pc = (struct pathComponent *)ea;
if (*symname == '/') if (*symname == '/') {
{ do {
do
{
symname++; symname++;
} while (*symname == '/'); } while (*symname == '/');
...@@ -1012,8 +992,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -1012,8 +992,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
err = -ENAMETOOLONG; err = -ENAMETOOLONG;
while (*symname) while (*symname) {
{
if (elen + sizeof(struct pathComponent) > eoffset) if (elen + sizeof(struct pathComponent) > eoffset)
goto out_no_entry; goto out_no_entry;
...@@ -1021,28 +1000,30 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -1021,28 +1000,30 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
compstart = (char *)symname; compstart = (char *)symname;
do do {
{
symname++; symname++;
} while (*symname && *symname != '/'); } while (*symname && *symname != '/');
pc->componentType = 5; pc->componentType = 5;
pc->lengthComponentIdent = 0; pc->lengthComponentIdent = 0;
pc->componentFileVersionNum = 0; pc->componentFileVersionNum = 0;
if (compstart[0] == '.') if (compstart[0] == '.') {
{ if ((symname - compstart) == 1)
if ((symname-compstart) == 1)
pc->componentType = 4; pc->componentType = 4;
else if ((symname-compstart) == 2 && compstart[1] == '.') else if ((symname - compstart) == 2
&& compstart[1] == '.')
pc->componentType = 3; pc->componentType = 3;
} }
if (pc->componentType == 5) if (pc->componentType == 5) {
{ if (!
if ( !(namelen = udf_put_filename(inode->i_sb, compstart, name, symname-compstart))) (namelen =
udf_put_filename(inode->i_sb, compstart, name,
symname - compstart)))
goto out_no_entry; goto out_no_entry;
if (elen + sizeof(struct pathComponent) + namelen > eoffset) if (elen + sizeof(struct pathComponent) + namelen >
eoffset)
goto out_no_entry; goto out_no_entry;
else else
pc->lengthComponentIdent = namelen; pc->lengthComponentIdent = namelen;
...@@ -1052,10 +1033,8 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -1052,10 +1033,8 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
if (*symname) if (*symname) {
{ do {
do
{
symname++; symname++;
} while (*symname == '/'); } while (*symname == '/');
} }
...@@ -1071,22 +1050,22 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -1071,22 +1050,22 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
goto out_no_entry; goto out_no_entry;
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
if (UDF_SB_LVIDBH(inode->i_sb)) if (UDF_SB_LVIDBH(inode->i_sb)) {
{
struct logicalVolHeaderDesc *lvhd; struct logicalVolHeaderDesc *lvhd;
uint64_t uniqueID; uint64_t uniqueID;
lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse); lvhd =
(struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->
logicalVolContentsUse);
uniqueID = le64_to_cpu(lvhd->uniqueID); uniqueID = le64_to_cpu(lvhd->uniqueID);
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
if (!(++uniqueID & 0x00000000FFFFFFFFUL)) if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16; uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID); lvhd->uniqueID = cpu_to_le64(uniqueID);
mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb)); mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
} }
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
{
mark_inode_dirty(dir); mark_inode_dirty(dir);
} }
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
...@@ -1095,18 +1074,18 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -1095,18 +1074,18 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
err = 0; err = 0;
out: out:
unlock_kernel(); unlock_kernel();
return err; return err;
out_no_entry: out_no_entry:
inode_dec_link_count(inode); inode_dec_link_count(inode);
iput(inode); iput(inode);
goto out; goto out;
} }
static int udf_link(struct dentry * old_dentry, struct inode * dir, static int udf_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *dentry) struct dentry *dentry)
{ {
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
...@@ -1114,35 +1093,33 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir, ...@@ -1114,35 +1093,33 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
int err; int err;
lock_kernel(); lock_kernel();
if (inode->i_nlink >= (256<<sizeof(inode->i_nlink))-1) if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) {
{
unlock_kernel(); unlock_kernel();
return -EMLINK; return -EMLINK;
} }
if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) {
{
unlock_kernel(); unlock_kernel();
return err; return err;
} }
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
if (UDF_SB_LVIDBH(inode->i_sb)) if (UDF_SB_LVIDBH(inode->i_sb)) {
{
struct logicalVolHeaderDesc *lvhd; struct logicalVolHeaderDesc *lvhd;
uint64_t uniqueID; uint64_t uniqueID;
lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse); lvhd =
(struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->
logicalVolContentsUse);
uniqueID = le64_to_cpu(lvhd->uniqueID); uniqueID = le64_to_cpu(lvhd->uniqueID);
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
if (!(++uniqueID & 0x00000000FFFFFFFFUL)) if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16; uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID); lvhd->uniqueID = cpu_to_le64(uniqueID);
mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb)); mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
} }
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
{
mark_inode_dirty(dir); mark_inode_dirty(dir);
} }
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
...@@ -1160,80 +1137,80 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir, ...@@ -1160,80 +1137,80 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
/* Anybody can rename anything with this: the permission checks are left to the /* Anybody can rename anything with this: the permission checks are left to the
* higher-level routines. * higher-level routines.
*/ */
static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode * new_dir, struct dentry * new_dentry) struct inode *new_dir, struct dentry *new_dentry)
{ {
struct inode * old_inode = old_dentry->d_inode; struct inode *old_inode = old_dentry->d_inode;
struct inode * new_inode = new_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode;
struct udf_fileident_bh ofibh, nfibh; struct udf_fileident_bh ofibh, nfibh;
struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi; struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi =
NULL, ocfi, ncfi;
struct buffer_head *dir_bh = NULL; struct buffer_head *dir_bh = NULL;
int retval = -ENOENT; int retval = -ENOENT;
kernel_lb_addr tloc; kernel_lb_addr tloc;
lock_kernel(); lock_kernel();
if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) {
{
if (ofibh.sbh != ofibh.ebh) if (ofibh.sbh != ofibh.ebh)
brelse(ofibh.ebh); brelse(ofibh.ebh);
brelse(ofibh.sbh); brelse(ofibh.sbh);
} }
tloc = lelb_to_cpu(ocfi.icb.extLocation); 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) != old_inode->i_ino)
goto end_rename; goto end_rename;
nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi); nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
if (nfi) if (nfi) {
{ if (!new_inode) {
if (!new_inode)
{
if (nfibh.sbh != nfibh.ebh) if (nfibh.sbh != nfibh.ebh)
brelse(nfibh.ebh); brelse(nfibh.ebh);
brelse(nfibh.sbh); brelse(nfibh.sbh);
nfi = NULL; nfi = NULL;
} }
} }
if (S_ISDIR(old_inode->i_mode)) if (S_ISDIR(old_inode->i_mode)) {
{
uint32_t offset = udf_ext0_offset(old_inode); uint32_t offset = udf_ext0_offset(old_inode);
if (new_inode) if (new_inode) {
{
retval = -ENOTEMPTY; retval = -ENOTEMPTY;
if (!empty_dir(new_inode)) if (!empty_dir(new_inode))
goto end_rename; goto end_rename;
} }
retval = -EIO; retval = -EIO;
if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) {
{
dir_fi = udf_get_fileident(UDF_I_DATA(old_inode) - dir_fi = udf_get_fileident(UDF_I_DATA(old_inode) -
(UDF_I_EFE(old_inode) ? (UDF_I_EFE(old_inode) ?
sizeof(struct extendedFileEntry) : sizeof(struct
sizeof(struct fileEntry)), extendedFileEntry) :
old_inode->i_sb->s_blocksize, &offset); sizeof(struct fileEntry)),
} old_inode->i_sb->s_blocksize,
else &offset);
{ } else {
dir_bh = udf_bread(old_inode, 0, 0, &retval); dir_bh = udf_bread(old_inode, 0, 0, &retval);
if (!dir_bh) if (!dir_bh)
goto end_rename; goto end_rename;
dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset); dir_fi =
udf_get_fileident(dir_bh->b_data,
old_inode->i_sb->s_blocksize,
&offset);
} }
if (!dir_fi) if (!dir_fi)
goto end_rename; goto end_rename;
tloc = lelb_to_cpu(dir_fi->icb.extLocation); 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) != old_dir->i_ino)
goto end_rename; goto end_rename;
retval = -EMLINK; retval = -EMLINK;
if (!new_inode && new_dir->i_nlink >= (256<<sizeof(new_dir->i_nlink))-1) if (!new_inode
&& new_dir->i_nlink >=
(256 << sizeof(new_dir->i_nlink)) - 1)
goto end_rename; goto end_rename;
} }
if (!nfi) if (!nfi) {
{ nfi =
nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval); udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
if (!nfi) if (!nfi)
goto end_rename; goto end_rename;
} }
...@@ -1257,39 +1234,33 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, ...@@ -1257,39 +1234,33 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi); ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
udf_delete_entry(old_dir, ofi, &ofibh, &ocfi); udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
if (new_inode) if (new_inode) {
{
new_inode->i_ctime = current_fs_time(new_inode->i_sb); new_inode->i_ctime = current_fs_time(new_inode->i_sb);
inode_dec_link_count(new_inode); inode_dec_link_count(new_inode);
} }
old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
mark_inode_dirty(old_dir); mark_inode_dirty(old_dir);
if (dir_fi) if (dir_fi) {
{
dir_fi->icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(new_dir)); dir_fi->icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(new_dir));
udf_update_tag((char *)dir_fi, (sizeof(struct fileIdentDesc) + udf_update_tag((char *)dir_fi, (sizeof(struct fileIdentDesc) +
le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3); le16_to_cpu(dir_fi->
if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) lengthOfImpUse) +
{ 3) & ~3);
if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) {
mark_inode_dirty(old_inode); mark_inode_dirty(old_inode);
} } else
else
mark_buffer_dirty_inode(dir_bh, old_inode); mark_buffer_dirty_inode(dir_bh, old_inode);
inode_dec_link_count(old_dir); inode_dec_link_count(old_dir);
if (new_inode) if (new_inode) {
{
inode_dec_link_count(new_inode); inode_dec_link_count(new_inode);
} } else {
else
{
inc_nlink(new_dir); inc_nlink(new_dir);
mark_inode_dirty(new_dir); mark_inode_dirty(new_dir);
} }
} }
if (ofi) if (ofi) {
{
if (ofibh.sbh != ofibh.ebh) if (ofibh.sbh != ofibh.ebh)
brelse(ofibh.ebh); brelse(ofibh.ebh);
brelse(ofibh.sbh); brelse(ofibh.sbh);
...@@ -1297,10 +1268,9 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, ...@@ -1297,10 +1268,9 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
retval = 0; retval = 0;
end_rename: end_rename:
brelse(dir_bh); brelse(dir_bh);
if (nfi) if (nfi) {
{
if (nfibh.sbh != nfibh.ebh) if (nfibh.sbh != nfibh.ebh)
brelse(nfibh.ebh); brelse(nfibh.ebh);
brelse(nfibh.sbh); brelse(nfibh.sbh);
...@@ -1310,13 +1280,13 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, ...@@ -1310,13 +1280,13 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
} }
const struct inode_operations udf_dir_inode_operations = { const struct inode_operations udf_dir_inode_operations = {
.lookup = udf_lookup, .lookup = udf_lookup,
.create = udf_create, .create = udf_create,
.link = udf_link, .link = udf_link,
.unlink = udf_unlink, .unlink = udf_unlink,
.symlink = udf_symlink, .symlink = udf_symlink,
.mkdir = udf_mkdir, .mkdir = udf_mkdir,
.rmdir = udf_rmdir, .rmdir = udf_rmdir,
.mknod = udf_mknod, .mknod = udf_mknod,
.rename = udf_rename, .rename = udf_rename,
}; };
...@@ -65,153 +65,140 @@ ...@@ -65,153 +65,140 @@
#define IS_DF_HARD_WRITE_PROTECT 0x01 #define IS_DF_HARD_WRITE_PROTECT 0x01
#define IS_DF_SOFT_WRITE_PROTECT 0x02 #define IS_DF_SOFT_WRITE_PROTECT 0x02
struct UDFIdentSuffix struct UDFIdentSuffix {
{ __le16 UDFRevision;
__le16 UDFRevision; uint8_t OSClass;
uint8_t OSClass; uint8_t OSIdentifier;
uint8_t OSIdentifier; uint8_t reserved[4];
uint8_t reserved[4];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct impIdentSuffix struct impIdentSuffix {
{ uint8_t OSClass;
uint8_t OSClass; uint8_t OSIdentifier;
uint8_t OSIdentifier; uint8_t reserved[6];
uint8_t reserved[6];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct appIdentSuffix struct appIdentSuffix {
{ uint8_t impUse[8];
uint8_t impUse[8];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */ /* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */
/* Implementation Use (UDF 2.50 2.2.6.4) */ /* Implementation Use (UDF 2.50 2.2.6.4) */
struct logicalVolIntegrityDescImpUse struct logicalVolIntegrityDescImpUse {
{ regid impIdent;
regid impIdent; __le32 numFiles;
__le32 numFiles; __le32 numDirs;
__le32 numDirs; __le16 minUDFReadRev;
__le16 minUDFReadRev; __le16 minUDFWriteRev;
__le16 minUDFWriteRev; __le16 maxUDFWriteRev;
__le16 maxUDFWriteRev; uint8_t impUse[0];
uint8_t impUse[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */ /* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */
/* Implementation Use (UDF 2.50 2.2.7.2) */ /* Implementation Use (UDF 2.50 2.2.7.2) */
struct impUseVolDescImpUse struct impUseVolDescImpUse {
{ charspec LVICharset;
charspec LVICharset; dstring logicalVolIdent[128];
dstring logicalVolIdent[128]; dstring LVInfo1[36];
dstring LVInfo1[36]; dstring LVInfo2[36];
dstring LVInfo2[36]; dstring LVInfo3[36];
dstring LVInfo3[36]; regid impIdent;
regid impIdent; uint8_t impUse[128];
uint8_t impUse[128];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct udfPartitionMap2 struct udfPartitionMap2 {
{ uint8_t partitionMapType;
uint8_t partitionMapType; uint8_t partitionMapLength;
uint8_t partitionMapLength; uint8_t reserved1[2];
uint8_t reserved1[2]; regid partIdent;
regid partIdent; __le16 volSeqNum;
__le16 volSeqNum; __le16 partitionNum;
__le16 partitionNum;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Virtual Partition Map (UDF 2.50 2.2.8) */ /* Virtual Partition Map (UDF 2.50 2.2.8) */
struct virtualPartitionMap struct virtualPartitionMap {
{ uint8_t partitionMapType;
uint8_t partitionMapType; uint8_t partitionMapLength;
uint8_t partitionMapLength; uint8_t reserved1[2];
uint8_t reserved1[2]; regid partIdent;
regid partIdent; __le16 volSeqNum;
__le16 volSeqNum; __le16 partitionNum;
__le16 partitionNum; uint8_t reserved2[24];
uint8_t reserved2[24];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Sparable Partition Map (UDF 2.50 2.2.9) */ /* Sparable Partition Map (UDF 2.50 2.2.9) */
struct sparablePartitionMap struct sparablePartitionMap {
{ uint8_t partitionMapType;
uint8_t partitionMapType; uint8_t partitionMapLength;
uint8_t partitionMapLength; uint8_t reserved1[2];
uint8_t reserved1[2]; regid partIdent;
regid partIdent; __le16 volSeqNum;
__le16 volSeqNum; __le16 partitionNum;
__le16 partitionNum; __le16 packetLength;
__le16 packetLength; uint8_t numSparingTables;
uint8_t numSparingTables; uint8_t reserved2[1];
uint8_t reserved2[1]; __le32 sizeSparingTable;
__le32 sizeSparingTable; __le32 locSparingTable[4];
__le32 locSparingTable[4];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Metadata Partition Map (UDF 2.4.0 2.2.10) */ /* Metadata Partition Map (UDF 2.4.0 2.2.10) */
struct metadataPartitionMap struct metadataPartitionMap {
{ uint8_t partitionMapType;
uint8_t partitionMapType; uint8_t partitionMapLength;
uint8_t partitionMapLength; uint8_t reserved1[2];
uint8_t reserved1[2]; regid partIdent;
regid partIdent; __le16 volSeqNum;
__le16 volSeqNum; __le16 partitionNum;
__le16 partitionNum; __le32 metadataFileLoc;
__le32 metadataFileLoc; __le32 metadataMirrorFileLoc;
__le32 metadataMirrorFileLoc; __le32 metadataBitmapFileLoc;
__le32 metadataBitmapFileLoc; __le32 allocUnitSize;
__le32 allocUnitSize; __le16 alignUnitSize;
__le16 alignUnitSize; uint8_t flags;
uint8_t flags; uint8_t reserved2[5];
uint8_t reserved2[5];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Virtual Allocation Table (UDF 1.5 2.2.10) */ /* Virtual Allocation Table (UDF 1.5 2.2.10) */
struct virtualAllocationTable15 struct virtualAllocationTable15 {
{ __le32 VirtualSector[0];
__le32 VirtualSector[0]; regid vatIdent;
regid vatIdent; __le32 previousVATICBLoc;
__le32 previousVATICBLoc; } __attribute__ ((packed));
} __attribute__ ((packed));
#define ICBTAG_FILE_TYPE_VAT15 0x00U #define ICBTAG_FILE_TYPE_VAT15 0x00U
/* Virtual Allocation Table (UDF 2.50 2.2.11) */ /* Virtual Allocation Table (UDF 2.50 2.2.11) */
struct virtualAllocationTable20 struct virtualAllocationTable20 {
{ __le16 lengthHeader;
__le16 lengthHeader; __le16 lengthImpUse;
__le16 lengthImpUse; dstring logicalVolIdent[128];
dstring logicalVolIdent[128]; __le32 previousVATICBLoc;
__le32 previousVATICBLoc; __le32 numFiles;
__le32 numFiles; __le32 numDirs;
__le32 numDirs; __le16 minReadRevision;
__le16 minReadRevision; __le16 minWriteRevision;
__le16 minWriteRevision; __le16 maxWriteRevision;
__le16 maxWriteRevision; __le16 reserved;
__le16 reserved; uint8_t impUse[0];
uint8_t impUse[0]; __le32 vatEntry[0];
__le32 vatEntry[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define ICBTAG_FILE_TYPE_VAT20 0xF8U #define ICBTAG_FILE_TYPE_VAT20 0xF8U
/* Sparing Table (UDF 2.50 2.2.12) */ /* Sparing Table (UDF 2.50 2.2.12) */
struct sparingEntry struct sparingEntry {
{ __le32 origLocation;
__le32 origLocation; __le32 mappedLocation;
__le32 mappedLocation;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct sparingTable struct sparingTable {
{ tag descTag;
tag descTag; regid sparingIdent;
regid sparingIdent; __le16 reallocationTableLen;
__le16 reallocationTableLen; __le16 reserved;
__le16 reserved; __le32 sequenceNum;
__le32 sequenceNum;
struct sparingEntry struct sparingEntry
mapEntry[0]; mapEntry[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Metadata File (and Metadata Mirror File) (UDF 2.50 2.2.13.1) */ /* Metadata File (and Metadata Mirror File) (UDF 2.50 2.2.13.1) */
...@@ -220,10 +207,9 @@ struct sparingTable ...@@ -220,10 +207,9 @@ struct sparingTable
#define ICBTAG_FILE_TYPE_BITMAP 0xFC #define ICBTAG_FILE_TYPE_BITMAP 0xFC
/* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */ /* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */
struct allocDescImpUse struct allocDescImpUse {
{ __le16 flags;
__le16 flags; uint8_t impUse[4];
uint8_t impUse[4];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define AD_IU_EXT_ERASED 0x0001 #define AD_IU_EXT_ERASED 0x0001
...@@ -233,27 +219,24 @@ struct allocDescImpUse ...@@ -233,27 +219,24 @@ struct allocDescImpUse
/* Implementation Use Extended Attribute (UDF 2.50 3.3.4.5) */ /* Implementation Use Extended Attribute (UDF 2.50 3.3.4.5) */
/* FreeEASpace (UDF 2.50 3.3.4.5.1.1) */ /* FreeEASpace (UDF 2.50 3.3.4.5.1.1) */
struct freeEaSpace struct freeEaSpace {
{ __le16 headerChecksum;
__le16 headerChecksum; uint8_t freeEASpace[0];
uint8_t freeEASpace[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* DVD Copyright Management Information (UDF 2.50 3.3.4.5.1.2) */ /* DVD Copyright Management Information (UDF 2.50 3.3.4.5.1.2) */
struct DVDCopyrightImpUse struct DVDCopyrightImpUse {
{ __le16 headerChecksum;
__le16 headerChecksum; uint8_t CGMSInfo;
uint8_t CGMSInfo; uint8_t dataType;
uint8_t dataType; uint8_t protectionSystemInfo[4];
uint8_t protectionSystemInfo[4];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Application Use Extended Attribute (UDF 2.50 3.3.4.6) */ /* Application Use Extended Attribute (UDF 2.50 3.3.4.6) */
/* FreeAppEASpace (UDF 2.50 3.3.4.6.1) */ /* FreeAppEASpace (UDF 2.50 3.3.4.6.1) */
struct freeAppEASpace struct freeAppEASpace {
{ __le16 headerChecksum;
__le16 headerChecksum; uint8_t freeEASpace[0];
uint8_t freeEASpace[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
/* UDF Defined System Stream (UDF 2.50 3.3.7) */ /* UDF Defined System Stream (UDF 2.50 3.3.7) */
...@@ -293,4 +276,4 @@ struct freeAppEASpace ...@@ -293,4 +276,4 @@ struct freeAppEASpace
#define UDF_OS_ID_BEOS 0x00U #define UDF_OS_ID_BEOS 0x00U
#define UDF_OS_ID_WINCE 0x00U #define UDF_OS_ID_WINCE 0x00U
#endif /* _OSTA_UDF_H */ #endif /* _OSTA_UDF_H */
...@@ -28,106 +28,120 @@ ...@@ -28,106 +28,120 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
uint16_t partition, uint32_t offset)
{ {
if (partition >= UDF_SB_NUMPARTS(sb)) if (partition >= UDF_SB_NUMPARTS(sb)) {
{ udf_debug
udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n", ("block=%d, partition=%d, offset=%d: invalid partition\n",
block, partition, offset); block, partition, offset);
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
if (UDF_SB_PARTFUNC(sb, partition)) if (UDF_SB_PARTFUNC(sb, partition))
return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset); return UDF_SB_PARTFUNC(sb, partition) (sb, block, partition,
offset);
else else
return UDF_SB_PARTROOT(sb, partition) + block + offset; return UDF_SB_PARTROOT(sb, partition) + block + offset;
} }
uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
uint16_t partition, uint32_t offset)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
uint32_t newblock; uint32_t newblock;
uint32_t index; uint32_t index;
uint32_t loc; uint32_t loc;
index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t); index =
(sb->s_blocksize -
UDF_SB_TYPEVIRT(sb, partition).s_start_offset) / sizeof(uint32_t);
if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries) if (block > UDF_SB_TYPEVIRT(sb, partition).s_num_entries) {
{ udf_debug
udf_debug("Trying to access block beyond end of VAT (%d max %d)\n", ("Trying to access block beyond end of VAT (%d max %d)\n",
block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries); block, UDF_SB_TYPEVIRT(sb, partition).s_num_entries);
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
if (block >= index) if (block >= index) {
{
block -= index; block -= index;
newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t))); newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
index = block % (sb->s_blocksize / sizeof(uint32_t)); index = block % (sb->s_blocksize / sizeof(uint32_t));
} } else {
else
{
newblock = 0; newblock = 0;
index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block; index =
UDF_SB_TYPEVIRT(sb,
partition).s_start_offset /
sizeof(uint32_t) + block;
} }
loc = udf_block_map(UDF_SB_VAT(sb), newblock); loc = udf_block_map(UDF_SB_VAT(sb), newblock);
if (!(bh = sb_bread(sb, loc))) if (!(bh = sb_bread(sb, loc))) {
{
udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n", udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
sb, block, partition, loc, index); sb, block, partition, loc, index);
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
loc = le32_to_cpu(((__le32 *)bh->b_data)[index]); loc = le32_to_cpu(((__le32 *) bh->b_data)[index]);
brelse(bh); brelse(bh);
if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) {
{
udf_debug("recursive call to udf_get_pblock!\n"); udf_debug("recursive call to udf_get_pblock!\n");
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset); return udf_get_pblock(sb, loc,
UDF_I_LOCATION(UDF_SB_VAT(sb)).
partitionReferenceNum, offset);
} }
inline uint32_t udf_get_pblock_virt20(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) inline uint32_t udf_get_pblock_virt20(struct super_block * sb, uint32_t block,
uint16_t partition, uint32_t offset)
{ {
return udf_get_pblock_virt15(sb, block, partition, offset); return udf_get_pblock_virt15(sb, block, partition, offset);
} }
uint32_t udf_get_pblock_spar15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) uint32_t udf_get_pblock_spar15(struct super_block * sb, uint32_t block,
uint16_t partition, uint32_t offset)
{ {
int i; int i;
struct sparingTable *st = NULL; struct sparingTable *st = NULL;
uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1); uint32_t packet =
(block + offset) & ~(UDF_SB_TYPESPAR(sb, partition).s_packet_len -
1);
for (i=0; i<4; i++) for (i = 0; i < 4; i++) {
{ if (UDF_SB_TYPESPAR(sb, partition).s_spar_map[i] != NULL) {
if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL) st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,
{ partition).
st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data; s_spar_map[i]->b_data;
break; break;
} }
} }
if (st) if (st) {
{ for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) {
for (i=0; i<le16_to_cpu(st->reallocationTableLen); i++) if (le32_to_cpu(st->mapEntry[i].origLocation) >=
{ 0xFFFFFFF0)
if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0)
break; break;
else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet) else if (le32_to_cpu(st->mapEntry[i].origLocation) ==
{ packet) {
return le32_to_cpu(st->mapEntry[i].mappedLocation) + return le32_to_cpu(st->mapEntry[i].
((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1)); mappedLocation) + ((block +
} offset) &
else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet) (UDF_SB_TYPESPAR
(sb,
partition).
s_packet_len
- 1));
} else if (le32_to_cpu(st->mapEntry[i].origLocation) >
packet)
break; break;
} }
} }
return UDF_SB_PARTROOT(sb,partition) + block + offset; return UDF_SB_PARTROOT(sb, partition) + block + offset;
} }
int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
...@@ -138,19 +152,21 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) ...@@ -138,19 +152,21 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
uint32_t packet; uint32_t packet;
int i, j, k, l; int i, j, k, l;
for (i=0; i<UDF_SB_NUMPARTS(sb); i++) for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
{ if (old_block > UDF_SB_PARTROOT(sb, i) &&
if (old_block > UDF_SB_PARTROOT(sb,i) && old_block < UDF_SB_PARTROOT(sb, i) + UDF_SB_PARTLEN(sb, i))
old_block < UDF_SB_PARTROOT(sb,i) + UDF_SB_PARTLEN(sb,i))
{ {
sdata = &UDF_SB_TYPESPAR(sb,i); sdata = &UDF_SB_TYPESPAR(sb, i);
packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1); packet =
(old_block -
for (j=0; j<4; j++) UDF_SB_PARTROOT(sb,
{ i)) & ~(sdata->s_packet_len - 1);
if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
{ for (j = 0; j < 4; j++) {
st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; if (UDF_SB_TYPESPAR(sb, i).s_spar_map[j] !=
NULL) {
st = (struct sparingTable *)sdata->
s_spar_map[j]->b_data;
break; break;
} }
} }
...@@ -158,60 +174,123 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) ...@@ -158,60 +174,123 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
if (!st) if (!st)
return 1; return 1;
for (k=0; k<le16_to_cpu(st->reallocationTableLen); k++) for (k = 0; k < le16_to_cpu(st->reallocationTableLen);
{ k++) {
if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF) if (le32_to_cpu(st->mapEntry[k].origLocation) ==
{ 0xFFFFFFFF) {
for (; j<4; j++) for (; j < 4; j++) {
{ if (sdata->s_spar_map[j]) {
if (sdata->s_spar_map[j]) st = (struct
{ sparingTable *)
st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; sdata->
st->mapEntry[k].origLocation = cpu_to_le32(packet); s_spar_map[j]->
udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry)); b_data;
mark_buffer_dirty(sdata->s_spar_map[j]); st->mapEntry[k].
origLocation =
cpu_to_le32(packet);
udf_update_tag((char *)
st,
sizeof
(struct
sparingTable)
+
le16_to_cpu
(st->
reallocationTableLen)
*
sizeof
(struct
sparingEntry));
mark_buffer_dirty
(sdata->
s_spar_map[j]);
} }
} }
*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) + *new_block =
((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1)); le32_to_cpu(st->mapEntry[k].
mappedLocation) +
((old_block -
UDF_SB_PARTROOT(sb,
i)) & (sdata->
s_packet_len
- 1));
return 0; return 0;
} } else
else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet) if (le32_to_cpu
{ (st->mapEntry[k].origLocation) ==
*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) + packet) {
((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1)); *new_block =
le32_to_cpu(st->mapEntry[k].
mappedLocation) +
((old_block -
UDF_SB_PARTROOT(sb,
i)) & (sdata->
s_packet_len
- 1));
return 0; return 0;
} } else
else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet) if (le32_to_cpu
(st->mapEntry[k].origLocation) > packet)
break; break;
} }
for (l=k; l<le16_to_cpu(st->reallocationTableLen); l++) for (l = k; l < le16_to_cpu(st->reallocationTableLen);
{ l++) {
if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF) if (le32_to_cpu(st->mapEntry[l].origLocation) ==
{ 0xFFFFFFFF) {
for (; j<4; j++) for (; j < 4; j++) {
{ if (sdata->s_spar_map[j]) {
if (sdata->s_spar_map[j]) st = (struct
{ sparingTable *)
st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; sdata->
mapEntry = st->mapEntry[l]; s_spar_map[j]->
mapEntry.origLocation = cpu_to_le32(packet); b_data;
memmove(&st->mapEntry[k+1], &st->mapEntry[k], (l-k)*sizeof(struct sparingEntry)); mapEntry =
st->mapEntry[k] = mapEntry; st->mapEntry[l];
udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry)); mapEntry.origLocation =
mark_buffer_dirty(sdata->s_spar_map[j]); cpu_to_le32(packet);
memmove(&st->
mapEntry[k + 1],
&st->
mapEntry[k],
(l -
k) *
sizeof(struct
sparingEntry));
st->mapEntry[k] =
mapEntry;
udf_update_tag((char *)
st,
sizeof
(struct
sparingTable)
+
le16_to_cpu
(st->
reallocationTableLen)
*
sizeof
(struct
sparingEntry));
mark_buffer_dirty
(sdata->
s_spar_map[j]);
} }
} }
*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) + *new_block =
((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1)); le32_to_cpu(st->mapEntry[k].
mappedLocation) +
((old_block -
UDF_SB_PARTROOT(sb,
i)) & (sdata->
s_packet_len
- 1));
return 0; return 0;
} }
} }
return 1; return 1;
} }
} }
if (i == UDF_SB_NUMPARTS(sb)) if (i == UDF_SB_NUMPARTS(sb)) {
{
/* outside of partitions */ /* outside of partitions */
/* for now, fail =) */ /* for now, fail =) */
return 1; return 1;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* 12/20/98 find the free space bitmap (if it exists) * 12/20/98 find the free space bitmap (if it exists)
*/ */
#include "udfdecl.h" #include "udfdecl.h"
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -80,12 +80,15 @@ static int udf_remount_fs(struct super_block *, int *, char *); ...@@ -80,12 +80,15 @@ static int udf_remount_fs(struct super_block *, int *, char *);
static int udf_check_valid(struct super_block *, int, int); static int udf_check_valid(struct super_block *, int, int);
static int udf_vrs(struct super_block *sb, int silent); static int udf_vrs(struct super_block *sb, int silent);
static int udf_load_partition(struct super_block *, kernel_lb_addr *); static int udf_load_partition(struct super_block *, kernel_lb_addr *);
static int udf_load_logicalvol(struct super_block *, struct buffer_head *, kernel_lb_addr *); static int udf_load_logicalvol(struct super_block *, struct buffer_head *,
kernel_lb_addr *);
static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad);
static void udf_find_anchor(struct super_block *); static void udf_find_anchor(struct super_block *);
static int udf_find_fileset(struct super_block *, kernel_lb_addr *, kernel_lb_addr *); static int udf_find_fileset(struct super_block *, kernel_lb_addr *,
kernel_lb_addr *);
static void udf_load_pvoldesc(struct super_block *, struct buffer_head *); static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
static void udf_load_fileset(struct super_block *, struct buffer_head *, kernel_lb_addr *); static void udf_load_fileset(struct super_block *, struct buffer_head *,
kernel_lb_addr *);
static void udf_load_partdesc(struct super_block *, struct buffer_head *); static void udf_load_partdesc(struct super_block *, struct buffer_head *);
static void udf_open_lvid(struct super_block *); static void udf_open_lvid(struct super_block *);
static void udf_close_lvid(struct super_block *); static void udf_close_lvid(struct super_block *);
...@@ -94,25 +97,27 @@ static int udf_statfs(struct dentry *, struct kstatfs *); ...@@ -94,25 +97,27 @@ static int udf_statfs(struct dentry *, struct kstatfs *);
/* UDF filesystem type */ /* UDF filesystem type */
static int udf_get_sb(struct file_system_type *fs_type, static int udf_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data, struct vfsmount *mnt) int flags, const char *dev_name, void *data,
struct vfsmount *mnt)
{ {
return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt); return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt);
} }
static struct file_system_type udf_fstype = { static struct file_system_type udf_fstype = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "udf", .name = "udf",
.get_sb = udf_get_sb, .get_sb = udf_get_sb,
.kill_sb = kill_block_super, .kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV, .fs_flags = FS_REQUIRES_DEV,
}; };
static struct kmem_cache * udf_inode_cachep; static struct kmem_cache *udf_inode_cachep;
static struct inode *udf_alloc_inode(struct super_block *sb) static struct inode *udf_alloc_inode(struct super_block *sb)
{ {
struct udf_inode_info *ei; struct udf_inode_info *ei;
ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL); ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep,
GFP_KERNEL);
if (!ei) if (!ei)
return NULL; return NULL;
...@@ -130,9 +135,9 @@ static void udf_destroy_inode(struct inode *inode) ...@@ -130,9 +135,9 @@ static void udf_destroy_inode(struct inode *inode)
kmem_cache_free(udf_inode_cachep, UDF_I(inode)); kmem_cache_free(udf_inode_cachep, UDF_I(inode));
} }
static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
{ {
struct udf_inode_info *ei = (struct udf_inode_info *) foo; struct udf_inode_info *ei = (struct udf_inode_info *)foo;
ei->i_ext.i_data = NULL; ei->i_ext.i_data = NULL;
inode_init_once(&ei->vfs_inode); inode_init_once(&ei->vfs_inode);
...@@ -142,8 +147,8 @@ static int init_inodecache(void) ...@@ -142,8 +147,8 @@ static int init_inodecache(void)
{ {
udf_inode_cachep = kmem_cache_create("udf_inode_cache", udf_inode_cachep = kmem_cache_create("udf_inode_cache",
sizeof(struct udf_inode_info), sizeof(struct udf_inode_info),
0, (SLAB_RECLAIM_ACCOUNT| 0, (SLAB_RECLAIM_ACCOUNT |
SLAB_MEM_SPREAD), SLAB_MEM_SPREAD),
init_once, NULL); init_once, NULL);
if (udf_inode_cachep == NULL) if (udf_inode_cachep == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -157,19 +162,18 @@ static void destroy_inodecache(void) ...@@ -157,19 +162,18 @@ static void destroy_inodecache(void)
/* Superblock operations */ /* Superblock operations */
static const struct super_operations udf_sb_ops = { static const struct super_operations udf_sb_ops = {
.alloc_inode = udf_alloc_inode, .alloc_inode = udf_alloc_inode,
.destroy_inode = udf_destroy_inode, .destroy_inode = udf_destroy_inode,
.write_inode = udf_write_inode, .write_inode = udf_write_inode,
.delete_inode = udf_delete_inode, .delete_inode = udf_delete_inode,
.clear_inode = udf_clear_inode, .clear_inode = udf_clear_inode,
.put_super = udf_put_super, .put_super = udf_put_super,
.write_super = udf_write_super, .write_super = udf_write_super,
.statfs = udf_statfs, .statfs = udf_statfs,
.remount_fs = udf_remount_fs, .remount_fs = udf_remount_fs,
}; };
struct udf_options struct udf_options {
{
unsigned char novrs; unsigned char novrs;
unsigned int blocksize; unsigned int blocksize;
unsigned int session; unsigned int session;
...@@ -196,9 +200,9 @@ static int __init init_udf_fs(void) ...@@ -196,9 +200,9 @@ static int __init init_udf_fs(void)
if (err) if (err)
goto out; goto out;
return 0; return 0;
out: out:
destroy_inodecache(); destroy_inodecache();
out1: out1:
return err; return err;
} }
...@@ -209,7 +213,7 @@ static void __exit exit_udf_fs(void) ...@@ -209,7 +213,7 @@ static void __exit exit_udf_fs(void)
} }
module_init(init_udf_fs) module_init(init_udf_fs)
module_exit(exit_udf_fs) module_exit(exit_udf_fs)
/* /*
* udf_parse_options * udf_parse_options
...@@ -264,7 +268,6 @@ module_exit(exit_udf_fs) ...@@ -264,7 +268,6 @@ module_exit(exit_udf_fs)
* July 1, 1997 - Andrew E. Mileski * July 1, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
enum { enum {
Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete, Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad, Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
...@@ -303,8 +306,7 @@ static match_table_t tokens = { ...@@ -303,8 +306,7 @@ static match_table_t tokens = {
{Opt_err, NULL} {Opt_err, NULL}
}; };
static int static int udf_parse_options(char *options, struct udf_options *uopt)
udf_parse_options(char *options, struct udf_options *uopt)
{ {
char *p; char *p;
int option; int option;
...@@ -323,126 +325,123 @@ udf_parse_options(char *options, struct udf_options *uopt) ...@@ -323,126 +325,123 @@ udf_parse_options(char *options, struct udf_options *uopt)
if (!options) if (!options)
return 1; return 1;
while ((p = strsep(&options, ",")) != NULL) while ((p = strsep(&options, ",")) != NULL) {
{
substring_t args[MAX_OPT_ARGS]; substring_t args[MAX_OPT_ARGS];
int token; int token;
if (!*p) if (!*p)
continue; continue;
token = match_token(p, tokens, args); token = match_token(p, tokens, args);
switch (token) switch (token) {
{ case Opt_novrs:
case Opt_novrs: uopt->novrs = 1;
uopt->novrs = 1; case Opt_bs:
case Opt_bs: if (match_int(&args[0], &option))
if (match_int(&args[0], &option)) return 0;
return 0; uopt->blocksize = option;
uopt->blocksize = option; break;
break; case Opt_unhide:
case Opt_unhide: uopt->flags |= (1 << UDF_FLAG_UNHIDE);
uopt->flags |= (1 << UDF_FLAG_UNHIDE); break;
break; case Opt_undelete:
case Opt_undelete: uopt->flags |= (1 << UDF_FLAG_UNDELETE);
uopt->flags |= (1 << UDF_FLAG_UNDELETE); break;
break; case Opt_noadinicb:
case Opt_noadinicb: uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB); break;
break; case Opt_adinicb:
case Opt_adinicb: uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB); break;
break; case Opt_shortad:
case Opt_shortad: uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD); break;
break; case Opt_longad:
case Opt_longad: uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD); break;
break; case Opt_gid:
case Opt_gid: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->gid = option;
uopt->gid = option; break;
break; case Opt_uid:
case Opt_uid: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->uid = option;
uopt->uid = option; break;
break; case Opt_umask:
case Opt_umask: if (match_octal(args, &option))
if (match_octal(args, &option)) return 0;
return 0; uopt->umask = option;
uopt->umask = option; break;
break; case Opt_nostrict:
case Opt_nostrict: uopt->flags &= ~(1 << UDF_FLAG_STRICT);
uopt->flags &= ~(1 << UDF_FLAG_STRICT); break;
break; case Opt_session:
case Opt_session: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->session = option;
uopt->session = option; break;
break; case Opt_lastblock:
case Opt_lastblock: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->lastblock = option;
uopt->lastblock = option; break;
break; case Opt_anchor:
case Opt_anchor: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->anchor = option;
uopt->anchor = option; break;
break; case Opt_volume:
case Opt_volume: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->volume = option;
uopt->volume = option; break;
break; case Opt_partition:
case Opt_partition: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->partition = option;
uopt->partition = option; break;
break; case Opt_fileset:
case Opt_fileset: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->fileset = option;
uopt->fileset = option; break;
break; case Opt_rootdir:
case Opt_rootdir: if (match_int(args, &option))
if (match_int(args, &option)) return 0;
return 0; uopt->rootdir = option;
uopt->rootdir = option; break;
break; case Opt_utf8:
case Opt_utf8: uopt->flags |= (1 << UDF_FLAG_UTF8);
uopt->flags |= (1 << UDF_FLAG_UTF8); break;
break;
#ifdef CONFIG_UDF_NLS #ifdef CONFIG_UDF_NLS
case Opt_iocharset: case Opt_iocharset:
uopt->nls_map = load_nls(args[0].from); uopt->nls_map = load_nls(args[0].from);
uopt->flags |= (1 << UDF_FLAG_NLS_MAP); uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
break; break;
#endif #endif
case Opt_uignore: case Opt_uignore:
uopt->flags |= (1 << UDF_FLAG_UID_IGNORE); uopt->flags |= (1 << UDF_FLAG_UID_IGNORE);
break; break;
case Opt_uforget: case Opt_uforget:
uopt->flags |= (1 << UDF_FLAG_UID_FORGET); uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
break; break;
case Opt_gignore: case Opt_gignore:
uopt->flags |= (1 << UDF_FLAG_GID_IGNORE); uopt->flags |= (1 << UDF_FLAG_GID_IGNORE);
break; break;
case Opt_gforget: case Opt_gforget:
uopt->flags |= (1 << UDF_FLAG_GID_FORGET); uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
break; break;
default: default:
printk(KERN_ERR "udf: bad mount option \"%s\" " printk(KERN_ERR "udf: bad mount option \"%s\" "
"or missing value\n", p); "or missing value\n", p);
return 0; return 0;
} }
} }
return 1; return 1;
} }
void void udf_write_super(struct super_block *sb)
udf_write_super(struct super_block *sb)
{ {
lock_kernel(); lock_kernel();
if (!(sb->s_flags & MS_RDONLY)) if (!(sb->s_flags & MS_RDONLY))
...@@ -451,22 +450,21 @@ udf_write_super(struct super_block *sb) ...@@ -451,22 +450,21 @@ udf_write_super(struct super_block *sb)
unlock_kernel(); unlock_kernel();
} }
static int static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
udf_remount_fs(struct super_block *sb, int *flags, char *options)
{ {
struct udf_options uopt; struct udf_options uopt;
uopt.flags = UDF_SB(sb)->s_flags ; uopt.flags = UDF_SB(sb)->s_flags;
uopt.uid = UDF_SB(sb)->s_uid ; uopt.uid = UDF_SB(sb)->s_uid;
uopt.gid = UDF_SB(sb)->s_gid ; uopt.gid = UDF_SB(sb)->s_gid;
uopt.umask = UDF_SB(sb)->s_umask ; uopt.umask = UDF_SB(sb)->s_umask;
if ( !udf_parse_options(options, &uopt) ) if (!udf_parse_options(options, &uopt))
return -EINVAL; return -EINVAL;
UDF_SB(sb)->s_flags = uopt.flags; UDF_SB(sb)->s_flags = uopt.flags;
UDF_SB(sb)->s_uid = uopt.uid; UDF_SB(sb)->s_uid = uopt.uid;
UDF_SB(sb)->s_gid = uopt.gid; UDF_SB(sb)->s_gid = uopt.gid;
UDF_SB(sb)->s_umask = uopt.umask; UDF_SB(sb)->s_umask = uopt.umask;
if (UDF_SB_LVIDBH(sb)) { if (UDF_SB_LVIDBH(sb)) {
...@@ -512,8 +510,7 @@ udf_remount_fs(struct super_block *sb, int *flags, char *options) ...@@ -512,8 +510,7 @@ udf_remount_fs(struct super_block *sb, int *flags, char *options)
* July 1, 1997 - Andrew E. Mileski * July 1, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
static int static int udf_set_blocksize(struct super_block *sb, int bsize)
udf_set_blocksize(struct super_block *sb, int bsize)
{ {
if (!sb_min_blocksize(sb, bsize)) { if (!sb_min_blocksize(sb, bsize)) {
udf_debug("Bad block size (%d)\n", bsize); udf_debug("Bad block size (%d)\n", bsize);
...@@ -523,16 +520,15 @@ udf_set_blocksize(struct super_block *sb, int bsize) ...@@ -523,16 +520,15 @@ udf_set_blocksize(struct super_block *sb, int bsize)
return sb->s_blocksize; return sb->s_blocksize;
} }
static int static int udf_vrs(struct super_block *sb, int silent)
udf_vrs(struct super_block *sb, int silent)
{ {
struct volStructDesc *vsd = NULL; struct volStructDesc *vsd = NULL;
int sector = 32768; int sector = 32768;
int sectorsize; int sectorsize;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int iso9660=0; int iso9660 = 0;
int nsr02=0; int nsr02 = 0;
int nsr03=0; int nsr03 = 0;
/* Block size must be a multiple of 512 */ /* Block size must be a multiple of 512 */
if (sb->s_blocksize & 511) if (sb->s_blocksize & 511)
...@@ -546,10 +542,9 @@ udf_vrs(struct super_block *sb, int silent) ...@@ -546,10 +542,9 @@ udf_vrs(struct super_block *sb, int silent)
sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits); sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits);
udf_debug("Starting at sector %u (%ld byte sectors)\n", udf_debug("Starting at sector %u (%ld byte sectors)\n",
(sector >> sb->s_blocksize_bits), sb->s_blocksize); (sector >> sb->s_blocksize_bits), sb->s_blocksize);
/* Process the sequence (if applicable) */ /* Process the sequence (if applicable) */
for (;!nsr02 && !nsr03; sector += sectorsize) for (; !nsr02 && !nsr03; sector += sectorsize) {
{
/* Read a block */ /* Read a block */
bh = udf_tread(sb, sector >> sb->s_blocksize_bits); bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
if (!bh) if (!bh)
...@@ -557,52 +552,56 @@ udf_vrs(struct super_block *sb, int silent) ...@@ -557,52 +552,56 @@ udf_vrs(struct super_block *sb, int silent)
/* Look for ISO descriptors */ /* Look for ISO descriptors */
vsd = (struct volStructDesc *)(bh->b_data + vsd = (struct volStructDesc *)(bh->b_data +
(sector & (sb->s_blocksize - 1))); (sector &
(sb->s_blocksize - 1)));
if (vsd->stdIdent[0] == 0) if (vsd->stdIdent[0] == 0) {
{
brelse(bh); brelse(bh);
break; break;
} } else
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) if (!strncmp
{ (vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {
iso9660 = sector; iso9660 = sector;
switch (vsd->structType) switch (vsd->structType) {
{ case 0:
case 0: udf_debug("ISO9660 Boot Record found\n");
udf_debug("ISO9660 Boot Record found\n"); break;
break; case 1:
case 1: udf_debug
udf_debug("ISO9660 Primary Volume Descriptor found\n"); ("ISO9660 Primary Volume Descriptor found\n");
break; break;
case 2: case 2:
udf_debug("ISO9660 Supplementary Volume Descriptor found\n"); udf_debug
break; ("ISO9660 Supplementary Volume Descriptor found\n");
case 3: break;
udf_debug("ISO9660 Volume Partition Descriptor found\n"); case 3:
break; udf_debug
case 255: ("ISO9660 Volume Partition Descriptor found\n");
udf_debug("ISO9660 Volume Descriptor Set Terminator found\n"); break;
break; case 255:
default: udf_debug
udf_debug("ISO9660 VRS (%u) found\n", vsd->structType); ("ISO9660 Volume Descriptor Set Terminator found\n");
break; break;
default:
udf_debug("ISO9660 VRS (%u) found\n",
vsd->structType);
break;
} }
} } else
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) if (!strncmp
{ (vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) {
} } else
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) if (!strncmp
{ (vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) {
brelse(bh); brelse(bh);
break; break;
} } else
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) if (!strncmp
{ (vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) {
nsr02 = sector; nsr02 = sector;
} } else
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) if (!strncmp
{ (vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) {
nsr03 = sector; nsr03 = sector;
} }
brelse(bh); brelse(bh);
...@@ -635,8 +634,7 @@ udf_vrs(struct super_block *sb, int silent) ...@@ -635,8 +634,7 @@ udf_vrs(struct super_block *sb, int silent)
* July 1, 1997 - Andrew E. Mileski * July 1, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
static void static void udf_find_anchor(struct super_block *sb)
udf_find_anchor(struct super_block *sb)
{ {
int lastblock = UDF_SB_LASTBLOCK(sb); int lastblock = UDF_SB_LASTBLOCK(sb);
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
...@@ -644,13 +642,13 @@ udf_find_anchor(struct super_block *sb) ...@@ -644,13 +642,13 @@ udf_find_anchor(struct super_block *sb)
uint32_t location; uint32_t location;
int i; int i;
if (lastblock) if (lastblock) {
{
int varlastblock = udf_variable_to_fixed(lastblock); int varlastblock = udf_variable_to_fixed(lastblock);
int last[] = { lastblock, lastblock - 2, int last[] = { lastblock, lastblock - 2,
lastblock - 150, lastblock - 152, lastblock - 150, lastblock - 152,
varlastblock, varlastblock - 2, varlastblock, varlastblock - 2,
varlastblock - 150, varlastblock - 152 }; varlastblock - 150, varlastblock - 152
};
lastblock = 0; lastblock = 0;
...@@ -663,90 +661,103 @@ udf_find_anchor(struct super_block *sb) ...@@ -663,90 +661,103 @@ udf_find_anchor(struct super_block *sb)
* however, if the disc isn't closed, it could be 512 */ * however, if the disc isn't closed, it could be 512 */
for (i = 0; !lastblock && i < ARRAY_SIZE(last); i++) { for (i = 0; !lastblock && i < ARRAY_SIZE(last); i++) {
if (last[i] < 0 || !(bh = sb_bread(sb, last[i]))) if (last[i] < 0 || !(bh = sb_bread(sb, last[i]))) {
{
ident = location = 0; ident = location = 0;
} } else {
else ident =
{ le16_to_cpu(((tag *) bh->b_data)->tagIdent);
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); location =
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); le32_to_cpu(((tag *) bh->b_data)->
tagLocation);
brelse(bh); brelse(bh);
} }
if (ident == TAG_IDENT_AVDP) if (ident == TAG_IDENT_AVDP) {
{ if (location == last[i] - UDF_SB_SESSION(sb)) {
if (location == last[i] - UDF_SB_SESSION(sb)) lastblock = UDF_SB_ANCHOR(sb)[0] =
{ last[i] - UDF_SB_SESSION(sb);
lastblock = UDF_SB_ANCHOR(sb)[0] = last[i] - UDF_SB_SESSION(sb); UDF_SB_ANCHOR(sb)[1] =
UDF_SB_ANCHOR(sb)[1] = last[i] - 256 - UDF_SB_SESSION(sb); last[i] - 256 - UDF_SB_SESSION(sb);
} } else if (location ==
else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb)) udf_variable_to_fixed(last[i]) -
{ UDF_SB_SESSION(sb)) {
UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb); lastblock = UDF_SB_ANCHOR(sb)[0] =
UDF_SB_ANCHOR(sb)[1] = lastblock - 256 - UDF_SB_SESSION(sb); udf_variable_to_fixed(last[i]) -
} UDF_SB_SESSION(sb);
else UDF_SB_ANCHOR(sb)[1] =
udf_debug("Anchor found at block %d, location mismatch %d.\n", lastblock - 256 -
last[i], location); UDF_SB_SESSION(sb);
} } else
else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE) udf_debug
{ ("Anchor found at block %d, location mismatch %d.\n",
last[i], location);
} else if (ident == TAG_IDENT_FE
|| ident == TAG_IDENT_EFE) {
lastblock = last[i]; lastblock = last[i];
UDF_SB_ANCHOR(sb)[3] = 512; UDF_SB_ANCHOR(sb)[3] = 512;
} } else {
else if (last[i] < 256
{ || !(bh = sb_bread(sb, last[i] - 256))) {
if (last[i] < 256 || !(bh = sb_bread(sb, last[i] - 256)))
{
ident = location = 0; ident = location = 0;
} } else {
else ident =
{ le16_to_cpu(((tag *) bh->b_data)->
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); location =
le32_to_cpu(((tag *) bh->b_data)->
tagLocation);
brelse(bh); brelse(bh);
} }
if (ident == TAG_IDENT_AVDP && if (ident == TAG_IDENT_AVDP &&
location == last[i] - 256 - UDF_SB_SESSION(sb)) location ==
{ last[i] - 256 - UDF_SB_SESSION(sb)) {
lastblock = last[i]; lastblock = last[i];
UDF_SB_ANCHOR(sb)[1] = last[i] - 256; UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
} } else {
else if (last[i] < 312 + UDF_SB_SESSION(sb)
{ || !(bh =
if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = sb_bread(sb, last[i] - 312 - UDF_SB_SESSION(sb)))) sb_bread(sb,
last[i] - 312 -
UDF_SB_SESSION(sb))))
{ {
ident = location = 0; ident = location = 0;
} } else {
else ident =
{ le16_to_cpu(((tag *) bh->
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); b_data)->
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); tagIdent);
location =
le32_to_cpu(((tag *) bh->
b_data)->
tagLocation);
brelse(bh); brelse(bh);
} }
if (ident == TAG_IDENT_AVDP && if (ident == TAG_IDENT_AVDP &&
location == udf_variable_to_fixed(last[i]) - 256) location ==
{ udf_variable_to_fixed(last[i]) -
UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); 256) {
lastblock = udf_variable_to_fixed(last[i]); UDF_SET_FLAG(sb,
UDF_SB_ANCHOR(sb)[1] = lastblock - 256; UDF_FLAG_VARCONV);
lastblock =
udf_variable_to_fixed(last
[i]);
UDF_SB_ANCHOR(sb)[1] =
lastblock - 256;
} }
} }
} }
} }
} }
if (!lastblock) if (!lastblock) {
{
/* We havn't found the lastblock. check 312 */ /* We havn't found the lastblock. check 312 */
if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb)))) if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb)))) {
{ ident = le16_to_cpu(((tag *) bh->b_data)->tagIdent);
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); location =
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); le32_to_cpu(((tag *) bh->b_data)->tagLocation);
brelse(bh); brelse(bh);
if (ident == TAG_IDENT_AVDP && location == 256) if (ident == TAG_IDENT_AVDP && location == 256)
...@@ -755,18 +766,19 @@ udf_find_anchor(struct super_block *sb) ...@@ -755,18 +766,19 @@ udf_find_anchor(struct super_block *sb)
} }
for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) { for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {
if (UDF_SB_ANCHOR(sb)[i]) if (UDF_SB_ANCHOR(sb)[i]) {
{
if (!(bh = udf_read_tagged(sb, if (!(bh = udf_read_tagged(sb,
UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident))) UDF_SB_ANCHOR(sb)[i],
{ UDF_SB_ANCHOR(sb)[i],
&ident))) {
UDF_SB_ANCHOR(sb)[i] = 0; UDF_SB_ANCHOR(sb)[i] = 0;
} } else {
else
{
brelse(bh); brelse(bh);
if ((ident != TAG_IDENT_AVDP) && (i || if ((ident != TAG_IDENT_AVDP) && (i ||
(ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE))) (ident !=
TAG_IDENT_FE
&& ident !=
TAG_IDENT_EFE)))
{ {
UDF_SB_ANCHOR(sb)[i] = 0; UDF_SB_ANCHOR(sb)[i] = 0;
} }
...@@ -777,72 +789,75 @@ udf_find_anchor(struct super_block *sb) ...@@ -777,72 +789,75 @@ udf_find_anchor(struct super_block *sb)
UDF_SB_LASTBLOCK(sb) = lastblock; UDF_SB_LASTBLOCK(sb) = lastblock;
} }
static int static int
udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr *root) udf_find_fileset(struct super_block *sb, kernel_lb_addr * fileset,
kernel_lb_addr * root)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
long lastblock; long lastblock;
uint16_t ident; uint16_t ident;
if (fileset->logicalBlockNum != 0xFFFFFFFF || if (fileset->logicalBlockNum != 0xFFFFFFFF ||
fileset->partitionReferenceNum != 0xFFFF) fileset->partitionReferenceNum != 0xFFFF) {
{
bh = udf_read_ptagged(sb, *fileset, 0, &ident); bh = udf_read_ptagged(sb, *fileset, 0, &ident);
if (!bh) if (!bh)
return 1; return 1;
else if (ident != TAG_IDENT_FSD) else if (ident != TAG_IDENT_FSD) {
{
brelse(bh); brelse(bh);
return 1; return 1;
} }
} }
if (!bh) /* Search backwards through the partitions */ if (!bh) { /* Search backwards through the partitions */
{
kernel_lb_addr newfileset; kernel_lb_addr newfileset;
return 1; return 1;
for (newfileset.partitionReferenceNum=UDF_SB_NUMPARTS(sb)-1; for (newfileset.partitionReferenceNum = UDF_SB_NUMPARTS(sb) - 1;
(newfileset.partitionReferenceNum != 0xFFFF && (newfileset.partitionReferenceNum != 0xFFFF &&
fileset->logicalBlockNum == 0xFFFFFFFF && fileset->logicalBlockNum == 0xFFFFFFFF &&
fileset->partitionReferenceNum == 0xFFFF); fileset->partitionReferenceNum == 0xFFFF);
newfileset.partitionReferenceNum--) newfileset.partitionReferenceNum--) {
{ lastblock =
lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum); UDF_SB_PARTLEN(sb,
newfileset.partitionReferenceNum);
newfileset.logicalBlockNum = 0; newfileset.logicalBlockNum = 0;
do do {
{ bh = udf_read_ptagged(sb, newfileset, 0,
bh = udf_read_ptagged(sb, newfileset, 0, &ident); &ident);
if (!bh) if (!bh) {
{ newfileset.logicalBlockNum++;
newfileset.logicalBlockNum ++;
continue; continue;
} }
switch (ident) switch (ident) {
{ case TAG_IDENT_SBD:
case TAG_IDENT_SBD:
{ {
struct spaceBitmapDesc *sp; struct spaceBitmapDesc *sp;
sp = (struct spaceBitmapDesc *)bh->b_data; sp = (struct spaceBitmapDesc *)
newfileset.logicalBlockNum += 1 + bh->b_data;
((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1) newfileset.logicalBlockNum +=
>> sb->s_blocksize_bits); 1 +
((le32_to_cpu
(sp->numOfBytes) +
sizeof(struct
spaceBitmapDesc) -
1)
>> sb->s_blocksize_bits);
brelse(bh); brelse(bh);
break; break;
} }
case TAG_IDENT_FSD: case TAG_IDENT_FSD:
{ {
*fileset = newfileset; *fileset = newfileset;
break; break;
} }
default: default:
{ {
newfileset.logicalBlockNum ++; newfileset.logicalBlockNum++;
brelse(bh); brelse(bh);
bh = NULL; bh = NULL;
break; break;
...@@ -850,16 +865,16 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr ...@@ -850,16 +865,16 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr
} }
} }
while (newfileset.logicalBlockNum < lastblock && while (newfileset.logicalBlockNum < lastblock &&
fileset->logicalBlockNum == 0xFFFFFFFF && fileset->logicalBlockNum == 0xFFFFFFFF &&
fileset->partitionReferenceNum == 0xFFFF); fileset->partitionReferenceNum == 0xFFFF);
} }
} }
if ((fileset->logicalBlockNum != 0xFFFFFFFF || if ((fileset->logicalBlockNum != 0xFFFFFFFF ||
fileset->partitionReferenceNum != 0xFFFF) && bh) fileset->partitionReferenceNum != 0xFFFF) && bh) {
{
udf_debug("Fileset at block=%d, partition=%d\n", udf_debug("Fileset at block=%d, partition=%d\n",
fileset->logicalBlockNum, fileset->partitionReferenceNum); fileset->logicalBlockNum,
fileset->partitionReferenceNum);
UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum; UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
udf_load_fileset(sb, bh, root); udf_load_fileset(sb, bh, root);
...@@ -869,8 +884,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr ...@@ -869,8 +884,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr
return 1; return 1;
} }
static void static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
{ {
struct primaryVolDesc *pvoldesc; struct primaryVolDesc *pvoldesc;
time_t recording; time_t recording;
...@@ -880,37 +894,35 @@ udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh) ...@@ -880,37 +894,35 @@ udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
pvoldesc = (struct primaryVolDesc *)bh->b_data; pvoldesc = (struct primaryVolDesc *)bh->b_data;
if ( udf_stamp_to_time(&recording, &recording_usec, if (udf_stamp_to_time(&recording, &recording_usec,
lets_to_cpu(pvoldesc->recordingDateAndTime)) ) lets_to_cpu(pvoldesc->recordingDateAndTime))) {
{
kernel_timestamp ts; kernel_timestamp ts;
ts = lets_to_cpu(pvoldesc->recordingDateAndTime); ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n", udf_debug
recording, recording_usec, ("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone); recording, recording_usec, ts.year, ts.month, ts.day,
ts.hour, ts.minute, ts.typeAndTimezone);
UDF_SB_RECORDTIME(sb).tv_sec = recording; UDF_SB_RECORDTIME(sb).tv_sec = recording;
UDF_SB_RECORDTIME(sb).tv_nsec = recording_usec * 1000; UDF_SB_RECORDTIME(sb).tv_nsec = recording_usec * 1000;
} }
if ( !udf_build_ustr(&instr, pvoldesc->volIdent, 32) ) if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) {
{ if (udf_CS0toUTF8(&outstr, &instr)) {
if (udf_CS0toUTF8(&outstr, &instr)) strncpy(UDF_SB_VOLIDENT(sb), outstr.u_name,
{
strncpy( UDF_SB_VOLIDENT(sb), outstr.u_name,
outstr.u_len > 31 ? 31 : outstr.u_len); outstr.u_len > 31 ? 31 : outstr.u_len);
udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb)); udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb));
} }
} }
if ( !udf_build_ustr(&instr, pvoldesc->volSetIdent, 128) ) if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) {
{
if (udf_CS0toUTF8(&outstr, &instr)) if (udf_CS0toUTF8(&outstr, &instr))
udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
} }
} }
static void static void
udf_load_fileset(struct super_block *sb, struct buffer_head *bh, kernel_lb_addr *root) udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
kernel_lb_addr * root)
{ {
struct fileSetDesc *fset; struct fileSetDesc *fset;
...@@ -920,109 +932,154 @@ udf_load_fileset(struct super_block *sb, struct buffer_head *bh, kernel_lb_addr ...@@ -920,109 +932,154 @@ udf_load_fileset(struct super_block *sb, struct buffer_head *bh, kernel_lb_addr
UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum); UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum);
udf_debug("Rootdir at block=%d, partition=%d\n", udf_debug("Rootdir at block=%d, partition=%d\n",
root->logicalBlockNum, root->partitionReferenceNum); root->logicalBlockNum, root->partitionReferenceNum);
} }
static void static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
{ {
struct partitionDesc *p; struct partitionDesc *p;
int i; int i;
p = (struct partitionDesc *)bh->b_data; p = (struct partitionDesc *)bh->b_data;
for (i=0; i<UDF_SB_NUMPARTS(sb); i++) for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
{ udf_debug("Searching map: (%d == %d)\n",
udf_debug("Searching map: (%d == %d)\n", UDF_SB_PARTMAPS(sb)[i].s_partition_num,
UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber)); le16_to_cpu(p->partitionNumber));
if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber)) if (UDF_SB_PARTMAPS(sb)[i].s_partition_num ==
{ le16_to_cpu(p->partitionNumber)) {
UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */ UDF_SB_PARTLEN(sb, i) = le32_to_cpu(p->partitionLength); /* blocks */
UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation); UDF_SB_PARTROOT(sb, i) =
if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY) le32_to_cpu(p->partitionStartingLocation);
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY; if (le32_to_cpu(p->accessType) ==
if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE) PD_ACCESS_TYPE_READ_ONLY)
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_WRITE_ONCE; UDF_SB_PARTFLAGS(sb, i) |=
if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_REWRITABLE) UDF_PART_FLAG_READ_ONLY;
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_REWRITABLE; if (le32_to_cpu(p->accessType) ==
if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_OVERWRITABLE) PD_ACCESS_TYPE_WRITE_ONCE)
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_OVERWRITABLE; UDF_SB_PARTFLAGS(sb, i) |=
UDF_PART_FLAG_WRITE_ONCE;
if (!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) || if (le32_to_cpu(p->accessType) ==
!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) PD_ACCESS_TYPE_REWRITABLE)
{ UDF_SB_PARTFLAGS(sb, i) |=
UDF_PART_FLAG_REWRITABLE;
if (le32_to_cpu(p->accessType) ==
PD_ACCESS_TYPE_OVERWRITABLE)
UDF_SB_PARTFLAGS(sb, i) |=
UDF_PART_FLAG_OVERWRITABLE;
if (!strcmp
(p->partitionContents.ident,
PD_PARTITION_CONTENTS_NSR02)
|| !strcmp(p->partitionContents.ident,
PD_PARTITION_CONTENTS_NSR03)) {
struct partitionHeaderDesc *phd; struct partitionHeaderDesc *phd;
phd = (struct partitionHeaderDesc *)(p->partitionContentsUse); phd =
if (phd->unallocSpaceTable.extLength) (struct partitionHeaderDesc *)(p->
{ partitionContentsUse);
kernel_lb_addr loc = { le32_to_cpu(phd->unallocSpaceTable.extPosition), i }; if (phd->unallocSpaceTable.extLength) {
kernel_lb_addr loc =
UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table = { le32_to_cpu(phd->
udf_iget(sb, loc); unallocSpaceTable.
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE; extPosition), i };
udf_debug("unallocSpaceTable (part %d) @ %ld\n",
i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino); UDF_SB_PARTMAPS(sb)[i].s_uspace.
s_table = udf_iget(sb, loc);
UDF_SB_PARTFLAGS(sb, i) |=
UDF_PART_FLAG_UNALLOC_TABLE;
udf_debug
("unallocSpaceTable (part %d) @ %ld\n",
i,
UDF_SB_PARTMAPS(sb)[i].s_uspace.
s_table->i_ino);
} }
if (phd->unallocSpaceBitmap.extLength) if (phd->unallocSpaceBitmap.extLength) {
{
UDF_SB_ALLOC_BITMAP(sb, i, s_uspace); UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL) if (UDF_SB_PARTMAPS(sb)[i].s_uspace.
{ s_bitmap != NULL) {
UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength = UDF_SB_PARTMAPS(sb)[i].s_uspace.
le32_to_cpu(phd->unallocSpaceBitmap.extLength); s_bitmap->s_extLength =
UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition = le32_to_cpu(phd->
le32_to_cpu(phd->unallocSpaceBitmap.extPosition); unallocSpaceBitmap.
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP; extLength);
udf_debug("unallocSpaceBitmap (part %d) @ %d\n", UDF_SB_PARTMAPS(sb)[i].s_uspace.
i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition); s_bitmap->s_extPosition =
le32_to_cpu(phd->
unallocSpaceBitmap.
extPosition);
UDF_SB_PARTFLAGS(sb, i) |=
UDF_PART_FLAG_UNALLOC_BITMAP;
udf_debug
("unallocSpaceBitmap (part %d) @ %d\n",
i,
UDF_SB_PARTMAPS(sb)[i].
s_uspace.s_bitmap->
s_extPosition);
} }
} }
if (phd->partitionIntegrityTable.extLength) if (phd->partitionIntegrityTable.extLength)
udf_debug("partitionIntegrityTable (part %d)\n", i); udf_debug
if (phd->freedSpaceTable.extLength) ("partitionIntegrityTable (part %d)\n",
{ i);
kernel_lb_addr loc = { le32_to_cpu(phd->freedSpaceTable.extPosition), i }; if (phd->freedSpaceTable.extLength) {
kernel_lb_addr loc =
UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table = { le32_to_cpu(phd->freedSpaceTable.
udf_iget(sb, loc); extPosition), i };
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
udf_debug("freedSpaceTable (part %d) @ %ld\n", UDF_SB_PARTMAPS(sb)[i].s_fspace.
i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino); s_table = udf_iget(sb, loc);
UDF_SB_PARTFLAGS(sb, i) |=
UDF_PART_FLAG_FREED_TABLE;
udf_debug
("freedSpaceTable (part %d) @ %ld\n",
i,
UDF_SB_PARTMAPS(sb)[i].s_fspace.
s_table->i_ino);
} }
if (phd->freedSpaceBitmap.extLength) if (phd->freedSpaceBitmap.extLength) {
{
UDF_SB_ALLOC_BITMAP(sb, i, s_fspace); UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);
if (UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap != NULL) if (UDF_SB_PARTMAPS(sb)[i].s_fspace.
{ s_bitmap != NULL) {
UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength = UDF_SB_PARTMAPS(sb)[i].s_fspace.
le32_to_cpu(phd->freedSpaceBitmap.extLength); s_bitmap->s_extLength =
UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition = le32_to_cpu(phd->
le32_to_cpu(phd->freedSpaceBitmap.extPosition); freedSpaceBitmap.
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP; extLength);
udf_debug("freedSpaceBitmap (part %d) @ %d\n", UDF_SB_PARTMAPS(sb)[i].s_fspace.
i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition); s_bitmap->s_extPosition =
le32_to_cpu(phd->
freedSpaceBitmap.
extPosition);
UDF_SB_PARTFLAGS(sb, i) |=
UDF_PART_FLAG_FREED_BITMAP;
udf_debug
("freedSpaceBitmap (part %d) @ %d\n",
i,
UDF_SB_PARTMAPS(sb)[i].
s_fspace.s_bitmap->
s_extPosition);
} }
} }
} }
break; break;
} }
} }
if (i == UDF_SB_NUMPARTS(sb)) if (i == UDF_SB_NUMPARTS(sb)) {
{ udf_debug("Partition (%d) not found in partition map\n",
udf_debug("Partition (%d) not found in partition map\n", le16_to_cpu(p->partitionNumber)); le16_to_cpu(p->partitionNumber));
} } else {
else udf_debug
{ ("Partition (%d:%d type %x) starts at physical %d, block length %d\n",
udf_debug("Partition (%d:%d type %x) starts at physical %d, block length %d\n", le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb, i),
le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i), UDF_SB_PARTROOT(sb, i), UDF_SB_PARTLEN(sb, i));
UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));
} }
} }
static int static int
udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_addr *fileset) udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
kernel_lb_addr * fileset)
{ {
struct logicalVolDesc *lvd; struct logicalVolDesc *lvd;
int i, j, offset; int i, j, offset;
...@@ -1032,82 +1089,114 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a ...@@ -1032,82 +1089,114 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a
UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps)); UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
for (i=0,offset=0; for (i = 0, offset = 0;
i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength); i < UDF_SB_NUMPARTS(sb)
i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength) && offset < le32_to_cpu(lvd->mapTableLength);
{ i++, offset +=
type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType; ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->
if (type == 1) partitionMapLength) {
{ type =
struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)&(lvd->partitionMaps[offset]); ((struct genericPartitionMap *)
UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15; &(lvd->partitionMaps[offset]))->partitionMapType;
UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum); if (type == 1) {
UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum); struct genericPartitionMap1 *gpm1 =
UDF_SB_PARTFUNC(sb,i) = NULL; (struct genericPartitionMap1 *)&(lvd->
} partitionMaps
else if (type == 2) [offset]);
{ UDF_SB_PARTTYPE(sb, i) = UDF_TYPE1_MAP15;
struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]); UDF_SB_PARTVSN(sb, i) = le16_to_cpu(gpm1->volSeqNum);
if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL))) UDF_SB_PARTNUM(sb, i) = le16_to_cpu(gpm1->partitionNum);
{ UDF_SB_PARTFUNC(sb, i) = NULL;
if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0150) } else if (type == 2) {
{ struct udfPartitionMap2 *upm2 =
UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15; (struct udfPartitionMap2 *)&(lvd->
UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15; partitionMaps[offset]);
} if (!strncmp
else if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0200) (upm2->partIdent.ident, UDF_ID_VIRTUAL,
{ strlen(UDF_ID_VIRTUAL))) {
UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20; if (le16_to_cpu
UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20; (((__le16 *) upm2->partIdent.
identSuffix)[0]) == 0x0150) {
UDF_SB_PARTTYPE(sb, i) =
UDF_VIRTUAL_MAP15;
UDF_SB_PARTFUNC(sb, i) =
udf_get_pblock_virt15;
} else
if (le16_to_cpu
(((__le16 *) upm2->partIdent.
identSuffix)[0]) == 0x0200) {
UDF_SB_PARTTYPE(sb, i) =
UDF_VIRTUAL_MAP20;
UDF_SB_PARTFUNC(sb, i) =
udf_get_pblock_virt20;
} }
} } else
else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE))) if (!strncmp
{ (upm2->partIdent.ident, UDF_ID_SPARABLE,
strlen(UDF_ID_SPARABLE))) {
uint32_t loc; uint32_t loc;
uint16_t ident; uint16_t ident;
struct sparingTable *st; struct sparingTable *st;
struct sparablePartitionMap *spm = (struct sparablePartitionMap *)&(lvd->partitionMaps[offset]); struct sparablePartitionMap *spm =
(struct sparablePartitionMap *)&(lvd->
UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15; partitionMaps
UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength); [offset]);
for (j=0; j<spm->numSparingTables; j++)
{ UDF_SB_PARTTYPE(sb, i) = UDF_SPARABLE_MAP15;
loc = le32_to_cpu(spm->locSparingTable[j]); UDF_SB_TYPESPAR(sb, i).s_packet_len =
UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = le16_to_cpu(spm->packetLength);
udf_read_tagged(sb, loc, loc, &ident); for (j = 0; j < spm->numSparingTables; j++) {
if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) loc =
{ le32_to_cpu(spm->
st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data; locSparingTable[j]);
if (ident != 0 || UDF_SB_TYPESPAR(sb, i).s_spar_map[j] =
strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) udf_read_tagged(sb, loc, loc,
&ident);
if (UDF_SB_TYPESPAR(sb, i).
s_spar_map[j] != NULL) {
st = (struct sparingTable *)
UDF_SB_TYPESPAR(sb,
i).
s_spar_map[j]->b_data;
if (ident != 0
|| strncmp(st->sparingIdent.
ident,
UDF_ID_SPARING,
strlen
(UDF_ID_SPARING)))
{ {
brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]); brelse(UDF_SB_TYPESPAR
UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL; (sb,
i).
s_spar_map[j]);
UDF_SB_TYPESPAR(sb,
i).
s_spar_map[j] =
NULL;
} }
} }
} }
UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15; UDF_SB_PARTFUNC(sb, i) = udf_get_pblock_spar15;
} } else {
else udf_debug("Unknown ident: %s\n",
{ upm2->partIdent.ident);
udf_debug("Unknown ident: %s\n", upm2->partIdent.ident);
continue; continue;
} }
UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum); UDF_SB_PARTVSN(sb, i) = le16_to_cpu(upm2->volSeqNum);
UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum); UDF_SB_PARTNUM(sb, i) = le16_to_cpu(upm2->partitionNum);
} }
udf_debug("Partition (%d:%d) type %d on volume %d\n", udf_debug("Partition (%d:%d) type %d on volume %d\n",
i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i)); i, UDF_SB_PARTNUM(sb, i), type, UDF_SB_PARTVSN(sb,
i));
} }
if (fileset) if (fileset) {
{ long_ad *la = (long_ad *) & (lvd->logicalVolContentsUse[0]);
long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
*fileset = lelb_to_cpu(la->extLocation); *fileset = lelb_to_cpu(la->extLocation);
udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n", udf_debug
fileset->logicalBlockNum, ("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
fileset->partitionReferenceNum); fileset->logicalBlockNum, fileset->partitionReferenceNum);
} }
if (lvd->integritySeqExt.extLength) if (lvd->integritySeqExt.extLength)
udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
...@@ -1118,26 +1207,26 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a ...@@ -1118,26 +1207,26 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a
* udf_load_logicalvolint * udf_load_logicalvolint
* *
*/ */
static void static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
uint16_t ident; uint16_t ident;
while (loc.extLength > 0 && while (loc.extLength > 0 &&
(bh = udf_read_tagged(sb, loc.extLocation, (bh = udf_read_tagged(sb, loc.extLocation,
loc.extLocation, &ident)) && loc.extLocation, &ident)) &&
ident == TAG_IDENT_LVID) ident == TAG_IDENT_LVID) {
{
UDF_SB_LVIDBH(sb) = bh; UDF_SB_LVIDBH(sb) = bh;
if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength) if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength)
udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt)); udf_load_logicalvolint(sb,
leea_to_cpu(UDF_SB_LVID(sb)->
nextIntegrityExt));
if (UDF_SB_LVIDBH(sb) != bh) if (UDF_SB_LVIDBH(sb) != bh)
brelse(bh); brelse(bh);
loc.extLength -= sb->s_blocksize; loc.extLength -= sb->s_blocksize;
loc.extLocation ++; loc.extLocation++;
} }
if (UDF_SB_LVIDBH(sb) != bh) if (UDF_SB_LVIDBH(sb) != bh)
brelse(bh); brelse(bh);
...@@ -1158,15 +1247,16 @@ udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) ...@@ -1158,15 +1247,16 @@ udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
* July 1, 1997 - Andrew E. Mileski * July 1, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
static int static int
udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_lb_addr *fileset) udf_process_sequence(struct super_block *sb, long block, long lastblock,
kernel_lb_addr * fileset)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
struct udf_vds_record vds[VDS_POS_LENGTH]; struct udf_vds_record vds[VDS_POS_LENGTH];
struct generic_desc *gd; struct generic_desc *gd;
struct volDescPtr *vdp; struct volDescPtr *vdp;
int done=0; int done = 0;
int i,j; int i, j;
uint32_t vdsn; uint32_t vdsn;
uint16_t ident; uint16_t ident;
long next_s = 0, next_e = 0; long next_s = 0, next_e = 0;
...@@ -1174,93 +1264,92 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_ ...@@ -1174,93 +1264,92 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_
memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
/* Read the main descriptor sequence */ /* Read the main descriptor sequence */
for (;(!done && block <= lastblock); block++) for (; (!done && block <= lastblock); block++) {
{
bh = udf_read_tagged(sb, block, block, &ident); bh = udf_read_tagged(sb, block, block, &ident);
if (!bh) if (!bh)
break; break;
/* Process each descriptor (ISO 13346 3/8.3-8.4) */ /* Process each descriptor (ISO 13346 3/8.3-8.4) */
gd = (struct generic_desc *)bh->b_data; gd = (struct generic_desc *)bh->b_data;
vdsn = le32_to_cpu(gd->volDescSeqNum); vdsn = le32_to_cpu(gd->volDescSeqNum);
switch (ident) switch (ident) {
{ case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */ if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum) {
if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum) vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum =
{ vdsn;
vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn; vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
vds[VDS_POS_PRIMARY_VOL_DESC].block = block; }
} break;
break; case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */ if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum) {
if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum) vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
{ vds[VDS_POS_VOL_DESC_PTR].block = block;
vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
vds[VDS_POS_VOL_DESC_PTR].block = block; vdp = (struct volDescPtr *)bh->b_data;
next_s =
vdp = (struct volDescPtr *)bh->b_data; le32_to_cpu(vdp->nextVolDescSeqExt.
next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation); extLocation);
next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength); next_e =
next_e = next_e >> sb->s_blocksize_bits; le32_to_cpu(vdp->nextVolDescSeqExt.
next_e += next_s; extLength);
} next_e = next_e >> sb->s_blocksize_bits;
break; next_e += next_s;
case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */ }
if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum) break;
{ case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn; if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum) {
vds[VDS_POS_IMP_USE_VOL_DESC].block = block; vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum =
} vdsn;
break; vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
case TAG_IDENT_PD: /* ISO 13346 3/10.5 */ }
if (!vds[VDS_POS_PARTITION_DESC].block) break;
vds[VDS_POS_PARTITION_DESC].block = block; case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
break; if (!vds[VDS_POS_PARTITION_DESC].block)
case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */ vds[VDS_POS_PARTITION_DESC].block = block;
if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum) break;
{ case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn; if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum) {
vds[VDS_POS_LOGICAL_VOL_DESC].block = block; vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum =
} vdsn;
break; vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
case TAG_IDENT_USD: /* ISO 13346 3/10.8 */ }
if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum) break;
{ case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn; if (vdsn >=
vds[VDS_POS_UNALLOC_SPACE_DESC].block = block; vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum) {
} vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum =
break; vdsn;
case TAG_IDENT_TD: /* ISO 13346 3/10.9 */ vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
vds[VDS_POS_TERMINATING_DESC].block = block; }
if (next_e) break;
{ case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
block = next_s; vds[VDS_POS_TERMINATING_DESC].block = block;
lastblock = next_e; if (next_e) {
next_s = next_e = 0; block = next_s;
} lastblock = next_e;
else next_s = next_e = 0;
done = 1; } else
break; done = 1;
break;
} }
brelse(bh); brelse(bh);
} }
for (i=0; i<VDS_POS_LENGTH; i++) for (i = 0; i < VDS_POS_LENGTH; i++) {
{ if (vds[i].block) {
if (vds[i].block) bh = udf_read_tagged(sb, vds[i].block, vds[i].block,
{ &ident);
bh = udf_read_tagged(sb, vds[i].block, vds[i].block, &ident);
if (i == VDS_POS_PRIMARY_VOL_DESC) if (i == VDS_POS_PRIMARY_VOL_DESC)
udf_load_pvoldesc(sb, bh); udf_load_pvoldesc(sb, bh);
else if (i == VDS_POS_LOGICAL_VOL_DESC) else if (i == VDS_POS_LOGICAL_VOL_DESC)
udf_load_logicalvol(sb, bh, fileset); udf_load_logicalvol(sb, bh, fileset);
else if (i == VDS_POS_PARTITION_DESC) else if (i == VDS_POS_PARTITION_DESC) {
{
struct buffer_head *bh2 = NULL; struct buffer_head *bh2 = NULL;
udf_load_partdesc(sb, bh); udf_load_partdesc(sb, bh);
for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++) for (j = vds[i].block + 1;
{ j < vds[VDS_POS_TERMINATING_DESC].block;
j++) {
bh2 = udf_read_tagged(sb, j, j, &ident); bh2 = udf_read_tagged(sb, j, j, &ident);
gd = (struct generic_desc *)bh2->b_data; gd = (struct generic_desc *)bh2->b_data;
if (ident == TAG_IDENT_PD) if (ident == TAG_IDENT_PD)
...@@ -1278,31 +1367,27 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_ ...@@ -1278,31 +1367,27 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_
/* /*
* udf_check_valid() * udf_check_valid()
*/ */
static int static int udf_check_valid(struct super_block *sb, int novrs, int silent)
udf_check_valid(struct super_block *sb, int novrs, int silent)
{ {
long block; long block;
if (novrs) if (novrs) {
{
udf_debug("Validity check skipped because of novrs option\n"); udf_debug("Validity check skipped because of novrs option\n");
return 0; return 0;
} }
/* Check that it is NSR02 compliant */ /* Check that it is NSR02 compliant */
/* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
else if ((block = udf_vrs(sb, silent)) == -1) else if ((block = udf_vrs(sb, silent)) == -1) {
{ udf_debug
udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n"); ("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
if (!UDF_SB_LASTBLOCK(sb)) if (!UDF_SB_LASTBLOCK(sb))
UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb); UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
return 0; return 0;
} } else
else
return !block; return !block;
} }
static int static int udf_load_partition(struct super_block *sb, kernel_lb_addr * fileset)
udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
{ {
struct anchorVolDescPtr *anchor; struct anchorVolDescPtr *anchor;
uint16_t ident; uint16_t ident;
...@@ -1315,19 +1400,27 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) ...@@ -1315,19 +1400,27 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) { for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {
if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb, if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident))) UDF_SB_ANCHOR
{ (sb)[i],
UDF_SB_ANCHOR
(sb)[i],
&ident))) {
anchor = (struct anchorVolDescPtr *)bh->b_data; anchor = (struct anchorVolDescPtr *)bh->b_data;
/* Locate the main sequence */ /* Locate the main sequence */
main_s = le32_to_cpu( anchor->mainVolDescSeqExt.extLocation ); main_s =
main_e = le32_to_cpu( anchor->mainVolDescSeqExt.extLength ); 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_e >> sb->s_blocksize_bits;
main_e += main_s; main_e += main_s;
/* Locate the reserve sequence */ /* Locate the reserve sequence */
reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation); reserve_s =
reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength); 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_e >> sb->s_blocksize_bits;
reserve_e += reserve_s; reserve_e += reserve_s;
...@@ -1335,9 +1428,10 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) ...@@ -1335,9 +1428,10 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
/* Process the main & reserve sequences */ /* Process the main & reserve sequences */
/* responsible for finding the PartitionDesc(s) */ /* responsible for finding the PartitionDesc(s) */
if (!(udf_process_sequence(sb, main_s, main_e, fileset) && if (!
udf_process_sequence(sb, reserve_s, reserve_e, fileset))) (udf_process_sequence(sb, main_s, main_e, fileset)
{ && udf_process_sequence(sb, reserve_s, reserve_e,
fileset))) {
break; break;
} }
} }
...@@ -1349,36 +1443,37 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) ...@@ -1349,36 +1443,37 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
} else } else
udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]); udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);
for (i=0; i<UDF_SB_NUMPARTS(sb); i++) for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
{ switch (UDF_SB_PARTTYPE(sb, i)) {
switch (UDF_SB_PARTTYPE(sb, i)) case UDF_VIRTUAL_MAP15:
{ case UDF_VIRTUAL_MAP20:
case UDF_VIRTUAL_MAP15:
case UDF_VIRTUAL_MAP20:
{ {
kernel_lb_addr uninitialized_var(ino); kernel_lb_addr uninitialized_var(ino);
if (!UDF_SB_LASTBLOCK(sb)) if (!UDF_SB_LASTBLOCK(sb)) {
{ UDF_SB_LASTBLOCK(sb) =
UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb); udf_get_last_block(sb);
udf_find_anchor(sb); udf_find_anchor(sb);
} }
if (!UDF_SB_LASTBLOCK(sb)) if (!UDF_SB_LASTBLOCK(sb)) {
{ udf_debug
udf_debug("Unable to determine Lastblock (For Virtual Partition)\n"); ("Unable to determine Lastblock (For Virtual Partition)\n");
return 1; return 1;
} }
for (j=0; j<UDF_SB_NUMPARTS(sb); j++) for (j = 0; j < UDF_SB_NUMPARTS(sb); j++) {
{
if (j != i && if (j != i &&
UDF_SB_PARTVSN(sb,i) == UDF_SB_PARTVSN(sb,j) && UDF_SB_PARTVSN(sb,
UDF_SB_PARTNUM(sb,i) == UDF_SB_PARTNUM(sb,j)) i) ==
{ UDF_SB_PARTVSN(sb, j)
&& UDF_SB_PARTNUM(sb,
i) ==
UDF_SB_PARTNUM(sb, j)) {
ino.partitionReferenceNum = j; ino.partitionReferenceNum = j;
ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) - ino.logicalBlockNum =
UDF_SB_PARTROOT(sb,j); UDF_SB_LASTBLOCK(sb) -
UDF_SB_PARTROOT(sb, j);
break; break;
} }
} }
...@@ -1389,13 +1484,13 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) ...@@ -1389,13 +1484,13 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino))) if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))
return 1; return 1;
if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15) if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP15) {
{ UDF_SB_TYPEVIRT(sb, i).s_start_offset =
UDF_SB_TYPEVIRT(sb,i).s_start_offset = udf_ext0_offset(UDF_SB_VAT(sb)); udf_ext0_offset(UDF_SB_VAT(sb));
UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2; UDF_SB_TYPEVIRT(sb, i).s_num_entries =
} (UDF_SB_VAT(sb)->i_size - 36) >> 2;
else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20) } else if (UDF_SB_PARTTYPE(sb, i) ==
{ UDF_VIRTUAL_MAP20) {
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
uint32_t pos; uint32_t pos;
...@@ -1403,15 +1498,26 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) ...@@ -1403,15 +1498,26 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
bh = sb_bread(sb, pos); bh = sb_bread(sb, pos);
if (!bh) if (!bh)
return 1; return 1;
UDF_SB_TYPEVIRT(sb,i).s_start_offset = UDF_SB_TYPEVIRT(sb, i).s_start_offset =
le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) + le16_to_cpu(((struct
udf_ext0_offset(UDF_SB_VAT(sb)); virtualAllocationTable20
UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - *)bh->b_data +
UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2; udf_ext0_offset
(UDF_SB_VAT(sb)))->
lengthHeader) +
udf_ext0_offset(UDF_SB_VAT(sb));
UDF_SB_TYPEVIRT(sb, i).s_num_entries =
(UDF_SB_VAT(sb)->i_size -
UDF_SB_TYPEVIRT(sb,
i).
s_start_offset) >> 2;
brelse(bh); brelse(bh);
} }
UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0); UDF_SB_PARTROOT(sb, i) =
UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum); udf_get_pblock(sb, 0, i, 0);
UDF_SB_PARTLEN(sb, i) =
UDF_SB_PARTLEN(sb,
ino.partitionReferenceNum);
} }
} }
} }
...@@ -1420,26 +1526,28 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) ...@@ -1420,26 +1526,28 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
static void udf_open_lvid(struct super_block *sb) static void udf_open_lvid(struct super_block *sb)
{ {
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{
int i; int i;
kernel_timestamp cpu_time; kernel_timestamp cpu_time;
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time); UDF_SB_LVID(sb)->recordingDateAndTime =
cpu_to_lets(cpu_time);
UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN; UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
UDF_SB_LVID(sb)->descTag.descCRC = UDF_SB_LVID(sb)->descTag.descCRC =
cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag), cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0)); le16_to_cpu(UDF_SB_LVID(sb)->descTag.
descCRCLength), 0));
UDF_SB_LVID(sb)->descTag.tagChecksum = 0; UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
if (i != 4) if (i != 4)
UDF_SB_LVID(sb)->descTag.tagChecksum += UDF_SB_LVID(sb)->descTag.tagChecksum +=
((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i]; ((uint8_t *) &
(UDF_SB_LVID(sb)->descTag))[i];
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
} }
...@@ -1448,32 +1556,41 @@ static void udf_open_lvid(struct super_block *sb) ...@@ -1448,32 +1556,41 @@ static void udf_open_lvid(struct super_block *sb)
static void udf_close_lvid(struct super_block *sb) static void udf_close_lvid(struct super_block *sb)
{ {
if (UDF_SB_LVIDBH(sb) && if (UDF_SB_LVIDBH(sb) &&
UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN) UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN) {
{
int i; int i;
kernel_timestamp cpu_time; kernel_timestamp cpu_time;
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time); UDF_SB_LVID(sb)->recordingDateAndTime =
if (UDF_MAX_WRITE_VERSION > le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev)) cpu_to_lets(cpu_time);
UDF_SB_LVIDIU(sb)->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION); if (UDF_MAX_WRITE_VERSION >
if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev)) le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb)); UDF_SB_LVIDIU(sb)->maxUDFWriteRev =
if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev)) cpu_to_le16(UDF_MAX_WRITE_VERSION);
UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb)); if (UDF_SB_UDFREV(sb) >
UDF_SB_LVID(sb)->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev))
UDF_SB_LVIDIU(sb)->minUDFReadRev =
cpu_to_le16(UDF_SB_UDFREV(sb));
if (UDF_SB_UDFREV(sb) >
le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
UDF_SB_LVIDIU(sb)->minUDFWriteRev =
cpu_to_le16(UDF_SB_UDFREV(sb));
UDF_SB_LVID(sb)->integrityType =
cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
UDF_SB_LVID(sb)->descTag.descCRC = UDF_SB_LVID(sb)->descTag.descCRC =
cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag), cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0)); le16_to_cpu(UDF_SB_LVID(sb)->descTag.
descCRCLength), 0));
UDF_SB_LVID(sb)->descTag.tagChecksum = 0; UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
for (i=0; i<16; i++) for (i = 0; i < 16; i++)
if (i != 4) if (i != 4)
UDF_SB_LVID(sb)->descTag.tagChecksum += UDF_SB_LVID(sb)->descTag.tagChecksum +=
((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i]; ((uint8_t *) &
(UDF_SB_LVID(sb)->descTag))[i];
mark_buffer_dirty(UDF_SB_LVIDBH(sb)); mark_buffer_dirty(UDF_SB_LVIDBH(sb));
} }
...@@ -1498,7 +1615,7 @@ static void udf_close_lvid(struct super_block *sb) ...@@ -1498,7 +1615,7 @@ static void udf_close_lvid(struct super_block *sb)
static int udf_fill_super(struct super_block *sb, void *options, int silent) static int udf_fill_super(struct super_block *sb, void *options, int silent)
{ {
int i; int i;
struct inode *inode=NULL; struct inode *inode = NULL;
struct udf_options uopt; struct udf_options uopt;
kernel_lb_addr rootdir, fileset; kernel_lb_addr rootdir, fileset;
struct udf_sb_info *sbi; struct udf_sb_info *sbi;
...@@ -1520,15 +1637,13 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1520,15 +1637,13 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
goto error_out; goto error_out;
if (uopt.flags & (1 << UDF_FLAG_UTF8) && if (uopt.flags & (1 << UDF_FLAG_UTF8) &&
uopt.flags & (1 << UDF_FLAG_NLS_MAP)) uopt.flags & (1 << UDF_FLAG_NLS_MAP)) {
{
udf_error(sb, "udf_read_super", udf_error(sb, "udf_read_super",
"utf8 cannot be combined with iocharset\n"); "utf8 cannot be combined with iocharset\n");
goto error_out; goto error_out;
} }
#ifdef CONFIG_UDF_NLS #ifdef CONFIG_UDF_NLS
if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) {
{
uopt.nls_map = load_nls_default(); uopt.nls_map = load_nls_default();
if (!uopt.nls_map) if (!uopt.nls_map)
uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP); uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP);
...@@ -1552,7 +1667,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1552,7 +1667,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
if (!udf_set_blocksize(sb, uopt.blocksize)) if (!udf_set_blocksize(sb, uopt.blocksize))
goto error_out; goto error_out;
if ( uopt.session == 0xFFFFFFFF ) if (uopt.session == 0xFFFFFFFF)
UDF_SB_SESSION(sb) = udf_get_last_session(sb); UDF_SB_SESSION(sb) = udf_get_last_session(sb);
else else
UDF_SB_SESSION(sb) = uopt.session; UDF_SB_SESSION(sb) = uopt.session;
...@@ -1564,10 +1679,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1564,10 +1679,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
UDF_SB_ANCHOR(sb)[2] = uopt.anchor; UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
UDF_SB_ANCHOR(sb)[3] = 256; UDF_SB_ANCHOR(sb)[3] = 256;
if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */ if (udf_check_valid(sb, uopt.novrs, silent)) { /* read volume recognition sequences */
{
printk("UDF-fs: No VRS found\n"); printk("UDF-fs: No VRS found\n");
goto error_out; goto error_out;
} }
udf_find_anchor(sb); udf_find_anchor(sb);
...@@ -1579,29 +1693,26 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1579,29 +1693,26 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sb->s_magic = UDF_SUPER_MAGIC; sb->s_magic = UDF_SUPER_MAGIC;
sb->s_time_gran = 1000; sb->s_time_gran = 1000;
if (udf_load_partition(sb, &fileset)) if (udf_load_partition(sb, &fileset)) {
{
printk("UDF-fs: No partition found (1)\n"); printk("UDF-fs: No partition found (1)\n");
goto error_out; goto error_out;
} }
udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb)); udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
if ( UDF_SB_LVIDBH(sb) ) if (UDF_SB_LVIDBH(sb)) {
{ uint16_t minUDFReadRev =
uint16_t minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev); le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
uint16_t minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev); uint16_t minUDFWriteRev =
le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
/* uint16_t maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */ /* uint16_t maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
if (minUDFReadRev > UDF_MAX_READ_VERSION) if (minUDFReadRev > UDF_MAX_READ_VERSION) {
{
printk("UDF-fs: minUDFReadRev=%x (max is %x)\n", printk("UDF-fs: minUDFReadRev=%x (max is %x)\n",
le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev), le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev),
UDF_MAX_READ_VERSION); UDF_MAX_READ_VERSION);
goto error_out; goto error_out;
} } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) {
else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION)
{
sb->s_flags |= MS_RDONLY; sb->s_flags |= MS_RDONLY;
} }
...@@ -1613,31 +1724,30 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1613,31 +1724,30 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS); UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS);
} }
if ( !UDF_SB_NUMPARTS(sb) ) if (!UDF_SB_NUMPARTS(sb)) {
{
printk("UDF-fs: No partition found (2)\n"); printk("UDF-fs: No partition found (2)\n");
goto error_out; goto error_out;
} }
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) { if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
printk("UDF-fs: Partition marked readonly; forcing readonly mount\n"); UDF_PART_FLAG_READ_ONLY) {
printk
("UDF-fs: Partition marked readonly; forcing readonly mount\n");
sb->s_flags |= MS_RDONLY; sb->s_flags |= MS_RDONLY;
} }
if ( udf_find_fileset(sb, &fileset, &rootdir) ) if (udf_find_fileset(sb, &fileset, &rootdir)) {
{
printk("UDF-fs: No fileset found\n"); printk("UDF-fs: No fileset found\n");
goto error_out; goto error_out;
} }
if (!silent) if (!silent) {
{
kernel_timestamp ts; kernel_timestamp ts;
udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb)); udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb));
udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n", udf_info
UDFFS_VERSION, UDFFS_DATE, ("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute, UDFFS_VERSION, UDFFS_DATE, UDF_SB_VOLIDENT(sb), ts.year,
ts.typeAndTimezone); ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
} }
if (!(sb->s_flags & MS_RDONLY)) if (!(sb->s_flags & MS_RDONLY))
udf_open_lvid(sb); udf_open_lvid(sb);
...@@ -1645,18 +1755,16 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1645,18 +1755,16 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
/* Assign the root inode */ /* Assign the root inode */
/* assign inodes by physical block number */ /* assign inodes by physical block number */
/* perhaps it's not extensible enough, but for now ... */ /* perhaps it's not extensible enough, but for now ... */
inode = udf_iget(sb, rootdir); inode = udf_iget(sb, rootdir);
if (!inode) if (!inode) {
{
printk("UDF-fs: Error in udf_iget, block=%d, partition=%d\n", printk("UDF-fs: Error in udf_iget, block=%d, partition=%d\n",
rootdir.logicalBlockNum, rootdir.partitionReferenceNum); rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
goto error_out; goto error_out;
} }
/* Allocate a dentry for the root inode */ /* Allocate a dentry for the root inode */
sb->s_root = d_alloc_root(inode); sb->s_root = d_alloc_root(inode);
if (!sb->s_root) if (!sb->s_root) {
{
printk("UDF-fs: Couldn't allocate root dentry\n"); printk("UDF-fs: Couldn't allocate root dentry\n");
iput(inode); iput(inode);
goto error_out; goto error_out;
...@@ -1664,23 +1772,30 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1664,23 +1772,30 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
return 0; return 0;
error_out: error_out:
if (UDF_SB_VAT(sb)) if (UDF_SB_VAT(sb))
iput(UDF_SB_VAT(sb)); iput(UDF_SB_VAT(sb));
if (UDF_SB_NUMPARTS(sb)) if (UDF_SB_NUMPARTS(sb)) {
{ if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE) UDF_PART_FLAG_UNALLOC_TABLE)
iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table); iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE) s_table);
iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table); if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP) UDF_PART_FLAG_FREED_TABLE)
UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace); iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP) s_table);
UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace); if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) UDF_PART_FLAG_UNALLOC_BITMAP)
{ UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_uspace);
for (i=0; i<4; i++) if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); UDF_PART_FLAG_FREED_BITMAP)
UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_fspace);
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) ==
UDF_SPARABLE_MAP15) {
for (i = 0; i < 4; i++)
brelse(UDF_SB_TYPESPAR
(sb,
UDF_SB_PARTITION(sb)).s_spar_map[i]);
} }
} }
#ifdef CONFIG_UDF_NLS #ifdef CONFIG_UDF_NLS
...@@ -1697,32 +1812,31 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ...@@ -1697,32 +1812,31 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
} }
void udf_error(struct super_block *sb, const char *function, void udf_error(struct super_block *sb, const char *function,
const char *fmt, ...) const char *fmt, ...)
{ {
va_list args; va_list args;
if (!(sb->s_flags & MS_RDONLY)) if (!(sb->s_flags & MS_RDONLY)) {
{
/* mark sb error */ /* mark sb error */
sb->s_dirt = 1; sb->s_dirt = 1;
} }
va_start(args, fmt); va_start(args, fmt);
vsnprintf(error_buf, sizeof(error_buf), fmt, args); vsnprintf(error_buf, sizeof(error_buf), fmt, args);
va_end(args); va_end(args);
printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n", printk(KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
sb->s_id, function, error_buf); sb->s_id, function, error_buf);
} }
void udf_warning(struct super_block *sb, const char *function, void udf_warning(struct super_block *sb, const char *function,
const char *fmt, ...) const char *fmt, ...)
{ {
va_list args; va_list args;
va_start (args, fmt); va_start(args, fmt);
vsnprintf(error_buf, sizeof(error_buf), fmt, args); vsnprintf(error_buf, sizeof(error_buf), fmt, args);
va_end(args); va_end(args);
printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n", printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n",
sb->s_id, function, error_buf); sb->s_id, function, error_buf);
} }
/* /*
...@@ -1738,27 +1852,33 @@ void udf_warning(struct super_block *sb, const char *function, ...@@ -1738,27 +1852,33 @@ void udf_warning(struct super_block *sb, const char *function,
* July 1, 1997 - Andrew E. Mileski * July 1, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
static void static void udf_put_super(struct super_block *sb)
udf_put_super(struct super_block *sb)
{ {
int i; int i;
if (UDF_SB_VAT(sb)) if (UDF_SB_VAT(sb))
iput(UDF_SB_VAT(sb)); iput(UDF_SB_VAT(sb));
if (UDF_SB_NUMPARTS(sb)) if (UDF_SB_NUMPARTS(sb)) {
{ if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE) UDF_PART_FLAG_UNALLOC_TABLE)
iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table); iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE) s_table);
iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table); if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP) UDF_PART_FLAG_FREED_TABLE)
UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace); iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.
if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP) s_table);
UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace); if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) UDF_PART_FLAG_UNALLOC_BITMAP)
{ UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_uspace);
for (i=0; i<4; i++) if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]); UDF_PART_FLAG_FREED_BITMAP)
UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_fspace);
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) ==
UDF_SPARABLE_MAP15) {
for (i = 0; i < 4; i++)
brelse(UDF_SB_TYPESPAR
(sb,
UDF_SB_PARTITION(sb)).s_spar_map[i]);
} }
} }
#ifdef CONFIG_UDF_NLS #ifdef CONFIG_UDF_NLS
...@@ -1786,8 +1906,7 @@ udf_put_super(struct super_block *sb) ...@@ -1786,8 +1906,7 @@ udf_put_super(struct super_block *sb)
* July 1, 1997 - Andrew E. Mileski * July 1, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
static int static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
udf_statfs(struct dentry *dentry, struct kstatfs *buf)
{ {
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
...@@ -1797,11 +1916,12 @@ udf_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -1797,11 +1916,12 @@ udf_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_bfree = udf_count_free(sb); buf->f_bfree = udf_count_free(sb);
buf->f_bavail = buf->f_bfree; buf->f_bavail = buf->f_bfree;
buf->f_files = (UDF_SB_LVIDBH(sb) ? buf->f_files = (UDF_SB_LVIDBH(sb) ?
(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + (le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) +
le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + buf->f_bfree; le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) +
buf->f_bfree;
buf->f_ffree = buf->f_bfree; buf->f_ffree = buf->f_bfree;
/* __kernel_fsid_t f_fsid */ /* __kernel_fsid_t f_fsid */
buf->f_namelen = UDF_NAME_LEN-2; buf->f_namelen = UDF_NAME_LEN - 2;
return 0; return 0;
} }
...@@ -1830,13 +1950,10 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) ...@@ -1830,13 +1950,10 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
loc.partitionReferenceNum = UDF_SB_PARTITION(sb); loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
bh = udf_read_ptagged(sb, loc, 0, &ident); bh = udf_read_ptagged(sb, loc, 0, &ident);
if (!bh) if (!bh) {
{
printk(KERN_ERR "udf: udf_count_free failed\n"); printk(KERN_ERR "udf: udf_count_free failed\n");
goto out; goto out;
} } else if (ident != TAG_IDENT_SBD) {
else if (ident != TAG_IDENT_SBD)
{
brelse(bh); brelse(bh);
printk(KERN_ERR "udf: udf_count_free failed\n"); printk(KERN_ERR "udf: udf_count_free failed\n");
goto out; goto out;
...@@ -1844,43 +1961,39 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) ...@@ -1844,43 +1961,39 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
bm = (struct spaceBitmapDesc *)bh->b_data; bm = (struct spaceBitmapDesc *)bh->b_data;
bytes = le32_to_cpu(bm->numOfBytes); bytes = le32_to_cpu(bm->numOfBytes);
index = sizeof(struct spaceBitmapDesc); /* offset in first block only */ index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
ptr = (uint8_t *)bh->b_data; ptr = (uint8_t *) bh->b_data;
while ( bytes > 0 ) while (bytes > 0) {
{ while ((bytes > 0) && (index < sb->s_blocksize)) {
while ((bytes > 0) && (index < sb->s_blocksize))
{
value = ptr[index]; value = ptr[index];
accum += udf_bitmap_lookup[ value & 0x0f ]; accum += udf_bitmap_lookup[value & 0x0f];
accum += udf_bitmap_lookup[ value >> 4 ]; accum += udf_bitmap_lookup[value >> 4];
index++; index++;
bytes--; bytes--;
} }
if ( bytes ) if (bytes) {
{
brelse(bh); brelse(bh);
newblock = udf_get_lb_pblock(sb, loc, ++block); newblock = udf_get_lb_pblock(sb, loc, ++block);
bh = udf_tread(sb, newblock); bh = udf_tread(sb, newblock);
if (!bh) if (!bh) {
{
udf_debug("read failed\n"); udf_debug("read failed\n");
goto out; goto out;
} }
index = 0; index = 0;
ptr = (uint8_t *)bh->b_data; ptr = (uint8_t *) bh->b_data;
} }
} }
brelse(bh); brelse(bh);
out: out:
unlock_kernel(); unlock_kernel();
return accum; return accum;
} }
static unsigned int static unsigned int
udf_count_free_table(struct super_block *sb, struct inode * table) udf_count_free_table(struct super_block *sb, struct inode *table)
{ {
unsigned int accum = 0; unsigned int accum = 0;
uint32_t elen; uint32_t elen;
...@@ -1902,17 +2015,17 @@ udf_count_free_table(struct super_block *sb, struct inode * table) ...@@ -1902,17 +2015,17 @@ udf_count_free_table(struct super_block *sb, struct inode * table)
return accum; return accum;
} }
static unsigned int static unsigned int udf_count_free(struct super_block *sb)
udf_count_free(struct super_block *sb)
{ {
unsigned int accum = 0; unsigned int accum = 0;
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb)) {
{ if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) >
if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb)) UDF_SB_PARTITION(sb)) {
{ accum =
accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]); le32_to_cpu(UDF_SB_LVID(sb)->
freeSpaceTable[UDF_SB_PARTITION(sb)]);
if (accum == 0xFFFFFFFF) if (accum == 0xFFFFFFFF)
accum = 0; accum = 0;
...@@ -1922,28 +2035,40 @@ udf_count_free(struct super_block *sb) ...@@ -1922,28 +2035,40 @@ udf_count_free(struct super_block *sb)
if (accum) if (accum)
return accum; return accum;
if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP) if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
{ UDF_PART_FLAG_UNALLOC_BITMAP) {
accum += udf_count_free_bitmap(sb, accum +=
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap); udf_count_free_bitmap(sb,
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
(sb)].s_uspace.
s_bitmap);
} }
if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP) if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
{ UDF_PART_FLAG_FREED_BITMAP) {
accum += udf_count_free_bitmap(sb, accum +=
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap); udf_count_free_bitmap(sb,
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
(sb)].s_fspace.
s_bitmap);
} }
if (accum) if (accum)
return accum; return accum;
if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE) if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
{ UDF_PART_FLAG_UNALLOC_TABLE) {
accum += udf_count_free_table(sb, accum +=
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table); udf_count_free_table(sb,
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
(sb)].s_uspace.
s_table);
} }
if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE) if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
{ UDF_PART_FLAG_FREED_TABLE) {
accum += udf_count_free_table(sb, accum +=
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table); udf_count_free_table(sb,
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
(sb)].s_fspace.
s_table);
} }
return accum; return accum;
......
...@@ -33,41 +33,40 @@ ...@@ -33,41 +33,40 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include "udf_i.h" #include "udf_i.h"
static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to) static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen,
char *to)
{ {
struct pathComponent *pc; struct pathComponent *pc;
int elen = 0; int elen = 0;
char *p = to; char *p = to;
while (elen < fromlen) while (elen < fromlen) {
{
pc = (struct pathComponent *)(from + elen); pc = (struct pathComponent *)(from + elen);
switch (pc->componentType) switch (pc->componentType) {
{ case 1:
case 1: if (pc->lengthComponentIdent == 0) {
if (pc->lengthComponentIdent == 0) p = to;
{
p = to;
*p++ = '/';
}
break;
case 3:
memcpy(p, "../", 3);
p += 3;
break;
case 4:
memcpy(p, "./", 2);
p += 2;
/* that would be . - just ignore */
break;
case 5:
p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent);
*p++ = '/'; *p++ = '/';
break; }
break;
case 3:
memcpy(p, "../", 3);
p += 3;
break;
case 4:
memcpy(p, "./", 2);
p += 2;
/* that would be . - just ignore */
break;
case 5:
p += udf_get_filename(sb, pc->componentIdent, p,
pc->lengthComponentIdent);
*p++ = '/';
break;
} }
elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
} }
if (p > to+1) if (p > to + 1)
p[-1] = '\0'; p[-1] = '\0';
else else
p[0] = '\0'; p[0] = '\0';
...@@ -84,8 +83,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) ...@@ -84,8 +83,7 @@ static int udf_symlink_filler(struct file *file, struct page *page)
lock_kernel(); lock_kernel();
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
else else {
{
bh = sb_bread(inode->i_sb, udf_block_map(inode, 0)); bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
if (!bh) if (!bh)
...@@ -102,7 +100,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) ...@@ -102,7 +100,7 @@ static int udf_symlink_filler(struct file *file, struct page *page)
kunmap(page); kunmap(page);
unlock_page(page); unlock_page(page);
return 0; return 0;
out: out:
unlock_kernel(); unlock_kernel();
SetPageError(page); SetPageError(page);
kunmap(page); kunmap(page);
...@@ -114,5 +112,5 @@ static int udf_symlink_filler(struct file *file, struct page *page) ...@@ -114,5 +112,5 @@ static int udf_symlink_filler(struct file *file, struct page *page)
* symlinks can't do much... * symlinks can't do much...
*/ */
const struct address_space_operations udf_symlink_aops = { const struct address_space_operations udf_symlink_aops = {
.readpage = udf_symlink_filler, .readpage = udf_symlink_filler,
}; };
...@@ -28,35 +28,38 @@ ...@@ -28,35 +28,38 @@
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
static void extent_trunc(struct inode * inode, struct extent_position *epos, static void extent_trunc(struct inode *inode, struct extent_position *epos,
kernel_lb_addr eloc, int8_t etype, uint32_t elen, uint32_t nelen) kernel_lb_addr eloc, int8_t etype, uint32_t elen,
uint32_t nelen)
{ {
kernel_lb_addr neloc = { 0, 0 }; kernel_lb_addr neloc = { 0, 0 };
int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; int last_block =
int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; (elen + inode->i_sb->s_blocksize -
1) >> inode->i_sb->s_blocksize_bits;
int first_block =
(nelen + inode->i_sb->s_blocksize -
1) >> inode->i_sb->s_blocksize_bits;
if (nelen) if (nelen) {
{ if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) udf_free_blocks(inode->i_sb, inode, eloc, 0,
{ last_block);
udf_free_blocks(inode->i_sb, inode, eloc, 0, last_block);
etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30); etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30);
} } else
else
neloc = eloc; neloc = eloc;
nelen = (etype << 30) | nelen; nelen = (etype << 30) | nelen;
} }
if (elen != 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 (last_block - first_block > 0) {
{
if (etype == (EXT_RECORDED_ALLOCATED >> 30)) if (etype == (EXT_RECORDED_ALLOCATED >> 30))
mark_inode_dirty(inode); mark_inode_dirty(inode);
if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
udf_free_blocks(inode->i_sb, inode, eloc, first_block, last_block - first_block); udf_free_blocks(inode->i_sb, inode, eloc,
first_block,
last_block - first_block);
} }
} }
} }
...@@ -67,7 +70,7 @@ static void extent_trunc(struct inode * inode, struct extent_position *epos, ...@@ -67,7 +70,7 @@ static void extent_trunc(struct inode * inode, struct extent_position *epos,
*/ */
void udf_truncate_tail_extent(struct inode *inode) void udf_truncate_tail_extent(struct inode *inode)
{ {
struct extent_position epos = { NULL, 0, {0, 0}}; struct extent_position epos = { NULL, 0, {0, 0} };
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen, nelen; uint32_t elen, nelen;
uint64_t lbcount = 0; uint64_t lbcount = 0;
...@@ -89,8 +92,7 @@ void udf_truncate_tail_extent(struct inode *inode) ...@@ -89,8 +92,7 @@ void udf_truncate_tail_extent(struct inode *inode)
BUG(); BUG();
/* Find the last extent in the file */ /* Find the last extent in the file */
while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
{
etype = netype; etype = netype;
lbcount += elen; lbcount += elen;
if (lbcount > inode->i_size) { if (lbcount > inode->i_size) {
...@@ -123,7 +125,7 @@ void udf_truncate_tail_extent(struct inode *inode) ...@@ -123,7 +125,7 @@ void udf_truncate_tail_extent(struct inode *inode)
void udf_discard_prealloc(struct inode *inode) void udf_discard_prealloc(struct inode *inode)
{ {
struct extent_position epos = { NULL, 0, {0, 0}}; struct extent_position epos = { NULL, 0, {0, 0} };
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen; uint32_t elen;
uint64_t lbcount = 0; uint64_t lbcount = 0;
...@@ -131,7 +133,7 @@ void udf_discard_prealloc(struct inode *inode) ...@@ -131,7 +133,7 @@ void udf_discard_prealloc(struct inode *inode)
int adsize; int adsize;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ||
inode->i_size == UDF_I_LENEXTENTS(inode)) inode->i_size == UDF_I_LENEXTENTS(inode))
return; return;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
...@@ -153,15 +155,21 @@ void udf_discard_prealloc(struct inode *inode) ...@@ -153,15 +155,21 @@ void udf_discard_prealloc(struct inode *inode)
lbcount -= elen; lbcount -= elen;
extent_trunc(inode, &epos, eloc, etype, elen, 0); extent_trunc(inode, &epos, eloc, etype, elen, 0);
if (!epos.bh) { if (!epos.bh) {
UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode); UDF_I_LENALLOC(inode) =
epos.offset - udf_file_entry_alloc_offset(inode);
mark_inode_dirty(inode); mark_inode_dirty(inode);
} else { } else {
struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); struct allocExtDesc *aed =
aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc)); (struct allocExtDesc *)(epos.bh->b_data);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) aed->lengthAllocDescs =
cpu_to_le32(epos.offset -
sizeof(struct allocExtDesc));
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
|| UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(epos.bh->b_data, epos.offset); udf_update_tag(epos.bh->b_data, epos.offset);
else else
udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos.bh->b_data,
sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(epos.bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
} }
} }
...@@ -171,7 +179,7 @@ void udf_discard_prealloc(struct inode *inode) ...@@ -171,7 +179,7 @@ void udf_discard_prealloc(struct inode *inode)
brelse(epos.bh); brelse(epos.bh);
} }
void udf_truncate_extents(struct inode * inode) void udf_truncate_extents(struct inode *inode)
{ {
struct extent_position epos; struct extent_position epos;
kernel_lb_addr eloc, neloc = { 0, 0 }; kernel_lb_addr eloc, neloc = { 0, 0 };
...@@ -190,9 +198,10 @@ void udf_truncate_extents(struct inode * inode) ...@@ -190,9 +198,10 @@ void udf_truncate_extents(struct inode * inode)
BUG(); BUG();
etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
byte_offset = (offset << sb->s_blocksize_bits) + (inode->i_size & (sb->s_blocksize-1)); byte_offset =
if (etype != -1) (offset << sb->s_blocksize_bits) +
{ (inode->i_size & (sb->s_blocksize - 1));
if (etype != -1) {
epos.offset -= adsize; epos.offset -= adsize;
extent_trunc(inode, &epos, eloc, etype, elen, byte_offset); extent_trunc(inode, &epos, eloc, etype, elen, byte_offset);
epos.offset += adsize; epos.offset += adsize;
...@@ -206,86 +215,98 @@ void udf_truncate_extents(struct inode * inode) ...@@ -206,86 +215,98 @@ void udf_truncate_extents(struct inode * inode)
else else
lenalloc -= sizeof(struct allocExtDesc); lenalloc -= sizeof(struct allocExtDesc);
while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) while ((etype =
{ udf_current_aext(inode, &epos, &eloc, &elen,
if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) 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) if (indirect_ext_len) {
{
/* We managed to free all extents in the /* We managed to free all extents in the
* indirect extent - free it too */ * indirect extent - free it too */
if (!epos.bh) if (!epos.bh)
BUG(); BUG();
udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len); udf_free_blocks(sb, inode, epos.block,
} 0, indirect_ext_len);
else } else {
{ if (!epos.bh) {
if (!epos.bh) UDF_I_LENALLOC(inode) =
{ lenalloc;
UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} } else {
else struct allocExtDesc *aed =
{ (struct allocExtDesc
struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc); aed->lengthAllocDescs =
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201) cpu_to_le32(lenalloc);
udf_update_tag(epos.bh->b_data, lenalloc + if (!UDF_QUERY_FLAG
sizeof(struct allocExtDesc)); (sb, UDF_FLAG_STRICT)
|| UDF_SB_UDFREV(sb) >=
0x0201)
udf_update_tag(epos.bh->
b_data,
lenalloc
+
sizeof
(struct
allocExtDesc));
else else
udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos.bh->
mark_buffer_dirty_inode(epos.bh, inode); b_data,
sizeof
(struct
allocExtDesc));
mark_buffer_dirty_inode(epos.bh,
inode);
} }
} }
brelse(epos.bh); brelse(epos.bh);
epos.offset = sizeof(struct allocExtDesc); epos.offset = sizeof(struct allocExtDesc);
epos.block = eloc; epos.block = eloc;
epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0)); epos.bh =
udf_tread(sb,
udf_get_lb_pblock(sb, eloc, 0));
if (elen) if (elen)
indirect_ext_len = (elen + indirect_ext_len = (elen +
sb->s_blocksize - 1) >> sb->s_blocksize -
sb->s_blocksize_bits; 1) >> sb->
s_blocksize_bits;
else else
indirect_ext_len = 1; indirect_ext_len = 1;
} } else {
else extent_trunc(inode, &epos, eloc, etype, elen,
{ 0);
extent_trunc(inode, &epos, eloc, etype, elen, 0);
epos.offset += adsize; epos.offset += adsize;
} }
} }
if (indirect_ext_len) if (indirect_ext_len) {
{
if (!epos.bh) if (!epos.bh)
BUG(); BUG();
udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len); udf_free_blocks(sb, inode, epos.block, 0,
} indirect_ext_len);
else } else {
{ if (!epos.bh) {
if (!epos.bh)
{
UDF_I_LENALLOC(inode) = lenalloc; UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} } else {
else struct allocExtDesc *aed =
{ (struct allocExtDesc *)(epos.bh->b_data);
struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc); aed->lengthAllocDescs = cpu_to_le32(lenalloc);
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201) if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)
udf_update_tag(epos.bh->b_data, lenalloc + || UDF_SB_UDFREV(sb) >= 0x0201)
sizeof(struct allocExtDesc)); udf_update_tag(epos.bh->b_data,
lenalloc +
sizeof(struct
allocExtDesc));
else else
udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos.bh->b_data,
sizeof(struct
allocExtDesc));
mark_buffer_dirty_inode(epos.bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
} }
} }
} } else if (inode->i_size) {
else if (inode->i_size) if (byte_offset) {
{
if (byte_offset)
{
kernel_long_ad extent; kernel_long_ad extent;
/* /*
...@@ -293,21 +314,33 @@ void udf_truncate_extents(struct inode * inode) ...@@ -293,21 +314,33 @@ void udf_truncate_extents(struct inode * inode)
* no extent above inode->i_size => truncate is * no extent above inode->i_size => truncate is
* extending the file by 'offset' blocks. * extending the file by 'offset' blocks.
*/ */
if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || if ((!epos.bh
(epos.bh && epos.offset == sizeof(struct allocExtDesc))) { && epos.offset ==
udf_file_entry_alloc_offset(inode)) || (epos.bh
&& epos.
offset ==
sizeof
(struct
allocExtDesc)))
{
/* File has no extents at all or has empty last /* File has no extents at all or has empty last
* indirect extent! Create a fake extent... */ * indirect extent! Create a fake extent... */
extent.extLocation.logicalBlockNum = 0; extent.extLocation.logicalBlockNum = 0;
extent.extLocation.partitionReferenceNum = 0; extent.extLocation.partitionReferenceNum = 0;
extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; extent.extLength =
} EXT_NOT_RECORDED_NOT_ALLOCATED;
else { } else {
epos.offset -= adsize; epos.offset -= adsize;
etype = udf_next_aext(inode, &epos, etype = udf_next_aext(inode, &epos,
&extent.extLocation, &extent.extLength, 0); &extent.extLocation,
&extent.extLength, 0);
extent.extLength |= etype << 30; extent.extLength |= etype << 30;
} }
udf_extend_file(inode, &epos, &extent, offset+((inode->i_size & (sb->s_blocksize-1)) != 0)); udf_extend_file(inode, &epos, &extent,
offset +
((inode->
i_size & (sb->s_blocksize - 1)) !=
0));
} }
} }
UDF_I_LENEXTENTS(inode) = inode->i_size; UDF_I_LENEXTENTS(inode) = inode->i_size;
......
...@@ -23,4 +23,4 @@ static inline struct udf_inode_info *UDF_I(struct inode *inode) ...@@ -23,4 +23,4 @@ static inline struct udf_inode_info *UDF_I(struct inode *inode)
#define UDF_I_LAD(X) ( UDF_I(X)->i_ext.i_lad ) #define UDF_I_LAD(X) ( UDF_I(X)->i_ext.i_lad )
#define UDF_I_DATA(X) ( UDF_I(X)->i_ext.i_data ) #define UDF_I_DATA(X) ( UDF_I(X)->i_ext.i_data )
#endif /* !defined(_LINUX_UDF_I_H) */ #endif /* !defined(_LINUX_UDF_I_H) */
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
#define UDF_FLAG_VARCONV 8 #define UDF_FLAG_VARCONV 8
#define UDF_FLAG_NLS_MAP 9 #define UDF_FLAG_NLS_MAP 9
#define UDF_FLAG_UTF8 10 #define UDF_FLAG_UTF8 10
#define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */ #define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */
#define UDF_FLAG_UID_IGNORE 12 /* use sb uid instead of on disk uid */ #define UDF_FLAG_UID_IGNORE 12 /* use sb uid instead of on disk uid */
#define UDF_FLAG_GID_FORGET 13 #define UDF_FLAG_GID_FORGET 13
#define UDF_FLAG_GID_IGNORE 14 #define UDF_FLAG_GID_IGNORE 14
...@@ -139,4 +139,4 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb) ...@@ -139,4 +139,4 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
#define UDF_SB_FLAGS(X) ( UDF_SB(X)->s_flags ) #define UDF_SB_FLAGS(X) ( UDF_SB(X)->s_flags )
#define UDF_SB_VAT(X) ( UDF_SB(X)->s_vat ) #define UDF_SB_VAT(X) ( UDF_SB(X)->s_vat )
#endif /* __LINUX_UDF_SB_H */ #endif /* __LINUX_UDF_SB_H */
...@@ -50,30 +50,26 @@ extern const struct address_space_operations udf_aops; ...@@ -50,30 +50,26 @@ extern const struct address_space_operations udf_aops;
extern const struct address_space_operations udf_adinicb_aops; extern const struct address_space_operations udf_adinicb_aops;
extern const struct address_space_operations udf_symlink_aops; extern const struct address_space_operations udf_symlink_aops;
struct udf_fileident_bh struct udf_fileident_bh {
{
struct buffer_head *sbh; struct buffer_head *sbh;
struct buffer_head *ebh; struct buffer_head *ebh;
int soffset; int soffset;
int eoffset; int eoffset;
}; };
struct udf_vds_record struct udf_vds_record {
{
uint32_t block; uint32_t block;
uint32_t volDescSeqNum; uint32_t volDescSeqNum;
}; };
struct generic_desc struct generic_desc {
{ tag descTag;
tag descTag; __le32 volDescSeqNum;
__le32 volDescSeqNum;
}; };
struct ustr struct ustr {
{
uint8_t u_cmpID; uint8_t u_cmpID;
uint8_t u_name[UDF_NAME_LEN-2]; uint8_t u_name[UDF_NAME_LEN - 2];
uint8_t u_len; uint8_t u_len;
}; };
...@@ -83,44 +79,58 @@ struct extent_position { ...@@ -83,44 +79,58 @@ struct extent_position {
kernel_lb_addr block; kernel_lb_addr block;
}; };
/* super.c */ /* super.c */
extern void udf_error(struct super_block *, const char *, const char *, ...); extern void udf_error(struct super_block *, const char *, const char *, ...);
extern void udf_warning(struct super_block *, const char *, const char *, ...); extern void udf_warning(struct super_block *, const char *, const char *, ...);
/* namei.c */ /* namei.c */
extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, struct fileIdentDesc *, struct udf_fileident_bh *, uint8_t *, uint8_t *); extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
struct fileIdentDesc *, struct udf_fileident_bh *,
uint8_t *, uint8_t *);
/* file.c */ /* file.c */
extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long); extern int udf_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
/* inode.c */ /* inode.c */
extern struct inode *udf_iget(struct super_block *, kernel_lb_addr); extern struct inode *udf_iget(struct super_block *, kernel_lb_addr);
extern int udf_sync_inode(struct inode *); extern int udf_sync_inode(struct inode *);
extern void udf_expand_file_adinicb(struct inode *, int, int *); extern void udf_expand_file_adinicb(struct inode *, int, int *);
extern struct buffer_head * udf_expand_dir_adinicb(struct inode *, int *, int *); extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *);
extern struct buffer_head * udf_bread(struct inode *, int, int, int *); extern struct buffer_head *udf_bread(struct inode *, int, int, int *);
extern void udf_truncate(struct inode *); extern void udf_truncate(struct inode *);
extern void udf_read_inode(struct inode *); extern void udf_read_inode(struct inode *);
extern void udf_delete_inode(struct inode *); extern void udf_delete_inode(struct inode *);
extern void udf_clear_inode(struct inode *); extern void udf_clear_inode(struct inode *);
extern int udf_write_inode(struct inode *, int); extern int udf_write_inode(struct inode *, int);
extern long udf_block_map(struct inode *, sector_t); extern long udf_block_map(struct inode *, sector_t);
extern int udf_extend_file(struct inode *, struct extent_position *, kernel_long_ad *, sector_t); extern int udf_extend_file(struct inode *, struct extent_position *,
extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *); kernel_long_ad *, sector_t);
extern int8_t udf_add_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int); extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
extern int8_t udf_write_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int); kernel_lb_addr *, uint32_t *, sector_t *);
extern int8_t udf_delete_aext(struct inode *, struct extent_position, kernel_lb_addr, uint32_t); extern int8_t udf_add_aext(struct inode *, struct extent_position *,
extern int8_t udf_next_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); kernel_lb_addr, uint32_t, int);
extern int8_t udf_current_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int); extern int8_t udf_write_aext(struct inode *, struct extent_position *,
kernel_lb_addr, uint32_t, int);
extern int8_t udf_delete_aext(struct inode *, struct extent_position,
kernel_lb_addr, uint32_t);
extern int8_t udf_next_aext(struct inode *, struct extent_position *,
kernel_lb_addr *, uint32_t *, int);
extern int8_t udf_current_aext(struct inode *, struct extent_position *,
kernel_lb_addr *, uint32_t *, int);
/* misc.c */ /* misc.c */
extern struct buffer_head *udf_tgetblk(struct super_block *, int); extern struct buffer_head *udf_tgetblk(struct super_block *, int);
extern struct buffer_head *udf_tread(struct super_block *, int); extern struct buffer_head *udf_tread(struct super_block *, int);
extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, uint32_t, uint8_t); extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t,
extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t); uint32_t, uint8_t);
extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *); extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t,
extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *); uint8_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,
uint16_t *);
extern void udf_update_tag(char *, int); extern void udf_update_tag(char *, int);
extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int); extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
...@@ -129,21 +139,26 @@ extern unsigned int udf_get_last_session(struct super_block *); ...@@ -129,21 +139,26 @@ extern unsigned int udf_get_last_session(struct super_block *);
extern unsigned long udf_get_last_block(struct super_block *); extern unsigned long udf_get_last_block(struct super_block *);
/* partition.c */ /* partition.c */
extern uint32_t udf_get_pblock(struct super_block *, uint32_t, uint16_t, uint32_t); extern uint32_t udf_get_pblock(struct super_block *, uint32_t, uint16_t,
extern uint32_t udf_get_pblock_virt15(struct super_block *, uint32_t, uint16_t, uint32_t); uint32_t);
extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t, uint32_t); extern uint32_t udf_get_pblock_virt15(struct super_block *, uint32_t, uint16_t,
extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, uint32_t); uint32_t);
extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t,
uint32_t);
extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t,
uint32_t);
extern int udf_relocate_blocks(struct super_block *, long, long *); extern int udf_relocate_blocks(struct super_block *, long, long *);
/* unicode.c */ /* unicode.c */
extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); 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 *, int); extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *,
int);
extern int udf_build_ustr(struct ustr *, dstring *, int); extern int udf_build_ustr(struct ustr *, dstring *, int);
extern int udf_CS0toUTF8(struct ustr *, struct ustr *); extern int udf_CS0toUTF8(struct ustr *, struct ustr *);
/* ialloc.c */ /* ialloc.c */
extern void udf_free_inode(struct inode *); extern void udf_free_inode(struct inode *);
extern struct inode * udf_new_inode (struct inode *, int, int *); extern struct inode *udf_new_inode(struct inode *, int, int *);
/* truncate.c */ /* truncate.c */
extern void udf_truncate_tail_extent(struct inode *); extern void udf_truncate_tail_extent(struct inode *);
...@@ -151,18 +166,27 @@ extern void udf_discard_prealloc(struct inode *); ...@@ -151,18 +166,27 @@ extern void udf_discard_prealloc(struct inode *);
extern void udf_truncate_extents(struct inode *); extern void udf_truncate_extents(struct inode *);
/* balloc.c */ /* balloc.c */
extern void udf_free_blocks(struct super_block *, struct inode *, kernel_lb_addr, uint32_t, uint32_t); extern void udf_free_blocks(struct super_block *, struct inode *,
extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, uint32_t, uint32_t); kernel_lb_addr, uint32_t, uint32_t);
extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_t, int *); 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,
uint32_t, int *);
/* fsync.c */ /* fsync.c */
extern int udf_fsync_file(struct file *, struct dentry *, int); extern int udf_fsync_file(struct file *, struct dentry *, int);
/* directory.c */ /* directory.c */
extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *); extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *,
extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset); struct udf_fileident_bh *,
extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int); struct fileIdentDesc *,
extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int); struct extent_position *,
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, int *, int);
extern short_ad *udf_get_fileshortad(uint8_t *, int, int *, int);
/* crc.c */ /* crc.c */
extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t); extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t);
...@@ -171,4 +195,4 @@ extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t); ...@@ -171,4 +195,4 @@ extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t);
extern time_t *udf_stamp_to_time(time_t *, long *, kernel_timestamp); extern time_t *udf_stamp_to_time(time_t *, long *, kernel_timestamp);
extern kernel_timestamp *udf_time_to_stamp(kernel_timestamp *, struct timespec); extern kernel_timestamp *udf_time_to_stamp(kernel_timestamp *, struct timespec);
#endif /* __UDF_DECL_H */ #endif /* __UDF_DECL_H */
...@@ -78,4 +78,4 @@ static inline timestamp cpu_to_lets(kernel_timestamp in) ...@@ -78,4 +78,4 @@ static inline timestamp cpu_to_lets(kernel_timestamp in)
return out; return out;
} }
#endif /* __UDF_ENDIAN_H */ #endif /* __UDF_ENDIAN_H */
...@@ -46,37 +46,36 @@ ...@@ -46,37 +46,36 @@
#endif #endif
/* How many days come before each month (0-12). */ /* How many days come before each month (0-12). */
static const unsigned short int __mon_yday[2][13] = static const unsigned short int __mon_yday[2][13] = {
{
/* Normal years. */ /* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
/* Leap years. */ /* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
}; };
#define MAX_YEAR_SECONDS 69 #define MAX_YEAR_SECONDS 69
#define SPD 0x15180 /*3600*24*/ #define SPD 0x15180 /*3600*24 */
#define SPY(y,l,s) (SPD * (365*y+l)+s) #define SPY(y,l,s) (SPD * (365*y+l)+s)
static time_t year_seconds[MAX_YEAR_SECONDS]= { static time_t year_seconds[MAX_YEAR_SECONDS] = {
/*1970*/ SPY( 0, 0,0), SPY( 1, 0,0), SPY( 2, 0,0), SPY( 3, 1,0), /*1970*/ SPY(0, 0, 0), SPY(1, 0, 0), SPY(2, 0, 0), SPY(3, 1, 0),
/*1974*/ SPY( 4, 1,0), SPY( 5, 1,0), SPY( 6, 1,0), SPY( 7, 2,0), /*1974*/ SPY(4, 1, 0), SPY(5, 1, 0), SPY(6, 1, 0), SPY(7, 2, 0),
/*1978*/ SPY( 8, 2,0), SPY( 9, 2,0), SPY(10, 2,0), SPY(11, 3,0), /*1978*/ SPY(8, 2, 0), SPY(9, 2, 0), SPY(10, 2, 0), SPY(11, 3, 0),
/*1982*/ SPY(12, 3,0), SPY(13, 3,0), SPY(14, 3,0), SPY(15, 4,0), /*1982*/ SPY(12, 3, 0), SPY(13, 3, 0), SPY(14, 3, 0), SPY(15, 4, 0),
/*1986*/ SPY(16, 4,0), SPY(17, 4,0), SPY(18, 4,0), SPY(19, 5,0), /*1986*/ SPY(16, 4, 0), SPY(17, 4, 0), SPY(18, 4, 0), SPY(19, 5, 0),
/*1990*/ SPY(20, 5,0), SPY(21, 5,0), SPY(22, 5,0), SPY(23, 6,0), /*1990*/ SPY(20, 5, 0), SPY(21, 5, 0), SPY(22, 5, 0), SPY(23, 6, 0),
/*1994*/ SPY(24, 6,0), SPY(25, 6,0), SPY(26, 6,0), SPY(27, 7,0), /*1994*/ SPY(24, 6, 0), SPY(25, 6, 0), SPY(26, 6, 0), SPY(27, 7, 0),
/*1998*/ SPY(28, 7,0), SPY(29, 7,0), SPY(30, 7,0), SPY(31, 8,0), /*1998*/ SPY(28, 7, 0), SPY(29, 7, 0), SPY(30, 7, 0), SPY(31, 8, 0),
/*2002*/ SPY(32, 8,0), SPY(33, 8,0), SPY(34, 8,0), SPY(35, 9,0), /*2002*/ SPY(32, 8, 0), SPY(33, 8, 0), SPY(34, 8, 0), SPY(35, 9, 0),
/*2006*/ SPY(36, 9,0), SPY(37, 9,0), SPY(38, 9,0), SPY(39,10,0), /*2006*/ SPY(36, 9, 0), SPY(37, 9, 0), SPY(38, 9, 0), SPY(39, 10, 0),
/*2010*/ SPY(40,10,0), SPY(41,10,0), SPY(42,10,0), SPY(43,11,0), /*2010*/ SPY(40, 10, 0), SPY(41, 10, 0), SPY(42, 10, 0), SPY(43, 11, 0),
/*2014*/ SPY(44,11,0), SPY(45,11,0), SPY(46,11,0), SPY(47,12,0), /*2014*/ SPY(44, 11, 0), SPY(45, 11, 0), SPY(46, 11, 0), SPY(47, 12, 0),
/*2018*/ SPY(48,12,0), SPY(49,12,0), SPY(50,12,0), SPY(51,13,0), /*2018*/ SPY(48, 12, 0), SPY(49, 12, 0), SPY(50, 12, 0), SPY(51, 13, 0),
/*2022*/ SPY(52,13,0), SPY(53,13,0), SPY(54,13,0), SPY(55,14,0), /*2022*/ SPY(52, 13, 0), SPY(53, 13, 0), SPY(54, 13, 0), SPY(55, 14, 0),
/*2026*/ SPY(56,14,0), SPY(57,14,0), SPY(58,14,0), SPY(59,15,0), /*2026*/ SPY(56, 14, 0), SPY(57, 14, 0), SPY(58, 14, 0), SPY(59, 15, 0),
/*2030*/ SPY(60,15,0), SPY(61,15,0), SPY(62,15,0), SPY(63,16,0), /*2030*/ SPY(60, 15, 0), SPY(61, 15, 0), SPY(62, 15, 0), SPY(63, 16, 0),
/*2034*/ SPY(64,16,0), SPY(65,16,0), SPY(66,16,0), SPY(67,17,0), /*2034*/ SPY(64, 16, 0), SPY(65, 16, 0), SPY(66, 16, 0), SPY(67, 17, 0),
/*2038*/ SPY(68,17,0) /*2038*/ SPY(68, 17, 0)
}; };
extern struct timezone sys_tz; extern struct timezone sys_tz;
...@@ -84,27 +83,23 @@ extern struct timezone sys_tz; ...@@ -84,27 +83,23 @@ extern struct timezone sys_tz;
#define SECS_PER_HOUR (60 * 60) #define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (SECS_PER_HOUR * 24) #define SECS_PER_DAY (SECS_PER_HOUR * 24)
time_t * time_t *udf_stamp_to_time(time_t * dest, long *dest_usec, kernel_timestamp src)
udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src)
{ {
int yday; int yday;
uint8_t type = src.typeAndTimezone >> 12; uint8_t type = src.typeAndTimezone >> 12;
int16_t offset; int16_t offset;
if (type == 1) if (type == 1) {
{
offset = src.typeAndTimezone << 4; offset = src.typeAndTimezone << 4;
/* sign extent offset */ /* sign extent offset */
offset = (offset >> 4); offset = (offset >> 4);
if (offset == -2047) /* unspecified offset */ if (offset == -2047) /* unspecified offset */
offset = 0; offset = 0;
} } else
else
offset = 0; offset = 0;
if ((src.year < EPOCH_YEAR) || if ((src.year < EPOCH_YEAR) ||
(src.year >= EPOCH_YEAR+MAX_YEAR_SECONDS)) (src.year >= EPOCH_YEAR + MAX_YEAR_SECONDS)) {
{
*dest = -1; *dest = -1;
*dest_usec = -1; *dest_usec = -1;
return NULL; return NULL;
...@@ -112,16 +107,16 @@ udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src) ...@@ -112,16 +107,16 @@ udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src)
*dest = year_seconds[src.year - EPOCH_YEAR]; *dest = year_seconds[src.year - EPOCH_YEAR];
*dest -= offset * 60; *dest -= offset * 60;
yday = ((__mon_yday[__isleap (src.year)] yday = ((__mon_yday[__isleap(src.year)]
[src.month-1]) + (src.day-1)); [src.month - 1]) + (src.day - 1));
*dest += ( ( (yday* 24) + src.hour ) * 60 + src.minute ) * 60 + src.second; *dest += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second;
*dest_usec = src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 + src.microseconds; *dest_usec =
src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 +
src.microseconds;
return dest; return dest;
} }
kernel_timestamp *udf_time_to_stamp(kernel_timestamp * dest, struct timespec ts)
kernel_timestamp *
udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts)
{ {
long int days, rem, y; long int days, rem, y;
const unsigned short int *ip; const unsigned short int *ip;
...@@ -146,28 +141,28 @@ udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts) ...@@ -146,28 +141,28 @@ udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts)
#define DIV(a,b) ((a) / (b) - ((a) % (b) < 0)) #define DIV(a,b) ((a) / (b) - ((a) % (b) < 0))
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
while (days < 0 || days >= (__isleap(y) ? 366 : 365)) while (days < 0 || days >= (__isleap(y) ? 366 : 365)) {
{
long int yg = y + days / 365 - (days % 365 < 0); long int yg = y + days / 365 - (days % 365 < 0);
/* Adjust DAYS and Y to match the guessed year. */ /* Adjust DAYS and Y to match the guessed year. */
days -= ((yg - y) * 365 days -= ((yg - y) * 365 + LEAPS_THRU_END_OF(yg - 1)
+ LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF(y - 1));
- LEAPS_THRU_END_OF (y - 1));
y = yg; y = yg;
} }
dest->year = y; dest->year = y;
ip = __mon_yday[__isleap(y)]; ip = __mon_yday[__isleap(y)];
for (y = 11; days < (long int) ip[y]; --y) for (y = 11; days < (long int)ip[y]; --y)
continue; continue;
days -= ip[y]; days -= ip[y];
dest->month = y + 1; dest->month = y + 1;
dest->day = days + 1; dest->day = days + 1;
dest->centiseconds = ts.tv_nsec / 10000000; dest->centiseconds = ts.tv_nsec / 10000000;
dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000) / 100; dest->hundredsOfMicroseconds =
dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 - (ts.tv_nsec / 1000 - dest->centiseconds * 10000) / 100;
dest->hundredsOfMicroseconds * 100); dest->microseconds =
(ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
dest->hundredsOfMicroseconds * 100);
return dest; return dest;
} }
......
...@@ -29,9 +29,9 @@ ...@@ -29,9 +29,9 @@
static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int); static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) static int udf_char_to_ustr(struct ustr *dest, const uint8_t * src, int strlen)
{ {
if ( (!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN-2) ) if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN - 2))
return 0; return 0;
memset(dest, 0, sizeof(struct ustr)); memset(dest, 0, sizeof(struct ustr));
memcpy(dest->u_name, src, strlen); memcpy(dest->u_name, src, strlen);
...@@ -43,33 +43,33 @@ static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) ...@@ -43,33 +43,33 @@ static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
/* /*
* udf_build_ustr * udf_build_ustr
*/ */
int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) int udf_build_ustr(struct ustr *dest, dstring * ptr, int size)
{ {
int usesize; int usesize;
if ( (!dest) || (!ptr) || (!size) ) if ((!dest) || (!ptr) || (!size))
return -1; return -1;
memset(dest, 0, sizeof(struct ustr)); memset(dest, 0, sizeof(struct ustr));
usesize= (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size; usesize = (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size;
dest->u_cmpID=ptr[0]; dest->u_cmpID = ptr[0];
dest->u_len=ptr[size-1]; dest->u_len = ptr[size - 1];
memcpy(dest->u_name, ptr+1, usesize-1); memcpy(dest->u_name, ptr + 1, usesize - 1);
return 0; return 0;
} }
/* /*
* udf_build_ustr_exact * udf_build_ustr_exact
*/ */
static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) static int udf_build_ustr_exact(struct ustr *dest, dstring * ptr, int exactsize)
{ {
if ( (!dest) || (!ptr) || (!exactsize) ) if ((!dest) || (!ptr) || (!exactsize))
return -1; return -1;
memset(dest, 0, sizeof(struct ustr)); memset(dest, 0, sizeof(struct ustr));
dest->u_cmpID=ptr[0]; dest->u_cmpID = ptr[0];
dest->u_len=exactsize-1; dest->u_len = exactsize - 1;
memcpy(dest->u_name, ptr+1, exactsize-1); memcpy(dest->u_name, ptr + 1, exactsize - 1);
return 0; return 0;
} }
...@@ -108,22 +108,20 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i) ...@@ -108,22 +108,20 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
cmp_id = ocu_i->u_cmpID; cmp_id = ocu_i->u_cmpID;
utf_o->u_len = 0; utf_o->u_len = 0;
if (ocu_len == 0) if (ocu_len == 0) {
{
memset(utf_o, 0, sizeof(struct ustr)); memset(utf_o, 0, sizeof(struct ustr));
utf_o->u_cmpID = 0; utf_o->u_cmpID = 0;
utf_o->u_len = 0; utf_o->u_len = 0;
return 0; return 0;
} }
if ((cmp_id != 8) && (cmp_id != 16)) if ((cmp_id != 8) && (cmp_id != 16)) {
{ printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n",
printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name); cmp_id, ocu_i->u_name);
return 0; return 0;
} }
for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;) for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) {
{
/* Expand OSTA compressed Unicode to Unicode */ /* Expand OSTA compressed Unicode to Unicode */
c = ocu[i++]; c = ocu[i++];
...@@ -132,20 +130,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i) ...@@ -132,20 +130,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
/* Compress Unicode to UTF-8 */ /* Compress Unicode to UTF-8 */
if (c < 0x80U) if (c < 0x80U)
utf_o->u_name[utf_o->u_len++] = (uint8_t)c; utf_o->u_name[utf_o->u_len++] = (uint8_t) c;
else if (c < 0x800U) else if (c < 0x800U) {
{ utf_o->u_name[utf_o->u_len++] =
utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xc0 | (c >> 6)); (uint8_t) (0xc0 | (c >> 6));
utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f)); utf_o->u_name[utf_o->u_len++] =
} (uint8_t) (0x80 | (c & 0x3f));
else } else {
{ utf_o->u_name[utf_o->u_len++] =
utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xe0 | (c >> 12)); (uint8_t) (0xe0 | (c >> 12));
utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | ((c >> 6) & 0x3f)); utf_o->u_name[utf_o->u_len++] =
utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f)); (uint8_t) (0x80 | ((c >> 6) & 0x3f));
utf_o->u_name[utf_o->u_len++] =
(uint8_t) (0x80 | (c & 0x3f));
} }
} }
utf_o->u_cmpID=8; utf_o->u_cmpID = 8;
return utf_o->u_len; return utf_o->u_len;
} }
...@@ -173,7 +173,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i) ...@@ -173,7 +173,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
* November 12, 1997 - Andrew E. Mileski * November 12, 1997 - Andrew E. Mileski
* Written, tested, and released. * Written, tested, and released.
*/ */
static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) static int udf_UTF8toCS0(dstring * ocu, struct ustr *utf, int length)
{ {
unsigned c, i, max_val, utf_char; unsigned c, i, max_val, utf_char;
int utf_cnt, u_len; int utf_cnt, u_len;
...@@ -182,53 +182,38 @@ static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) ...@@ -182,53 +182,38 @@ static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
ocu[0] = 8; ocu[0] = 8;
max_val = 0xffU; max_val = 0xffU;
try_again: try_again:
u_len = 0U; u_len = 0U;
utf_char = 0U; utf_char = 0U;
utf_cnt = 0U; utf_cnt = 0U;
for (i = 0U; i < utf->u_len; i++) for (i = 0U; i < utf->u_len; i++) {
{ c = (uint8_t) utf->u_name[i];
c = (uint8_t)utf->u_name[i];
/* Complete a multi-byte UTF-8 character */ /* Complete a multi-byte UTF-8 character */
if (utf_cnt) if (utf_cnt) {
{
utf_char = (utf_char << 6) | (c & 0x3fU); utf_char = (utf_char << 6) | (c & 0x3fU);
if (--utf_cnt) if (--utf_cnt)
continue; continue;
} } else {
else
{
/* Check for a multi-byte UTF-8 character */ /* Check for a multi-byte UTF-8 character */
if (c & 0x80U) if (c & 0x80U) {
{
/* Start a multi-byte UTF-8 character */ /* Start a multi-byte UTF-8 character */
if ((c & 0xe0U) == 0xc0U) if ((c & 0xe0U) == 0xc0U) {
{
utf_char = c & 0x1fU; utf_char = c & 0x1fU;
utf_cnt = 1; utf_cnt = 1;
} } else if ((c & 0xf0U) == 0xe0U) {
else if ((c & 0xf0U) == 0xe0U)
{
utf_char = c & 0x0fU; utf_char = c & 0x0fU;
utf_cnt = 2; utf_cnt = 2;
} } else if ((c & 0xf8U) == 0xf0U) {
else if ((c & 0xf8U) == 0xf0U)
{
utf_char = c & 0x07U; utf_char = c & 0x07U;
utf_cnt = 3; utf_cnt = 3;
} } else if ((c & 0xfcU) == 0xf8U) {
else if ((c & 0xfcU) == 0xf8U)
{
utf_char = c & 0x03U; utf_char = c & 0x03U;
utf_cnt = 4; utf_cnt = 4;
} } else if ((c & 0xfeU) == 0xfcU) {
else if ((c & 0xfeU) == 0xfcU)
{
utf_char = c & 0x01U; utf_char = c & 0x01U;
utf_cnt = 5; utf_cnt = 5;
} } else
else
goto error_out; goto error_out;
continue; continue;
} else } else
...@@ -237,37 +222,33 @@ static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) ...@@ -237,37 +222,33 @@ static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
} }
/* Choose no compression if necessary */ /* Choose no compression if necessary */
if (utf_char > max_val) if (utf_char > max_val) {
{ if (0xffU == max_val) {
if ( 0xffU == max_val )
{
max_val = 0xffffU; max_val = 0xffffU;
ocu[0] = (uint8_t)0x10U; ocu[0] = (uint8_t) 0x10U;
goto try_again; goto try_again;
} }
goto error_out; goto error_out;
} }
if (max_val == 0xffffU) if (max_val == 0xffffU) {
{ ocu[++u_len] = (uint8_t) (utf_char >> 8);
ocu[++u_len] = (uint8_t)(utf_char >> 8);
} }
ocu[++u_len] = (uint8_t)(utf_char & 0xffU); ocu[++u_len] = (uint8_t) (utf_char & 0xffU);
} }
if (utf_cnt) {
if (utf_cnt) error_out:
{
error_out:
ocu[++u_len] = '?'; ocu[++u_len] = '?';
printk(KERN_DEBUG "udf: bad UTF-8 character\n"); printk(KERN_DEBUG "udf: bad UTF-8 character\n");
} }
ocu[length - 1] = (uint8_t)u_len + 1; ocu[length - 1] = (uint8_t) u_len + 1;
return u_len + 1; return u_len + 1;
} }
static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i) static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
struct ustr *ocu_i)
{ {
uint8_t *ocu; uint8_t *ocu;
uint32_t c; uint32_t c;
...@@ -280,36 +261,35 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr * ...@@ -280,36 +261,35 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *
cmp_id = ocu_i->u_cmpID; cmp_id = ocu_i->u_cmpID;
utf_o->u_len = 0; utf_o->u_len = 0;
if (ocu_len == 0) if (ocu_len == 0) {
{
memset(utf_o, 0, sizeof(struct ustr)); memset(utf_o, 0, sizeof(struct ustr));
utf_o->u_cmpID = 0; utf_o->u_cmpID = 0;
utf_o->u_len = 0; utf_o->u_len = 0;
return 0; return 0;
} }
if ((cmp_id != 8) && (cmp_id != 16)) if ((cmp_id != 8) && (cmp_id != 16)) {
{ printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n",
printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name); cmp_id, ocu_i->u_name);
return 0; return 0;
} }
for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;) for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) {
{
/* Expand OSTA compressed Unicode to Unicode */ /* Expand OSTA compressed Unicode to Unicode */
c = ocu[i++]; c = ocu[i++];
if (cmp_id == 16) if (cmp_id == 16)
c = (c << 8) | ocu[i++]; c = (c << 8) | ocu[i++];
utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len], utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
UDF_NAME_LEN - utf_o->u_len); UDF_NAME_LEN - utf_o->u_len);
} }
utf_o->u_cmpID=8; utf_o->u_cmpID = 8;
return utf_o->u_len; return utf_o->u_len;
} }
static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length) static int udf_NLStoCS0(struct nls_table *nls, dstring * ocu, struct ustr *uni,
int length)
{ {
unsigned len, i, max_val; unsigned len, i, max_val;
uint16_t uni_char; uint16_t uni_char;
...@@ -319,93 +299,87 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, i ...@@ -319,93 +299,87 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, i
ocu[0] = 8; ocu[0] = 8;
max_val = 0xffU; max_val = 0xffU;
try_again: try_again:
u_len = 0U; u_len = 0U;
for (i = 0U; i < uni->u_len; i++) for (i = 0U; i < uni->u_len; i++) {
{ len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char);
len = nls->char2uni(&uni->u_name[i], uni->u_len-i, &uni_char);
if (len <= 0) if (len <= 0)
continue; continue;
if (uni_char > max_val) if (uni_char > max_val) {
{
max_val = 0xffffU; max_val = 0xffffU;
ocu[0] = (uint8_t)0x10U; ocu[0] = (uint8_t) 0x10U;
goto try_again; goto try_again;
} }
if (max_val == 0xffffU) if (max_val == 0xffffU)
ocu[++u_len] = (uint8_t)(uni_char >> 8); ocu[++u_len] = (uint8_t) (uni_char >> 8);
ocu[++u_len] = (uint8_t)(uni_char & 0xffU); ocu[++u_len] = (uint8_t) (uni_char & 0xffU);
i += len - 1; i += len - 1;
} }
ocu[length - 1] = (uint8_t)u_len + 1; ocu[length - 1] = (uint8_t) u_len + 1;
return u_len + 1; return u_len + 1;
} }
int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, int flen) int udf_get_filename(struct super_block *sb, uint8_t * sname, uint8_t * dname,
int flen)
{ {
struct ustr filename, unifilename; struct ustr filename, unifilename;
int len; int len;
if (udf_build_ustr_exact(&unifilename, sname, flen)) if (udf_build_ustr_exact(&unifilename, sname, flen)) {
{
return 0; return 0;
} }
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) 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);
udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
return 0; return 0;
} }
} } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
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);
udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
return 0; return 0;
} }
} } else
else
return 0; return 0;
if ((len = udf_translate_to_linux(dname, filename.u_name, filename.u_len, if ((len =
unifilename.u_name, unifilename.u_len))) udf_translate_to_linux(dname, filename.u_name, filename.u_len,
{ unifilename.u_name, unifilename.u_len))) {
return len; return len;
} }
return 0; return 0;
} }
int udf_put_filename(struct super_block *sb, const uint8_t *sname, uint8_t *dname, int flen) int udf_put_filename(struct super_block *sb, const uint8_t * sname,
uint8_t * dname, int flen)
{ {
struct ustr unifilename; struct ustr unifilename;
int namelen; int namelen;
if ( !(udf_char_to_ustr(&unifilename, sname, flen)) ) if (!(udf_char_to_ustr(&unifilename, sname, flen))) {
{
return 0; return 0;
} }
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
{ if (!
if ( !(namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN)) ) (namelen =
{ udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN))) {
return 0; return 0;
} }
} } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) if (!
{ (namelen =
if ( !(namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, &unifilename, UDF_NAME_LEN)) ) udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, &unifilename,
{ UDF_NAME_LEN))) {
return 0; return 0;
} }
} } else
else
return 0; return 0;
return namelen; return namelen;
...@@ -416,40 +390,36 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, uint8_t *dnam ...@@ -416,40 +390,36 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, uint8_t *dnam
#define CRC_MARK '#' #define CRC_MARK '#'
#define EXT_SIZE 5 #define EXT_SIZE 5
static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen, uint8_t *fidName, int fidNameLen) static int udf_translate_to_linux(uint8_t * newName, uint8_t * udfName,
int udfLen, uint8_t * fidName, int fidNameLen)
{ {
int index, newIndex = 0, needsCRC = 0; int index, newIndex = 0, needsCRC = 0;
int extIndex = 0, newExtIndex = 0, hasExt = 0; int extIndex = 0, newExtIndex = 0, hasExt = 0;
unsigned short valueCRC; unsigned short valueCRC;
uint8_t curr; uint8_t curr;
const uint8_t hexChar[] = "0123456789ABCDEF"; const uint8_t hexChar[] = "0123456789ABCDEF";
if (udfName[0] == '.' && (udfLen == 1 || if (udfName[0] == '.' && (udfLen == 1 ||
(udfLen == 2 && udfName[1] == '.'))) (udfLen == 2 && udfName[1] == '.'))) {
{
needsCRC = 1; needsCRC = 1;
newIndex = udfLen; newIndex = udfLen;
memcpy(newName, udfName, udfLen); memcpy(newName, udfName, udfLen);
} } else {
else for (index = 0; index < udfLen; index++) {
{
for (index = 0; index < udfLen; index++)
{
curr = udfName[index]; curr = udfName[index];
if (curr == '/' || curr == 0) if (curr == '/' || curr == 0) {
{
needsCRC = 1; needsCRC = 1;
curr = ILLEGAL_CHAR_MARK; curr = ILLEGAL_CHAR_MARK;
while (index+1 < udfLen && (udfName[index+1] == '/' || while (index + 1 < udfLen
udfName[index+1] == 0)) && (udfName[index + 1] == '/'
|| udfName[index + 1] == 0))
index++; index++;
} }
if (curr == EXT_MARK && (udfLen - index - 1) <= EXT_SIZE) if (curr == EXT_MARK
{ && (udfLen - index - 1) <= EXT_SIZE) {
if (udfLen == index + 1) if (udfLen == index + 1)
hasExt = 0; hasExt = 0;
else else {
{
hasExt = 1; hasExt = 1;
extIndex = index; extIndex = index;
newExtIndex = newIndex; newExtIndex = newIndex;
...@@ -461,26 +431,29 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen ...@@ -461,26 +431,29 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen
needsCRC = 1; needsCRC = 1;
} }
} }
if (needsCRC) if (needsCRC) {
{
uint8_t ext[EXT_SIZE]; uint8_t ext[EXT_SIZE];
int localExtIndex = 0; int localExtIndex = 0;
if (hasExt) if (hasExt) {
{
int maxFilenameLen; int maxFilenameLen;
for(index = 0; index<EXT_SIZE && extIndex + index +1 < udfLen; for (index = 0;
index++ ) index < EXT_SIZE && extIndex + index + 1 < udfLen;
{ index++) {
curr = udfName[extIndex + index + 1]; curr = udfName[extIndex + index + 1];
if (curr == '/' || curr == 0) if (curr == '/' || curr == 0) {
{
needsCRC = 1; needsCRC = 1;
curr = ILLEGAL_CHAR_MARK; curr = ILLEGAL_CHAR_MARK;
while(extIndex + index + 2 < udfLen && (index + 1 < EXT_SIZE while (extIndex + index + 2 < udfLen
&& (udfName[extIndex + index + 2] == '/' || && (index + 1 < EXT_SIZE
udfName[extIndex + index + 2] == 0))) &&
(udfName
[extIndex + index + 2] ==
'/'
|| udfName[extIndex +
index + 2] ==
0)))
index++; index++;
} }
ext[localExtIndex++] = curr; ext[localExtIndex++] = curr;
...@@ -490,8 +463,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen ...@@ -490,8 +463,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen
newIndex = maxFilenameLen; newIndex = maxFilenameLen;
else else
newIndex = newExtIndex; newIndex = newExtIndex;
} } else if (newIndex > 250)
else if (newIndex > 250)
newIndex = 250; newIndex = 250;
newName[newIndex++] = CRC_MARK; newName[newIndex++] = CRC_MARK;
valueCRC = udf_crc(fidName, fidNameLen, 0); valueCRC = udf_crc(fidName, fidNameLen, 0);
...@@ -500,10 +472,9 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen ...@@ -500,10 +472,9 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen
newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4]; newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
newName[newIndex++] = hexChar[(valueCRC & 0x000f)]; newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
if (hasExt) if (hasExt) {
{
newName[newIndex++] = EXT_MARK; newName[newIndex++] = EXT_MARK;
for (index = 0;index < localExtIndex ;index++ ) for (index = 0; index < localExtIndex; index++)
newName[newIndex++] = ext[index]; newName[newIndex++] = ext[index];
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment