diff options
-rw-r--r-- | fs/udf/super.c | 61 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 38 |
2 files changed, 55 insertions, 44 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 913ece8eec61..86aa2238bc7b 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -937,6 +937,39 @@ static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, | |||
937 | root->logicalBlockNum, root->partitionReferenceNum); | 937 | root->logicalBlockNum, root->partitionReferenceNum); |
938 | } | 938 | } |
939 | 939 | ||
940 | static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | ||
941 | { | ||
942 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[index]; | ||
943 | struct udf_bitmap *bitmap; | ||
944 | int nr_groups; | ||
945 | int size; | ||
946 | |||
947 | /* TODO: move calculating of nr_groups into helper function */ | ||
948 | nr_groups = (map->s_partition_len + | ||
949 | (sizeof(struct spaceBitmapDesc) << 3) + | ||
950 | (sb->s_blocksize * 8) - 1) / | ||
951 | (sb->s_blocksize * 8); | ||
952 | size = sizeof(struct udf_bitmap) + | ||
953 | (sizeof(struct buffer_head *) * nr_groups); | ||
954 | |||
955 | if (size <= PAGE_SIZE) | ||
956 | bitmap = kmalloc(size, GFP_KERNEL); | ||
957 | else | ||
958 | bitmap = vmalloc(size); /* TODO: get rid of vmalloc */ | ||
959 | |||
960 | if (bitmap == NULL) { | ||
961 | udf_error(sb, __FUNCTION__, | ||
962 | "Unable to allocate space for bitmap " | ||
963 | "and %d buffer_head pointers", nr_groups); | ||
964 | return NULL; | ||
965 | } | ||
966 | |||
967 | memset(bitmap, 0x00, size); | ||
968 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); | ||
969 | bitmap->s_nr_groups = nr_groups; | ||
970 | return bitmap; | ||
971 | } | ||
972 | |||
940 | static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) | 973 | static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) |
941 | { | 974 | { |
942 | struct partitionDesc *p; | 975 | struct partitionDesc *p; |
@@ -987,7 +1020,7 @@ static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) | |||
987 | i, map->s_uspace.s_table->i_ino); | 1020 | i, map->s_uspace.s_table->i_ino); |
988 | } | 1021 | } |
989 | if (phd->unallocSpaceBitmap.extLength) { | 1022 | if (phd->unallocSpaceBitmap.extLength) { |
990 | UDF_SB_ALLOC_BITMAP(sb, i, s_uspace); | 1023 | map->s_uspace.s_bitmap = udf_sb_alloc_bitmap(sb, i); |
991 | if (map->s_uspace.s_bitmap != NULL) { | 1024 | if (map->s_uspace.s_bitmap != NULL) { |
992 | map->s_uspace.s_bitmap->s_extLength = | 1025 | map->s_uspace.s_bitmap->s_extLength = |
993 | le32_to_cpu(phd->unallocSpaceBitmap.extLength); | 1026 | le32_to_cpu(phd->unallocSpaceBitmap.extLength); |
@@ -1017,7 +1050,7 @@ static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) | |||
1017 | i, map->s_fspace.s_table->i_ino); | 1050 | i, map->s_fspace.s_table->i_ino); |
1018 | } | 1051 | } |
1019 | if (phd->freedSpaceBitmap.extLength) { | 1052 | if (phd->freedSpaceBitmap.extLength) { |
1020 | UDF_SB_ALLOC_BITMAP(sb, i, s_fspace); | 1053 | map->s_fspace.s_bitmap = udf_sb_alloc_bitmap(sb, i); |
1021 | if (map->s_fspace.s_bitmap != NULL) { | 1054 | if (map->s_fspace.s_bitmap != NULL) { |
1022 | map->s_fspace.s_bitmap->s_extLength = | 1055 | map->s_fspace.s_bitmap->s_extLength = |
1023 | le32_to_cpu(phd->freedSpaceBitmap.extLength); | 1056 | le32_to_cpu(phd->freedSpaceBitmap.extLength); |
@@ -1504,6 +1537,22 @@ static void udf_close_lvid(struct super_block *sb) | |||
1504 | } | 1537 | } |
1505 | } | 1538 | } |
1506 | 1539 | ||
1540 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | ||
1541 | { | ||
1542 | int i; | ||
1543 | int nr_groups = bitmap->s_nr_groups; | ||
1544 | int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) * nr_groups); | ||
1545 | |||
1546 | for (i = 0; i < nr_groups; i++) | ||
1547 | if (bitmap->s_block_bitmap[i]) | ||
1548 | brelse(bitmap->s_block_bitmap[i]); | ||
1549 | |||
1550 | if (size <= PAGE_SIZE) | ||
1551 | kfree(bitmap); | ||
1552 | else | ||
1553 | vfree(bitmap); | ||
1554 | } | ||
1555 | |||
1507 | /* | 1556 | /* |
1508 | * udf_read_super | 1557 | * udf_read_super |
1509 | * | 1558 | * |
@@ -1689,9 +1738,9 @@ error_out: | |||
1689 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | 1738 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
1690 | iput(map->s_fspace.s_table); | 1739 | iput(map->s_fspace.s_table); |
1691 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | 1740 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
1692 | UDF_SB_FREE_BITMAP(sb, sbi->s_partition, s_uspace); | 1741 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); |
1693 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | 1742 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
1694 | UDF_SB_FREE_BITMAP(sb, sbi->s_partition, s_fspace); | 1743 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); |
1695 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | 1744 | if (map->s_partition_type == UDF_SPARABLE_MAP15) |
1696 | for (i = 0; i < 4; i++) | 1745 | for (i = 0; i < 4; i++) |
1697 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); | 1746 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); |
@@ -1767,9 +1816,9 @@ static void udf_put_super(struct super_block *sb) | |||
1767 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | 1816 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
1768 | iput(map->s_fspace.s_table); | 1817 | iput(map->s_fspace.s_table); |
1769 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | 1818 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
1770 | UDF_SB_FREE_BITMAP(sb, sbi->s_partition, s_uspace); | 1819 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); |
1771 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | 1820 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
1772 | UDF_SB_FREE_BITMAP(sb, sbi->s_partition, s_fspace); | 1821 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); |
1773 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | 1822 | if (map->s_partition_type == UDF_SPARABLE_MAP15) |
1774 | for (i = 0; i < 4; i++) | 1823 | for (i = 0; i < 4; i++) |
1775 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); | 1824 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 4d3bd77ea94b..2c05f8277fd8 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -43,46 +43,8 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb) | |||
43 | 43 | ||
44 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi); | 44 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi); |
45 | 45 | ||
46 | #define UDF_SB_ALLOC_BITMAP(X,Y,Z)\ | ||
47 | {\ | ||
48 | struct udf_sb_info *sbi = UDF_SB(X);\ | ||
49 | int nr_groups = ((sbi->s_partmaps[(Y)].s_partition_len + (sizeof(struct spaceBitmapDesc) << 3) +\ | ||
50 | ((X)->s_blocksize * 8) - 1) / ((X)->s_blocksize * 8));\ | ||
51 | int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) * nr_groups);\ | ||
52 | if (size <= PAGE_SIZE)\ | ||
53 | sbi->s_partmaps[(Y)].Z.s_bitmap = kmalloc(size, GFP_KERNEL);\ | ||
54 | else\ | ||
55 | sbi->s_partmaps[(Y)].Z.s_bitmap = vmalloc(size);\ | ||
56 | if (sbi->s_partmaps[(Y)].Z.s_bitmap != NULL) {\ | ||
57 | memset(sbi->s_partmaps[(Y)].Z.s_bitmap, 0x00, size);\ | ||
58 | sbi->s_partmaps[(Y)].Z.s_bitmap->s_block_bitmap =\ | ||
59 | (struct buffer_head **)(sbi->s_partmaps[(Y)].Z.s_bitmap + 1);\ | ||
60 | sbi->s_partmaps[(Y)].Z.s_bitmap->s_nr_groups = nr_groups;\ | ||
61 | } else {\ | ||
62 | udf_error(X, __FUNCTION__, "Unable to allocate space for bitmap and %d buffer_head pointers", nr_groups);\ | ||
63 | }\ | ||
64 | } | ||
65 | |||
66 | #define UDF_SB_FREE_BITMAP(X,Y,Z)\ | ||
67 | {\ | ||
68 | int i;\ | ||
69 | int nr_groups = UDF_SB_BITMAP_NR_GROUPS(X,Y,Z);\ | ||
70 | int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) * nr_groups);\ | ||
71 | for (i = 0; i < nr_groups; i++) {\ | ||
72 | if (UDF_SB_BITMAP(X,Y,Z,i))\ | ||
73 | brelse(UDF_SB_BITMAP(X,Y,Z,i));\ | ||
74 | }\ | ||
75 | if (size <= PAGE_SIZE)\ | ||
76 | kfree(UDF_SB(X)->s_partmaps[Y].Z.s_bitmap);\ | ||
77 | else\ | ||
78 | vfree(UDF_SB(X)->s_partmaps[Y].Z.s_bitmap);\ | ||
79 | } | ||
80 | |||
81 | #define UDF_QUERY_FLAG(X,Y) ( UDF_SB(X)->s_flags & ( 1 << (Y) ) ) | 46 | #define UDF_QUERY_FLAG(X,Y) ( UDF_SB(X)->s_flags & ( 1 << (Y) ) ) |
82 | #define UDF_SET_FLAG(X,Y) ( UDF_SB(X)->s_flags |= ( 1 << (Y) ) ) | 47 | #define UDF_SET_FLAG(X,Y) ( UDF_SB(X)->s_flags |= ( 1 << (Y) ) ) |
83 | #define UDF_CLEAR_FLAG(X,Y) ( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) ) | 48 | #define UDF_CLEAR_FLAG(X,Y) ( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) ) |
84 | 49 | ||
85 | #define UDF_SB_BITMAP(X,Y,Z,I) ( UDF_SB(X)->s_partmaps[(Y)].Z.s_bitmap->s_block_bitmap[I] ) | ||
86 | #define UDF_SB_BITMAP_NR_GROUPS(X,Y,Z) ( UDF_SB(X)->s_partmaps[(Y)].Z.s_bitmap->s_nr_groups ) | ||
87 | |||
88 | #endif /* __LINUX_UDF_SB_H */ | 50 | #endif /* __LINUX_UDF_SB_H */ |