diff options
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/balloc.c | 84 | ||||
-rw-r--r-- | fs/udf/file.c | 6 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 1 | ||||
-rw-r--r-- | fs/udf/inode.c | 20 | ||||
-rw-r--r-- | fs/udf/namei.c | 13 | ||||
-rw-r--r-- | fs/udf/super.c | 11 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 1 |
7 files changed, 69 insertions, 67 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 987585bb0a1..1ba2baaf436 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -105,7 +105,6 @@ static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt) } static void udf_bitmap_free_blocks(struct super_block *sb, - struct inode *inode, struct udf_bitmap *bitmap, struct kernel_lb_addr *bloc, uint32_t offset, @@ -172,7 +171,6 @@ error_return: } static int udf_bitmap_prealloc_blocks(struct super_block *sb, - struct inode *inode, struct udf_bitmap *bitmap, uint16_t partition, uint32_t first_block, uint32_t block_count) @@ -223,7 +221,6 @@ out: } static int udf_bitmap_new_block(struct super_block *sb, - struct inode *inode, struct udf_bitmap *bitmap, uint16_t partition, uint32_t goal, int *err) { @@ -349,7 +346,6 @@ error_return: } static void udf_table_free_blocks(struct super_block *sb, - struct inode *inode, struct inode *table, struct kernel_lb_addr *bloc, uint32_t offset, @@ -581,7 +577,6 @@ error_return: } static int udf_table_prealloc_blocks(struct super_block *sb, - struct inode *inode, struct inode *table, uint16_t partition, uint32_t first_block, uint32_t block_count) { @@ -643,7 +638,6 @@ static int udf_table_prealloc_blocks(struct super_block *sb, } static int udf_table_new_block(struct super_block *sb, - struct inode *inode, struct inode *table, uint16_t partition, uint32_t goal, int *err) { @@ -743,18 +737,23 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode, struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { - udf_bitmap_free_blocks(sb, inode, map->s_uspace.s_bitmap, + udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { - udf_table_free_blocks(sb, inode, map->s_uspace.s_table, + udf_table_free_blocks(sb, map->s_uspace.s_table, bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { - udf_bitmap_free_blocks(sb, inode, map->s_fspace.s_bitmap, + udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap, bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { - udf_table_free_blocks(sb, inode, map->s_fspace.s_table, + udf_table_free_blocks(sb, map->s_fspace.s_table, bloc, offset, count); } + + if (inode) { + inode_sub_bytes(inode, + ((sector_t)count) << sb->s_blocksize_bits); + } } inline int udf_prealloc_blocks(struct super_block *sb, @@ -763,29 +762,34 @@ inline int udf_prealloc_blocks(struct super_block *sb, uint32_t block_count) { struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; + sector_t allocated; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) - return udf_bitmap_prealloc_blocks(sb, inode, - map->s_uspace.s_bitmap, - partition, first_block, - block_count); + allocated = udf_bitmap_prealloc_blocks(sb, + map->s_uspace.s_bitmap, + partition, first_block, + block_count); else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) - return udf_table_prealloc_blocks(sb, inode, - map->s_uspace.s_table, - partition, first_block, - block_count); + allocated = udf_table_prealloc_blocks(sb, + map->s_uspace.s_table, + partition, first_block, + block_count); else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) - return udf_bitmap_prealloc_blocks(sb, inode, - map->s_fspace.s_bitmap, - partition, first_block, - block_count); + allocated = udf_bitmap_prealloc_blocks(sb, + map->s_fspace.s_bitmap, + partition, first_block, + block_count); else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) - return udf_table_prealloc_blocks(sb, inode, - map->s_fspace.s_table, - partition, first_block, - block_count); + allocated = udf_table_prealloc_blocks(sb, + map->s_fspace.s_table, + partition, first_block, + block_count); else return 0; + + if (inode && allocated > 0) + inode_add_bytes(inode, allocated << sb->s_blocksize_bits); + return allocated; } inline int udf_new_block(struct super_block *sb, @@ -793,25 +797,29 @@ inline int udf_new_block(struct super_block *sb, uint16_t partition, uint32_t goal, int *err) { struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; + int block; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) - return udf_bitmap_new_block(sb, inode, - map->s_uspace.s_bitmap, - partition, goal, err); + block = udf_bitmap_new_block(sb, + map->s_uspace.s_bitmap, + partition, goal, err); else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) - return udf_table_new_block(sb, inode, - map->s_uspace.s_table, - partition, goal, err); - else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) - return udf_bitmap_new_block(sb, inode, - map->s_fspace.s_bitmap, + block = udf_table_new_block(sb, + map->s_uspace.s_table, partition, goal, err); + else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) + block = udf_bitmap_new_block(sb, + map->s_fspace.s_bitmap, + partition, goal, err); else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) - return udf_table_new_block(sb, inode, - map->s_fspace.s_table, - partition, goal, err); + block = udf_table_new_block(sb, + map->s_fspace.s_table, + partition, goal, err); else { *err = -EIO; return 0; } + if (inode && block) + inode_add_bytes(inode, sb->s_blocksize); + return block; } diff --git a/fs/udf/file.c b/fs/udf/file.c index dca0c3881e8..7f3f7ba3df6 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -87,10 +87,10 @@ static int udf_adinicb_write_end(struct file *file, char *kaddr; struct udf_inode_info *iinfo = UDF_I(inode); - kaddr = kmap_atomic(page, KM_USER0); + kaddr = kmap_atomic(page); memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr + offset, kaddr + offset, copied); - kunmap_atomic(kaddr, KM_USER0); + kunmap_atomic(kaddr); return simple_write_end(file, mapping, pos, len, copied, page, fsdata); } @@ -201,12 +201,10 @@ out: static int udf_release_file(struct inode *inode, struct file *filp) { if (filp->f_mode & FMODE_WRITE) { - mutex_lock(&inode->i_mutex); down_write(&UDF_I(inode)->i_data_sem); udf_discard_prealloc(inode); udf_truncate_tail_extent(inode); up_write(&UDF_I(inode)->i_data_sem); - mutex_unlock(&inode->i_mutex); } return 0; } diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 05ab48195be..7e5aae4bf46 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -116,6 +116,7 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err) iinfo->i_lenEAttr = 0; iinfo->i_lenAlloc = 0; iinfo->i_use = 0; + iinfo->i_checkpoint = 1; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 7699df7b319..7d752800835 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1358,6 +1358,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) iinfo->i_unique = le64_to_cpu(fe->uniqueID); iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); + iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr; } else { inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << @@ -1379,6 +1380,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) iinfo->i_unique = le64_to_cpu(efe->uniqueID); iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); + iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); offset = sizeof(struct extendedFileEntry) + iinfo->i_lenEAttr; } @@ -1495,6 +1497,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) struct buffer_head *bh = NULL; struct fileEntry *fe; struct extendedFileEntry *efe; + uint64_t lb_recorded; uint32_t udfperms; uint16_t icbflags; uint16_t crclen; @@ -1589,13 +1592,18 @@ static int udf_update_inode(struct inode *inode, int do_sync) dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); } + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) + lb_recorded = 0; /* No extents => no blocks! */ + else + lb_recorded = + (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> + (blocksize_bits - 9); + if (iinfo->i_efe == 0) { memcpy(bh->b_data + sizeof(struct fileEntry), iinfo->i_ext.i_data, inode->i_sb->s_blocksize - sizeof(struct fileEntry)); - fe->logicalBlocksRecorded = cpu_to_le64( - (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> - (blocksize_bits - 9)); + fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); @@ -1607,6 +1615,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) fe->uniqueID = cpu_to_le64(iinfo->i_unique); fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); + fe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); crclen = sizeof(struct fileEntry); } else { @@ -1615,9 +1624,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); efe->objectSize = cpu_to_le64(inode->i_size); - efe->logicalBlocksRecorded = cpu_to_le64( - (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> - (blocksize_bits - 9)); + efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec || (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec && @@ -1646,6 +1653,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) efe->uniqueID = cpu_to_le64(iinfo->i_unique); efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); + efe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); crclen = sizeof(struct extendedFileEntry); } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 08bf46edf9c..38de8f234b9 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -32,8 +32,6 @@ #include <linux/crc-itu-t.h> #include <linux/exportfs.h> -enum { UDF_MAX_LINKS = 0xffff }; - static inline int udf_match(int len1, const unsigned char *name1, int len2, const unsigned char *name2) { @@ -649,10 +647,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) struct udf_inode_info *dinfo = UDF_I(dir); struct udf_inode_info *iinfo; - err = -EMLINK; - if (dir->i_nlink >= UDF_MAX_LINKS) - goto out; - err = -EIO; inode = udf_new_inode(dir, S_IFDIR | mode, &err); if (!inode) @@ -1032,9 +1026,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, struct fileIdentDesc cfi, *fi; int err; - if (inode->i_nlink >= UDF_MAX_LINKS) - return -EMLINK; - fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); if (!fi) { return err; @@ -1126,10 +1117,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) != old_dir->i_ino) goto end_rename; - - retval = -EMLINK; - if (!new_inode && new_dir->i_nlink >= UDF_MAX_LINKS) - goto end_rename; } if (!nfi) { nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, diff --git a/fs/udf/super.c b/fs/udf/super.c index c09a84daaf5..ac8a348dcb6 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -75,6 +75,8 @@ #define UDF_DEFAULT_BLOCKSIZE 2048 +enum { UDF_MAX_LINKS = 0xffff }; + /* These are the "meat" - everything else is stuffing */ static int udf_fill_super(struct super_block *, void *, int); static void udf_put_super(struct super_block *); @@ -948,11 +950,8 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) else bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ - if (bitmap == NULL) { - udf_err(sb, "Unable to allocate space for bitmap and %d buffer_head pointers\n", - nr_groups); + if (bitmap == NULL) return NULL; - } bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); bitmap->s_nr_groups = nr_groups; @@ -2035,13 +2034,13 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) } /* Allocate a dentry for the root inode */ - sb->s_root = d_alloc_root(inode); + sb->s_root = d_make_root(inode); if (!sb->s_root) { udf_err(sb, "Couldn't allocate root dentry\n"); - iput(inode); goto error_out; } sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_max_links = UDF_MAX_LINKS; return 0; error_out: diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index d1bd31ea724..bb8309dcd5c 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h @@ -23,6 +23,7 @@ struct udf_inode_info { __u64 i_lenExtents; __u32 i_next_alloc_block; __u32 i_next_alloc_goal; + __u32 i_checkpoint; unsigned i_alloc_type : 3; unsigned i_efe : 1; /* extendedFileEntry */ unsigned i_use : 1; /* unallocSpaceEntry */ |