diff options
-rw-r--r-- | fs/Kconfig | 1 | ||||
-rw-r--r-- | fs/udf/Makefile | 2 | ||||
-rw-r--r-- | fs/udf/balloc.c | 13 | ||||
-rw-r--r-- | fs/udf/crc.c | 172 | ||||
-rw-r--r-- | fs/udf/dir.c | 83 | ||||
-rw-r--r-- | fs/udf/ecma_167.h | 13 | ||||
-rw-r--r-- | fs/udf/file.c | 47 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 13 | ||||
-rw-r--r-- | fs/udf/inode.c | 208 | ||||
-rw-r--r-- | fs/udf/lowlevel.c | 1 | ||||
-rw-r--r-- | fs/udf/misc.c | 26 | ||||
-rw-r--r-- | fs/udf/namei.c | 218 | ||||
-rw-r--r-- | fs/udf/partition.c | 67 | ||||
-rw-r--r-- | fs/udf/super.c | 1262 | ||||
-rw-r--r-- | fs/udf/symlink.c | 1 | ||||
-rw-r--r-- | fs/udf/truncate.c | 81 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 30 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 109 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 67 | ||||
-rw-r--r-- | fs/udf/udfend.h | 22 | ||||
-rw-r--r-- | fs/udf/udftime.c | 35 | ||||
-rw-r--r-- | fs/udf/unicode.c | 62 | ||||
-rw-r--r-- | include/linux/Kbuild | 2 | ||||
-rw-r--r-- | include/linux/udf_fs.h | 51 | ||||
-rw-r--r-- | include/linux/udf_fs_i.h | 31 | ||||
-rw-r--r-- | include/linux/udf_fs_sb.h | 117 |
26 files changed, 1173 insertions, 1561 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 028ae38ecc52..8b18a8758677 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -689,6 +689,7 @@ config ZISOFS | |||
689 | 689 | ||
690 | config UDF_FS | 690 | config UDF_FS |
691 | tristate "UDF file system support" | 691 | tristate "UDF file system support" |
692 | select CRC_ITU_T | ||
692 | help | 693 | help |
693 | This is the new file system used on some CD-ROMs and DVDs. Say Y if | 694 | This is the new file system used on some CD-ROMs and DVDs. Say Y if |
694 | you intend to mount DVD discs or CDRW's written in packet mode, or | 695 | you intend to mount DVD discs or CDRW's written in packet mode, or |
diff --git a/fs/udf/Makefile b/fs/udf/Makefile index be845e7540ef..0d4503f7446d 100644 --- a/fs/udf/Makefile +++ b/fs/udf/Makefile | |||
@@ -6,4 +6,4 @@ obj-$(CONFIG_UDF_FS) += udf.o | |||
6 | 6 | ||
7 | udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \ | 7 | udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \ |
8 | partition.o super.o truncate.o symlink.o fsync.o \ | 8 | partition.o super.o truncate.o symlink.o fsync.o \ |
9 | crc.o directory.o misc.o udftime.o unicode.o | 9 | directory.o misc.o udftime.o unicode.o |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index f855dcbbdfb8..1b809bd494bd 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -149,8 +149,7 @@ static bool udf_add_free_space(struct udf_sb_info *sbi, | |||
149 | return false; | 149 | return false; |
150 | 150 | ||
151 | lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; | 151 | lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; |
152 | lvid->freeSpaceTable[partition] = cpu_to_le32(le32_to_cpu( | 152 | le32_add_cpu(&lvid->freeSpaceTable[partition], cnt); |
153 | lvid->freeSpaceTable[partition]) + cnt); | ||
154 | return true; | 153 | return true; |
155 | } | 154 | } |
156 | 155 | ||
@@ -589,10 +588,8 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
589 | sptr = oepos.bh->b_data + epos.offset; | 588 | sptr = oepos.bh->b_data + epos.offset; |
590 | aed = (struct allocExtDesc *) | 589 | aed = (struct allocExtDesc *) |
591 | oepos.bh->b_data; | 590 | oepos.bh->b_data; |
592 | aed->lengthAllocDescs = | 591 | le32_add_cpu(&aed->lengthAllocDescs, |
593 | cpu_to_le32(le32_to_cpu( | 592 | adsize); |
594 | aed->lengthAllocDescs) + | ||
595 | adsize); | ||
596 | } else { | 593 | } else { |
597 | sptr = iinfo->i_ext.i_data + | 594 | sptr = iinfo->i_ext.i_data + |
598 | epos.offset; | 595 | epos.offset; |
@@ -645,9 +642,7 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
645 | mark_inode_dirty(table); | 642 | mark_inode_dirty(table); |
646 | } else { | 643 | } else { |
647 | aed = (struct allocExtDesc *)epos.bh->b_data; | 644 | aed = (struct allocExtDesc *)epos.bh->b_data; |
648 | aed->lengthAllocDescs = | 645 | le32_add_cpu(&aed->lengthAllocDescs, adsize); |
649 | cpu_to_le32(le32_to_cpu( | ||
650 | aed->lengthAllocDescs) + adsize); | ||
651 | udf_update_tag(epos.bh->b_data, epos.offset); | 646 | udf_update_tag(epos.bh->b_data, epos.offset); |
652 | mark_buffer_dirty(epos.bh); | 647 | mark_buffer_dirty(epos.bh); |
653 | } | 648 | } |
diff --git a/fs/udf/crc.c b/fs/udf/crc.c deleted file mode 100644 index b1661296e786..000000000000 --- a/fs/udf/crc.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | * crc.c | ||
3 | * | ||
4 | * PURPOSE | ||
5 | * Routines to generate, calculate, and test a 16-bit CRC. | ||
6 | * | ||
7 | * DESCRIPTION | ||
8 | * The CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories | ||
9 | * and Ned W. Rhodes of Software Systems Group. It has been published in | ||
10 | * "Design and Validation of Computer Protocols", Prentice Hall, | ||
11 | * Englewood Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4. | ||
12 | * | ||
13 | * Copyright is held by AT&T. | ||
14 | * | ||
15 | * AT&T gives permission for the free use of the CRC source code. | ||
16 | * | ||
17 | * COPYRIGHT | ||
18 | * This file is distributed under the terms of the GNU General Public | ||
19 | * License (GPL). Copies of the GPL can be obtained from: | ||
20 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | ||
21 | * Each contributing author retains all rights to their own work. | ||
22 | */ | ||
23 | |||
24 | #include "udfdecl.h" | ||
25 | |||
26 | static uint16_t crc_table[256] = { | ||
27 | 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U, | ||
28 | 0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU, | ||
29 | 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U, | ||
30 | 0x9339U, 0x8318U, 0xb37bU, 0xa35aU, 0xd3bdU, 0xc39cU, 0xf3ffU, 0xe3deU, | ||
31 | 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64e6U, 0x74c7U, 0x44a4U, 0x5485U, | ||
32 | 0xa56aU, 0xb54bU, 0x8528U, 0x9509U, 0xe5eeU, 0xf5cfU, 0xc5acU, 0xd58dU, | ||
33 | 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76d7U, 0x66f6U, 0x5695U, 0x46b4U, | ||
34 | 0xb75bU, 0xa77aU, 0x9719U, 0x8738U, 0xf7dfU, 0xe7feU, 0xd79dU, 0xc7bcU, | ||
35 | 0x48c4U, 0x58e5U, 0x6886U, 0x78a7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U, | ||
36 | 0xc9ccU, 0xd9edU, 0xe98eU, 0xf9afU, 0x8948U, 0x9969U, 0xa90aU, 0xb92bU, | ||
37 | 0x5af5U, 0x4ad4U, 0x7ab7U, 0x6a96U, 0x1a71U, 0x0a50U, 0x3a33U, 0x2a12U, | ||
38 | 0xdbfdU, 0xcbdcU, 0xfbbfU, 0xeb9eU, 0x9b79U, 0x8b58U, 0xbb3bU, 0xab1aU, | ||
39 | 0x6ca6U, 0x7c87U, 0x4ce4U, 0x5cc5U, 0x2c22U, 0x3c03U, 0x0c60U, 0x1c41U, | ||
40 | 0xedaeU, 0xfd8fU, 0xcdecU, 0xddcdU, 0xad2aU, 0xbd0bU, 0x8d68U, 0x9d49U, | ||
41 | 0x7e97U, 0x6eb6U, 0x5ed5U, 0x4ef4U, 0x3e13U, 0x2e32U, 0x1e51U, 0x0e70U, | ||
42 | 0xff9fU, 0xefbeU, 0xdfddU, 0xcffcU, 0xbf1bU, 0xaf3aU, 0x9f59U, 0x8f78U, | ||
43 | 0x9188U, 0x81a9U, 0xb1caU, 0xa1ebU, 0xd10cU, 0xc12dU, 0xf14eU, 0xe16fU, | ||
44 | 0x1080U, 0x00a1U, 0x30c2U, 0x20e3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U, | ||
45 | 0x83b9U, 0x9398U, 0xa3fbU, 0xb3daU, 0xc33dU, 0xd31cU, 0xe37fU, 0xf35eU, | ||
46 | 0x02b1U, 0x1290U, 0x22f3U, 0x32d2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U, | ||
47 | 0xb5eaU, 0xa5cbU, 0x95a8U, 0x8589U, 0xf56eU, 0xe54fU, 0xd52cU, 0xc50dU, | ||
48 | 0x34e2U, 0x24c3U, 0x14a0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U, | ||
49 | 0xa7dbU, 0xb7faU, 0x8799U, 0x97b8U, 0xe75fU, 0xf77eU, 0xc71dU, 0xd73cU, | ||
50 | 0x26d3U, 0x36f2U, 0x0691U, 0x16b0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U, | ||
51 | 0xd94cU, 0xc96dU, 0xf90eU, 0xe92fU, 0x99c8U, 0x89e9U, 0xb98aU, 0xa9abU, | ||
52 | 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18c0U, 0x08e1U, 0x3882U, 0x28a3U, | ||
53 | 0xcb7dU, 0xdb5cU, 0xeb3fU, 0xfb1eU, 0x8bf9U, 0x9bd8U, 0xabbbU, 0xbb9aU, | ||
54 | 0x4a75U, 0x5a54U, 0x6a37U, 0x7a16U, 0x0af1U, 0x1ad0U, 0x2ab3U, 0x3a92U, | ||
55 | 0xfd2eU, 0xed0fU, 0xdd6cU, 0xcd4dU, 0xbdaaU, 0xad8bU, 0x9de8U, 0x8dc9U, | ||
56 | 0x7c26U, 0x6c07U, 0x5c64U, 0x4c45U, 0x3ca2U, 0x2c83U, 0x1ce0U, 0x0cc1U, | ||
57 | 0xef1fU, 0xff3eU, 0xcf5dU, 0xdf7cU, 0xaf9bU, 0xbfbaU, 0x8fd9U, 0x9ff8U, | ||
58 | 0x6e17U, 0x7e36U, 0x4e55U, 0x5e74U, 0x2e93U, 0x3eb2U, 0x0ed1U, 0x1ef0U | ||
59 | }; | ||
60 | |||
61 | /* | ||
62 | * udf_crc | ||
63 | * | ||
64 | * PURPOSE | ||
65 | * Calculate a 16-bit CRC checksum using ITU-T V.41 polynomial. | ||
66 | * | ||
67 | * DESCRIPTION | ||
68 | * The OSTA-UDF(tm) 1.50 standard states that using CRCs is mandatory. | ||
69 | * The polynomial used is: x^16 + x^12 + x^15 + 1 | ||
70 | * | ||
71 | * PRE-CONDITIONS | ||
72 | * data Pointer to the data block. | ||
73 | * size Size of the data block. | ||
74 | * | ||
75 | * POST-CONDITIONS | ||
76 | * <return> CRC of the data block. | ||
77 | * | ||
78 | * HISTORY | ||
79 | * July 21, 1997 - Andrew E. Mileski | ||
80 | * Adapted from OSTA-UDF(tm) 1.50 standard. | ||
81 | */ | ||
82 | uint16_t udf_crc(uint8_t *data, uint32_t size, uint16_t crc) | ||
83 | { | ||
84 | while (size--) | ||
85 | crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8); | ||
86 | |||
87 | return crc; | ||
88 | } | ||
89 | |||
90 | /****************************************************************************/ | ||
91 | #if defined(TEST) | ||
92 | |||
93 | /* | ||
94 | * PURPOSE | ||
95 | * Test udf_crc() | ||
96 | * | ||
97 | * HISTORY | ||
98 | * July 21, 1997 - Andrew E. Mileski | ||
99 | * Adapted from OSTA-UDF(tm) 1.50 standard. | ||
100 | */ | ||
101 | |||
102 | unsigned char bytes[] = { 0x70U, 0x6AU, 0x77U }; | ||
103 | |||
104 | int main(void) | ||
105 | { | ||
106 | unsigned short x; | ||
107 | |||
108 | x = udf_crc(bytes, sizeof bytes); | ||
109 | printf("udf_crc: calculated = %4.4x, correct = %4.4x\n", x, 0x3299U); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | #endif /* defined(TEST) */ | ||
115 | |||
116 | /****************************************************************************/ | ||
117 | #if defined(GENERATE) | ||
118 | |||
119 | /* | ||
120 | * PURPOSE | ||
121 | * Generate a table for fast 16-bit CRC calculations (any polynomial). | ||
122 | * | ||
123 | * DESCRIPTION | ||
124 | * The ITU-T V.41 polynomial is 010041. | ||
125 | * | ||
126 | * HISTORY | ||
127 | * July 21, 1997 - Andrew E. Mileski | ||
128 | * Adapted from OSTA-UDF(tm) 1.50 standard. | ||
129 | */ | ||
130 | |||
131 | #include <stdio.h> | ||
132 | |||
133 | int main(int argc, char **argv) | ||
134 | { | ||
135 | unsigned long crc, poly; | ||
136 | int n, i; | ||
137 | |||
138 | /* Get the polynomial */ | ||
139 | sscanf(argv[1], "%lo", &poly); | ||
140 | if (poly & 0xffff0000U) { | ||
141 | fprintf(stderr, "polynomial is too large\en"); | ||
142 | exit(1); | ||
143 | } | ||
144 | |||
145 | printf("/* CRC 0%o */\n", poly); | ||
146 | |||
147 | /* Create a table */ | ||
148 | printf("static unsigned short crc_table[256] = {\n"); | ||
149 | for (n = 0; n < 256; n++) { | ||
150 | if (n % 8 == 0) | ||
151 | printf("\t"); | ||
152 | crc = n << 8; | ||
153 | for (i = 0; i < 8; i++) { | ||
154 | if (crc & 0x8000U) | ||
155 | crc = (crc << 1) ^ poly; | ||
156 | else | ||
157 | crc <<= 1; | ||
158 | crc &= 0xFFFFU; | ||
159 | } | ||
160 | if (n == 255) | ||
161 | printf("0x%04xU ", crc); | ||
162 | else | ||
163 | printf("0x%04xU, ", crc); | ||
164 | if (n % 8 == 7) | ||
165 | printf("\n"); | ||
166 | } | ||
167 | printf("};\n"); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | #endif /* defined(GENERATE) */ | ||
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 8d8643ada199..62dc270c69d1 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -39,13 +39,13 @@ | |||
39 | static int do_udf_readdir(struct inode *dir, struct file *filp, | 39 | static int do_udf_readdir(struct inode *dir, struct file *filp, |
40 | filldir_t filldir, void *dirent) | 40 | filldir_t filldir, void *dirent) |
41 | { | 41 | { |
42 | struct udf_fileident_bh fibh; | 42 | struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; |
43 | struct fileIdentDesc *fi = NULL; | 43 | struct fileIdentDesc *fi = NULL; |
44 | struct fileIdentDesc cfi; | 44 | struct fileIdentDesc cfi; |
45 | int block, iblock; | 45 | int block, iblock; |
46 | loff_t nf_pos = (filp->f_pos - 1) << 2; | 46 | loff_t nf_pos = (filp->f_pos - 1) << 2; |
47 | int flen; | 47 | int flen; |
48 | char fname[UDF_NAME_LEN]; | 48 | char *fname = NULL; |
49 | char *nameptr; | 49 | char *nameptr; |
50 | uint16_t liu; | 50 | uint16_t liu; |
51 | uint8_t lfi; | 51 | uint8_t lfi; |
@@ -54,23 +54,32 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
54 | kernel_lb_addr eloc; | 54 | kernel_lb_addr eloc; |
55 | uint32_t elen; | 55 | uint32_t elen; |
56 | sector_t offset; | 56 | sector_t offset; |
57 | int i, num; | 57 | int i, num, ret = 0; |
58 | unsigned int dt_type; | 58 | unsigned int dt_type; |
59 | struct extent_position epos = { NULL, 0, {0, 0} }; | 59 | struct extent_position epos = { NULL, 0, {0, 0} }; |
60 | struct udf_inode_info *iinfo; | 60 | struct udf_inode_info *iinfo; |
61 | 61 | ||
62 | if (nf_pos >= size) | 62 | if (nf_pos >= size) |
63 | return 0; | 63 | goto out; |
64 | |||
65 | fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||
66 | if (!fname) { | ||
67 | ret = -ENOMEM; | ||
68 | goto out; | ||
69 | } | ||
64 | 70 | ||
65 | if (nf_pos == 0) | 71 | if (nf_pos == 0) |
66 | nf_pos = udf_ext0_offset(dir); | 72 | nf_pos = udf_ext0_offset(dir); |
67 | 73 | ||
68 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); | 74 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); |
69 | iinfo = UDF_I(dir); | 75 | iinfo = UDF_I(dir); |
70 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 76 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
71 | fibh.sbh = fibh.ebh = NULL; | 77 | if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, |
72 | } else if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, | 78 | &epos, &eloc, &elen, &offset) |
73 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { | 79 | != (EXT_RECORDED_ALLOCATED >> 30)) { |
80 | ret = -ENOENT; | ||
81 | goto out; | ||
82 | } | ||
74 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 83 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
75 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 84 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
76 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 85 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
@@ -83,8 +92,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
83 | } | 92 | } |
84 | 93 | ||
85 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { | 94 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { |
86 | brelse(epos.bh); | 95 | ret = -EIO; |
87 | return -EIO; | 96 | goto out; |
88 | } | 97 | } |
89 | 98 | ||
90 | if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { | 99 | if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { |
@@ -105,9 +114,6 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
105 | brelse(bha[i]); | 114 | brelse(bha[i]); |
106 | } | 115 | } |
107 | } | 116 | } |
108 | } else { | ||
109 | brelse(epos.bh); | ||
110 | return -ENOENT; | ||
111 | } | 117 | } |
112 | 118 | ||
113 | while (nf_pos < size) { | 119 | while (nf_pos < size) { |
@@ -115,13 +121,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
115 | 121 | ||
116 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, | 122 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, |
117 | &elen, &offset); | 123 | &elen, &offset); |
118 | if (!fi) { | 124 | if (!fi) |
119 | if (fibh.sbh != fibh.ebh) | 125 | goto out; |
120 | brelse(fibh.ebh); | ||
121 | brelse(fibh.sbh); | ||
122 | brelse(epos.bh); | ||
123 | return 0; | ||
124 | } | ||
125 | 126 | ||
126 | liu = le16_to_cpu(cfi.lengthOfImpUse); | 127 | liu = le16_to_cpu(cfi.lengthOfImpUse); |
127 | lfi = cfi.lengthFileIdent; | 128 | lfi = cfi.lengthFileIdent; |
@@ -167,53 +168,23 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
167 | dt_type = DT_UNKNOWN; | 168 | dt_type = DT_UNKNOWN; |
168 | } | 169 | } |
169 | 170 | ||
170 | if (flen) { | 171 | if (flen && filldir(dirent, fname, flen, filp->f_pos, |
171 | if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) { | 172 | iblock, dt_type) < 0) |
172 | if (fibh.sbh != fibh.ebh) | 173 | goto out; |
173 | brelse(fibh.ebh); | ||
174 | brelse(fibh.sbh); | ||
175 | brelse(epos.bh); | ||
176 | return 0; | ||
177 | } | ||
178 | } | ||
179 | } /* end while */ | 174 | } /* end while */ |
180 | 175 | ||
181 | filp->f_pos = (nf_pos >> 2) + 1; | 176 | filp->f_pos = (nf_pos >> 2) + 1; |
182 | 177 | ||
178 | out: | ||
183 | if (fibh.sbh != fibh.ebh) | 179 | if (fibh.sbh != fibh.ebh) |
184 | brelse(fibh.ebh); | 180 | brelse(fibh.ebh); |
185 | brelse(fibh.sbh); | 181 | brelse(fibh.sbh); |
186 | brelse(epos.bh); | 182 | brelse(epos.bh); |
183 | kfree(fname); | ||
187 | 184 | ||
188 | return 0; | 185 | return ret; |
189 | } | 186 | } |
190 | 187 | ||
191 | /* | ||
192 | * udf_readdir | ||
193 | * | ||
194 | * PURPOSE | ||
195 | * Read a directory entry. | ||
196 | * | ||
197 | * DESCRIPTION | ||
198 | * Optional - sys_getdents() will return -ENOTDIR if this routine is not | ||
199 | * available. | ||
200 | * | ||
201 | * Refer to sys_getdents() in fs/readdir.c | ||
202 | * sys_getdents() -> . | ||
203 | * | ||
204 | * PRE-CONDITIONS | ||
205 | * filp Pointer to directory file. | ||
206 | * buf Pointer to directory entry buffer. | ||
207 | * filldir Pointer to filldir function. | ||
208 | * | ||
209 | * POST-CONDITIONS | ||
210 | * <return> >=0 on success. | ||
211 | * | ||
212 | * HISTORY | ||
213 | * July 1, 1997 - Andrew E. Mileski | ||
214 | * Written, tested, and released. | ||
215 | */ | ||
216 | |||
217 | static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) | 188 | static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) |
218 | { | 189 | { |
219 | struct inode *dir = filp->f_path.dentry->d_inode; | 190 | struct inode *dir = filp->f_path.dentry->d_inode; |
diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h index 56387711589b..a0974df82b31 100644 --- a/fs/udf/ecma_167.h +++ b/fs/udf/ecma_167.h | |||
@@ -70,19 +70,6 @@ typedef struct { | |||
70 | uint8_t microseconds; | 70 | uint8_t microseconds; |
71 | } __attribute__ ((packed)) timestamp; | 71 | } __attribute__ ((packed)) timestamp; |
72 | 72 | ||
73 | typedef struct { | ||
74 | uint16_t typeAndTimezone; | ||
75 | int16_t year; | ||
76 | uint8_t month; | ||
77 | uint8_t day; | ||
78 | uint8_t hour; | ||
79 | uint8_t minute; | ||
80 | uint8_t second; | ||
81 | uint8_t centiseconds; | ||
82 | uint8_t hundredsOfMicroseconds; | ||
83 | uint8_t microseconds; | ||
84 | } __attribute__ ((packed)) kernel_timestamp; | ||
85 | |||
86 | /* Type and Time Zone (ECMA 167r3 1/7.3.1) */ | 73 | /* Type and Time Zone (ECMA 167r3 1/7.3.1) */ |
87 | #define TIMESTAMP_TYPE_MASK 0xF000 | 74 | #define TIMESTAMP_TYPE_MASK 0xF000 |
88 | #define TIMESTAMP_TYPE_CUT 0x0000 | 75 | #define TIMESTAMP_TYPE_CUT 0x0000 |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 97c71ae7c689..0ed6e146a0d9 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include "udfdecl.h" | 28 | #include "udfdecl.h" |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/udf_fs.h> | ||
31 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
32 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
33 | #include <linux/string.h> /* memset */ | 32 | #include <linux/string.h> /* memset */ |
@@ -144,40 +143,6 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
144 | return retval; | 143 | return retval; |
145 | } | 144 | } |
146 | 145 | ||
147 | /* | ||
148 | * udf_ioctl | ||
149 | * | ||
150 | * PURPOSE | ||
151 | * Issue an ioctl. | ||
152 | * | ||
153 | * DESCRIPTION | ||
154 | * Optional - sys_ioctl() will return -ENOTTY if this routine is not | ||
155 | * available, and the ioctl cannot be handled without filesystem help. | ||
156 | * | ||
157 | * sys_ioctl() handles these ioctls that apply only to regular files: | ||
158 | * FIBMAP [requires udf_block_map()], FIGETBSZ, FIONREAD | ||
159 | * These ioctls are also handled by sys_ioctl(): | ||
160 | * FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC | ||
161 | * All other ioctls are passed to the filesystem. | ||
162 | * | ||
163 | * Refer to sys_ioctl() in fs/ioctl.c | ||
164 | * sys_ioctl() -> . | ||
165 | * | ||
166 | * PRE-CONDITIONS | ||
167 | * inode Pointer to inode that ioctl was issued on. | ||
168 | * filp Pointer to file that ioctl was issued on. | ||
169 | * cmd The ioctl command. | ||
170 | * arg The ioctl argument [can be interpreted as a | ||
171 | * user-space pointer if desired]. | ||
172 | * | ||
173 | * POST-CONDITIONS | ||
174 | * <return> Success (>=0) or an error code (<=0) that | ||
175 | * sys_ioctl() will return. | ||
176 | * | ||
177 | * HISTORY | ||
178 | * July 1, 1997 - Andrew E. Mileski | ||
179 | * Written, tested, and released. | ||
180 | */ | ||
181 | int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 146 | int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, |
182 | unsigned long arg) | 147 | unsigned long arg) |
183 | { | 148 | { |
@@ -225,18 +190,6 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
225 | return result; | 190 | return result; |
226 | } | 191 | } |
227 | 192 | ||
228 | /* | ||
229 | * udf_release_file | ||
230 | * | ||
231 | * PURPOSE | ||
232 | * Called when all references to the file are closed | ||
233 | * | ||
234 | * DESCRIPTION | ||
235 | * Discard prealloced blocks | ||
236 | * | ||
237 | * HISTORY | ||
238 | * | ||
239 | */ | ||
240 | static int udf_release_file(struct inode *inode, struct file *filp) | 193 | static int udf_release_file(struct inode *inode, struct file *filp) |
241 | { | 194 | { |
242 | if (filp->f_mode & FMODE_WRITE) { | 195 | if (filp->f_mode & FMODE_WRITE) { |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 84360315aca2..eb9cfa23dc3d 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "udfdecl.h" | 21 | #include "udfdecl.h" |
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/quotaops.h> | 23 | #include <linux/quotaops.h> |
24 | #include <linux/udf_fs.h> | ||
25 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | 26 | ||
@@ -47,11 +46,9 @@ void udf_free_inode(struct inode *inode) | |||
47 | struct logicalVolIntegrityDescImpUse *lvidiu = | 46 | struct logicalVolIntegrityDescImpUse *lvidiu = |
48 | udf_sb_lvidiu(sbi); | 47 | udf_sb_lvidiu(sbi); |
49 | if (S_ISDIR(inode->i_mode)) | 48 | if (S_ISDIR(inode->i_mode)) |
50 | lvidiu->numDirs = | 49 | le32_add_cpu(&lvidiu->numDirs, -1); |
51 | cpu_to_le32(le32_to_cpu(lvidiu->numDirs) - 1); | ||
52 | else | 50 | else |
53 | lvidiu->numFiles = | 51 | le32_add_cpu(&lvidiu->numFiles, -1); |
54 | cpu_to_le32(le32_to_cpu(lvidiu->numFiles) - 1); | ||
55 | 52 | ||
56 | mark_buffer_dirty(sbi->s_lvid_bh); | 53 | mark_buffer_dirty(sbi->s_lvid_bh); |
57 | } | 54 | } |
@@ -105,11 +102,9 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
105 | lvhd = (struct logicalVolHeaderDesc *) | 102 | lvhd = (struct logicalVolHeaderDesc *) |
106 | (lvid->logicalVolContentsUse); | 103 | (lvid->logicalVolContentsUse); |
107 | if (S_ISDIR(mode)) | 104 | if (S_ISDIR(mode)) |
108 | lvidiu->numDirs = | 105 | le32_add_cpu(&lvidiu->numDirs, 1); |
109 | cpu_to_le32(le32_to_cpu(lvidiu->numDirs) + 1); | ||
110 | else | 106 | else |
111 | lvidiu->numFiles = | 107 | le32_add_cpu(&lvidiu->numFiles, 1); |
112 | cpu_to_le32(le32_to_cpu(lvidiu->numFiles) + 1); | ||
113 | iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID); | 108 | iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID); |
114 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) | 109 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) |
115 | uniqueID += 16; | 110 | uniqueID += 16; |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 24cfa55d0fdc..6e74b117aaf0 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/crc-itu-t.h> | ||
40 | 41 | ||
41 | #include "udf_i.h" | 42 | #include "udf_i.h" |
42 | #include "udf_sb.h" | 43 | #include "udf_sb.h" |
@@ -66,22 +67,7 @@ static void udf_update_extents(struct inode *, | |||
66 | struct extent_position *); | 67 | struct extent_position *); |
67 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | 68 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
68 | 69 | ||
69 | /* | 70 | |
70 | * udf_delete_inode | ||
71 | * | ||
72 | * PURPOSE | ||
73 | * Clean-up before the specified inode is destroyed. | ||
74 | * | ||
75 | * DESCRIPTION | ||
76 | * This routine is called when the kernel destroys an inode structure | ||
77 | * ie. when iput() finds i_count == 0. | ||
78 | * | ||
79 | * HISTORY | ||
80 | * July 1, 1997 - Andrew E. Mileski | ||
81 | * Written, tested, and released. | ||
82 | * | ||
83 | * Called at the last iput() if i_nlink is zero. | ||
84 | */ | ||
85 | void udf_delete_inode(struct inode *inode) | 71 | void udf_delete_inode(struct inode *inode) |
86 | { | 72 | { |
87 | truncate_inode_pages(&inode->i_data, 0); | 73 | truncate_inode_pages(&inode->i_data, 0); |
@@ -323,9 +309,6 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
323 | 309 | ||
324 | lock_kernel(); | 310 | lock_kernel(); |
325 | 311 | ||
326 | if (block < 0) | ||
327 | goto abort_negative; | ||
328 | |||
329 | iinfo = UDF_I(inode); | 312 | iinfo = UDF_I(inode); |
330 | if (block == iinfo->i_next_alloc_block + 1) { | 313 | if (block == iinfo->i_next_alloc_block + 1) { |
331 | iinfo->i_next_alloc_block++; | 314 | iinfo->i_next_alloc_block++; |
@@ -347,10 +330,6 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
347 | abort: | 330 | abort: |
348 | unlock_kernel(); | 331 | unlock_kernel(); |
349 | return err; | 332 | return err; |
350 | |||
351 | abort_negative: | ||
352 | udf_warning(inode->i_sb, "udf_get_block", "block < 0"); | ||
353 | goto abort; | ||
354 | } | 333 | } |
355 | 334 | ||
356 | static struct buffer_head *udf_getblk(struct inode *inode, long block, | 335 | static struct buffer_head *udf_getblk(struct inode *inode, long block, |
@@ -1116,42 +1095,36 @@ static void __udf_read_inode(struct inode *inode) | |||
1116 | fe = (struct fileEntry *)bh->b_data; | 1095 | fe = (struct fileEntry *)bh->b_data; |
1117 | 1096 | ||
1118 | if (fe->icbTag.strategyType == cpu_to_le16(4096)) { | 1097 | if (fe->icbTag.strategyType == cpu_to_le16(4096)) { |
1119 | struct buffer_head *ibh = NULL, *nbh = NULL; | 1098 | struct buffer_head *ibh; |
1120 | struct indirectEntry *ie; | ||
1121 | 1099 | ||
1122 | ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1, | 1100 | ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1, |
1123 | &ident); | 1101 | &ident); |
1124 | if (ident == TAG_IDENT_IE) { | 1102 | if (ident == TAG_IDENT_IE && ibh) { |
1125 | if (ibh) { | 1103 | struct buffer_head *nbh = NULL; |
1126 | kernel_lb_addr loc; | 1104 | kernel_lb_addr loc; |
1127 | ie = (struct indirectEntry *)ibh->b_data; | 1105 | struct indirectEntry *ie; |
1128 | 1106 | ||
1129 | loc = lelb_to_cpu(ie->indirectICB.extLocation); | 1107 | ie = (struct indirectEntry *)ibh->b_data; |
1130 | 1108 | loc = lelb_to_cpu(ie->indirectICB.extLocation); | |
1131 | if (ie->indirectICB.extLength && | 1109 | |
1132 | (nbh = udf_read_ptagged(inode->i_sb, loc, 0, | 1110 | if (ie->indirectICB.extLength && |
1133 | &ident))) { | 1111 | (nbh = udf_read_ptagged(inode->i_sb, loc, 0, |
1134 | if (ident == TAG_IDENT_FE || | 1112 | &ident))) { |
1135 | ident == TAG_IDENT_EFE) { | 1113 | if (ident == TAG_IDENT_FE || |
1136 | memcpy(&iinfo->i_location, | 1114 | ident == TAG_IDENT_EFE) { |
1137 | &loc, | 1115 | memcpy(&iinfo->i_location, |
1138 | sizeof(kernel_lb_addr)); | 1116 | &loc, |
1139 | brelse(bh); | 1117 | sizeof(kernel_lb_addr)); |
1140 | brelse(ibh); | 1118 | brelse(bh); |
1141 | brelse(nbh); | ||
1142 | __udf_read_inode(inode); | ||
1143 | return; | ||
1144 | } else { | ||
1145 | brelse(nbh); | ||
1146 | brelse(ibh); | ||
1147 | } | ||
1148 | } else { | ||
1149 | brelse(ibh); | 1119 | brelse(ibh); |
1120 | brelse(nbh); | ||
1121 | __udf_read_inode(inode); | ||
1122 | return; | ||
1150 | } | 1123 | } |
1124 | brelse(nbh); | ||
1151 | } | 1125 | } |
1152 | } else { | ||
1153 | brelse(ibh); | ||
1154 | } | 1126 | } |
1127 | brelse(ibh); | ||
1155 | } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { | 1128 | } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { |
1156 | printk(KERN_ERR "udf: unsupported strategy type: %d\n", | 1129 | printk(KERN_ERR "udf: unsupported strategy type: %d\n", |
1157 | le16_to_cpu(fe->icbTag.strategyType)); | 1130 | le16_to_cpu(fe->icbTag.strategyType)); |
@@ -1168,8 +1141,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1168 | { | 1141 | { |
1169 | struct fileEntry *fe; | 1142 | struct fileEntry *fe; |
1170 | struct extendedFileEntry *efe; | 1143 | struct extendedFileEntry *efe; |
1171 | time_t convtime; | ||
1172 | long convtime_usec; | ||
1173 | int offset; | 1144 | int offset; |
1174 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); | 1145 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); |
1175 | struct udf_inode_info *iinfo = UDF_I(inode); | 1146 | struct udf_inode_info *iinfo = UDF_I(inode); |
@@ -1257,29 +1228,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1257 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << | 1228 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << |
1258 | (inode->i_sb->s_blocksize_bits - 9); | 1229 | (inode->i_sb->s_blocksize_bits - 9); |
1259 | 1230 | ||
1260 | if (udf_stamp_to_time(&convtime, &convtime_usec, | 1231 | if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime)) |
1261 | lets_to_cpu(fe->accessTime))) { | ||
1262 | inode->i_atime.tv_sec = convtime; | ||
1263 | inode->i_atime.tv_nsec = convtime_usec * 1000; | ||
1264 | } else { | ||
1265 | inode->i_atime = sbi->s_record_time; | 1232 | inode->i_atime = sbi->s_record_time; |
1266 | } | ||
1267 | 1233 | ||
1268 | if (udf_stamp_to_time(&convtime, &convtime_usec, | 1234 | if (!udf_disk_stamp_to_time(&inode->i_mtime, |
1269 | lets_to_cpu(fe->modificationTime))) { | 1235 | fe->modificationTime)) |
1270 | inode->i_mtime.tv_sec = convtime; | ||
1271 | inode->i_mtime.tv_nsec = convtime_usec * 1000; | ||
1272 | } else { | ||
1273 | inode->i_mtime = sbi->s_record_time; | 1236 | inode->i_mtime = sbi->s_record_time; |
1274 | } | ||
1275 | 1237 | ||
1276 | if (udf_stamp_to_time(&convtime, &convtime_usec, | 1238 | if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime)) |
1277 | lets_to_cpu(fe->attrTime))) { | ||
1278 | inode->i_ctime.tv_sec = convtime; | ||
1279 | inode->i_ctime.tv_nsec = convtime_usec * 1000; | ||
1280 | } else { | ||
1281 | inode->i_ctime = sbi->s_record_time; | 1239 | inode->i_ctime = sbi->s_record_time; |
1282 | } | ||
1283 | 1240 | ||
1284 | iinfo->i_unique = le64_to_cpu(fe->uniqueID); | 1241 | iinfo->i_unique = le64_to_cpu(fe->uniqueID); |
1285 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); | 1242 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); |
@@ -1289,37 +1246,18 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1289 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << | 1246 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << |
1290 | (inode->i_sb->s_blocksize_bits - 9); | 1247 | (inode->i_sb->s_blocksize_bits - 9); |
1291 | 1248 | ||
1292 | if (udf_stamp_to_time(&convtime, &convtime_usec, | 1249 | if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime)) |
1293 | lets_to_cpu(efe->accessTime))) { | ||
1294 | inode->i_atime.tv_sec = convtime; | ||
1295 | inode->i_atime.tv_nsec = convtime_usec * 1000; | ||
1296 | } else { | ||
1297 | inode->i_atime = sbi->s_record_time; | 1250 | inode->i_atime = sbi->s_record_time; |
1298 | } | ||
1299 | 1251 | ||
1300 | if (udf_stamp_to_time(&convtime, &convtime_usec, | 1252 | if (!udf_disk_stamp_to_time(&inode->i_mtime, |
1301 | lets_to_cpu(efe->modificationTime))) { | 1253 | efe->modificationTime)) |
1302 | inode->i_mtime.tv_sec = convtime; | ||
1303 | inode->i_mtime.tv_nsec = convtime_usec * 1000; | ||
1304 | } else { | ||
1305 | inode->i_mtime = sbi->s_record_time; | 1254 | inode->i_mtime = sbi->s_record_time; |
1306 | } | ||
1307 | 1255 | ||
1308 | if (udf_stamp_to_time(&convtime, &convtime_usec, | 1256 | if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime)) |
1309 | lets_to_cpu(efe->createTime))) { | ||
1310 | iinfo->i_crtime.tv_sec = convtime; | ||
1311 | iinfo->i_crtime.tv_nsec = convtime_usec * 1000; | ||
1312 | } else { | ||
1313 | iinfo->i_crtime = sbi->s_record_time; | 1257 | iinfo->i_crtime = sbi->s_record_time; |
1314 | } | ||
1315 | 1258 | ||
1316 | if (udf_stamp_to_time(&convtime, &convtime_usec, | 1259 | if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime)) |
1317 | lets_to_cpu(efe->attrTime))) { | ||
1318 | inode->i_ctime.tv_sec = convtime; | ||
1319 | inode->i_ctime.tv_nsec = convtime_usec * 1000; | ||
1320 | } else { | ||
1321 | inode->i_ctime = sbi->s_record_time; | 1260 | inode->i_ctime = sbi->s_record_time; |
1322 | } | ||
1323 | 1261 | ||
1324 | iinfo->i_unique = le64_to_cpu(efe->uniqueID); | 1262 | iinfo->i_unique = le64_to_cpu(efe->uniqueID); |
1325 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); | 1263 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); |
@@ -1338,6 +1276,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1338 | case ICBTAG_FILE_TYPE_REALTIME: | 1276 | case ICBTAG_FILE_TYPE_REALTIME: |
1339 | case ICBTAG_FILE_TYPE_REGULAR: | 1277 | case ICBTAG_FILE_TYPE_REGULAR: |
1340 | case ICBTAG_FILE_TYPE_UNDEF: | 1278 | case ICBTAG_FILE_TYPE_UNDEF: |
1279 | case ICBTAG_FILE_TYPE_VAT20: | ||
1341 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1280 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1342 | inode->i_data.a_ops = &udf_adinicb_aops; | 1281 | inode->i_data.a_ops = &udf_adinicb_aops; |
1343 | else | 1282 | else |
@@ -1363,6 +1302,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1363 | inode->i_op = &page_symlink_inode_operations; | 1302 | inode->i_op = &page_symlink_inode_operations; |
1364 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 1303 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
1365 | break; | 1304 | break; |
1305 | case ICBTAG_FILE_TYPE_MAIN: | ||
1306 | udf_debug("METADATA FILE-----\n"); | ||
1307 | break; | ||
1308 | case ICBTAG_FILE_TYPE_MIRROR: | ||
1309 | udf_debug("METADATA MIRROR FILE-----\n"); | ||
1310 | break; | ||
1311 | case ICBTAG_FILE_TYPE_BITMAP: | ||
1312 | udf_debug("METADATA BITMAP FILE-----\n"); | ||
1313 | break; | ||
1366 | default: | 1314 | default: |
1367 | printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown " | 1315 | printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown " |
1368 | "file type=%d\n", inode->i_ino, | 1316 | "file type=%d\n", inode->i_ino, |
@@ -1416,21 +1364,6 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) | |||
1416 | return mode; | 1364 | return mode; |
1417 | } | 1365 | } |
1418 | 1366 | ||
1419 | /* | ||
1420 | * udf_write_inode | ||
1421 | * | ||
1422 | * PURPOSE | ||
1423 | * Write out the specified inode. | ||
1424 | * | ||
1425 | * DESCRIPTION | ||
1426 | * This routine is called whenever an inode is synced. | ||
1427 | * Currently this routine is just a placeholder. | ||
1428 | * | ||
1429 | * HISTORY | ||
1430 | * July 1, 1997 - Andrew E. Mileski | ||
1431 | * Written, tested, and released. | ||
1432 | */ | ||
1433 | |||
1434 | int udf_write_inode(struct inode *inode, int sync) | 1367 | int udf_write_inode(struct inode *inode, int sync) |
1435 | { | 1368 | { |
1436 | int ret; | 1369 | int ret; |
@@ -1455,7 +1388,6 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1455 | uint32_t udfperms; | 1388 | uint32_t udfperms; |
1456 | uint16_t icbflags; | 1389 | uint16_t icbflags; |
1457 | uint16_t crclen; | 1390 | uint16_t crclen; |
1458 | kernel_timestamp cpu_time; | ||
1459 | int err = 0; | 1391 | int err = 0; |
1460 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); | 1392 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); |
1461 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 1393 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
@@ -1488,9 +1420,9 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1488 | iinfo->i_location. | 1420 | iinfo->i_location. |
1489 | logicalBlockNum); | 1421 | logicalBlockNum); |
1490 | use->descTag.descCRCLength = cpu_to_le16(crclen); | 1422 | use->descTag.descCRCLength = cpu_to_le16(crclen); |
1491 | use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + | 1423 | use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use + |
1492 | sizeof(tag), crclen, | 1424 | sizeof(tag), |
1493 | 0)); | 1425 | crclen)); |
1494 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); | 1426 | use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); |
1495 | 1427 | ||
1496 | mark_buffer_dirty(bh); | 1428 | mark_buffer_dirty(bh); |
@@ -1558,12 +1490,9 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1558 | (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> | 1490 | (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> |
1559 | (blocksize_bits - 9)); | 1491 | (blocksize_bits - 9)); |
1560 | 1492 | ||
1561 | if (udf_time_to_stamp(&cpu_time, inode->i_atime)) | 1493 | udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); |
1562 | fe->accessTime = cpu_to_lets(cpu_time); | 1494 | udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); |
1563 | if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) | 1495 | udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime); |
1564 | fe->modificationTime = cpu_to_lets(cpu_time); | ||
1565 | if (udf_time_to_stamp(&cpu_time, inode->i_ctime)) | ||
1566 | fe->attrTime = cpu_to_lets(cpu_time); | ||
1567 | memset(&(fe->impIdent), 0, sizeof(regid)); | 1496 | memset(&(fe->impIdent), 0, sizeof(regid)); |
1568 | strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); | 1497 | strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); |
1569 | fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1498 | fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
@@ -1598,14 +1527,10 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1598 | iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec)) | 1527 | iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec)) |
1599 | iinfo->i_crtime = inode->i_ctime; | 1528 | iinfo->i_crtime = inode->i_ctime; |
1600 | 1529 | ||
1601 | if (udf_time_to_stamp(&cpu_time, inode->i_atime)) | 1530 | udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime); |
1602 | efe->accessTime = cpu_to_lets(cpu_time); | 1531 | udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime); |
1603 | if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) | 1532 | udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime); |
1604 | efe->modificationTime = cpu_to_lets(cpu_time); | 1533 | udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime); |
1605 | if (udf_time_to_stamp(&cpu_time, iinfo->i_crtime)) | ||
1606 | efe->createTime = cpu_to_lets(cpu_time); | ||
1607 | if (udf_time_to_stamp(&cpu_time, inode->i_ctime)) | ||
1608 | efe->attrTime = cpu_to_lets(cpu_time); | ||
1609 | 1534 | ||
1610 | memset(&(efe->impIdent), 0, sizeof(regid)); | 1535 | memset(&(efe->impIdent), 0, sizeof(regid)); |
1611 | strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); | 1536 | strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); |
@@ -1660,8 +1585,8 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1660 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - | 1585 | crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - |
1661 | sizeof(tag); | 1586 | sizeof(tag); |
1662 | fe->descTag.descCRCLength = cpu_to_le16(crclen); | 1587 | fe->descTag.descCRCLength = cpu_to_le16(crclen); |
1663 | fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), | 1588 | fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(tag), |
1664 | crclen, 0)); | 1589 | crclen)); |
1665 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); | 1590 | fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); |
1666 | 1591 | ||
1667 | /* write the data blocks */ | 1592 | /* write the data blocks */ |
@@ -1778,9 +1703,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1778 | 1703 | ||
1779 | if (epos->bh) { | 1704 | if (epos->bh) { |
1780 | aed = (struct allocExtDesc *)epos->bh->b_data; | 1705 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1781 | aed->lengthAllocDescs = | 1706 | le32_add_cpu(&aed->lengthAllocDescs, adsize); |
1782 | cpu_to_le32(le32_to_cpu( | ||
1783 | aed->lengthAllocDescs) + adsize); | ||
1784 | } else { | 1707 | } else { |
1785 | iinfo->i_lenAlloc += adsize; | 1708 | iinfo->i_lenAlloc += adsize; |
1786 | mark_inode_dirty(inode); | 1709 | mark_inode_dirty(inode); |
@@ -1830,9 +1753,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos, | |||
1830 | mark_inode_dirty(inode); | 1753 | mark_inode_dirty(inode); |
1831 | } else { | 1754 | } else { |
1832 | aed = (struct allocExtDesc *)epos->bh->b_data; | 1755 | aed = (struct allocExtDesc *)epos->bh->b_data; |
1833 | aed->lengthAllocDescs = | 1756 | le32_add_cpu(&aed->lengthAllocDescs, adsize); |
1834 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + | ||
1835 | adsize); | ||
1836 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 1757 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
1837 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) | 1758 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
1838 | udf_update_tag(epos->bh->b_data, | 1759 | udf_update_tag(epos->bh->b_data, |
@@ -2046,9 +1967,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, | |||
2046 | mark_inode_dirty(inode); | 1967 | mark_inode_dirty(inode); |
2047 | } else { | 1968 | } else { |
2048 | aed = (struct allocExtDesc *)oepos.bh->b_data; | 1969 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
2049 | aed->lengthAllocDescs = | 1970 | le32_add_cpu(&aed->lengthAllocDescs, -(2 * adsize)); |
2050 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - | ||
2051 | (2 * adsize)); | ||
2052 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 1971 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
2053 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) | 1972 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
2054 | udf_update_tag(oepos.bh->b_data, | 1973 | udf_update_tag(oepos.bh->b_data, |
@@ -2065,9 +1984,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos, | |||
2065 | mark_inode_dirty(inode); | 1984 | mark_inode_dirty(inode); |
2066 | } else { | 1985 | } else { |
2067 | aed = (struct allocExtDesc *)oepos.bh->b_data; | 1986 | aed = (struct allocExtDesc *)oepos.bh->b_data; |
2068 | aed->lengthAllocDescs = | 1987 | le32_add_cpu(&aed->lengthAllocDescs, -adsize); |
2069 | cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - | ||
2070 | adsize); | ||
2071 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 1988 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
2072 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) | 1989 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
2073 | udf_update_tag(oepos.bh->b_data, | 1990 | udf_update_tag(oepos.bh->b_data, |
@@ -2095,11 +2012,6 @@ int8_t inode_bmap(struct inode *inode, sector_t block, | |||
2095 | int8_t etype; | 2012 | int8_t etype; |
2096 | struct udf_inode_info *iinfo; | 2013 | struct udf_inode_info *iinfo; |
2097 | 2014 | ||
2098 | if (block < 0) { | ||
2099 | printk(KERN_ERR "udf: inode_bmap: block < 0\n"); | ||
2100 | return -1; | ||
2101 | } | ||
2102 | |||
2103 | iinfo = UDF_I(inode); | 2015 | iinfo = UDF_I(inode); |
2104 | pos->offset = 0; | 2016 | pos->offset = 0; |
2105 | pos->block = iinfo->i_location; | 2017 | pos->block = iinfo->i_location; |
diff --git a/fs/udf/lowlevel.c b/fs/udf/lowlevel.c index 579bae71e67e..703843f30ffd 100644 --- a/fs/udf/lowlevel.c +++ b/fs/udf/lowlevel.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/cdrom.h> | 23 | #include <linux/cdrom.h> |
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | 25 | ||
26 | #include <linux/udf_fs.h> | ||
27 | #include "udf_sb.h" | 26 | #include "udf_sb.h" |
28 | 27 | ||
29 | unsigned int udf_get_last_session(struct super_block *sb) | 28 | unsigned int udf_get_last_session(struct super_block *sb) |
diff --git a/fs/udf/misc.c b/fs/udf/misc.c index a1d6da0caf71..84bf0fd4a4f1 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c | |||
@@ -23,8 +23,8 @@ | |||
23 | 23 | ||
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | #include <linux/udf_fs.h> | ||
27 | #include <linux/buffer_head.h> | 26 | #include <linux/buffer_head.h> |
27 | #include <linux/crc-itu-t.h> | ||
28 | 28 | ||
29 | #include "udf_i.h" | 29 | #include "udf_i.h" |
30 | #include "udf_sb.h" | 30 | #include "udf_sb.h" |
@@ -136,8 +136,8 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, | |||
136 | /* rewrite CRC + checksum of eahd */ | 136 | /* rewrite CRC + checksum of eahd */ |
137 | crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); | 137 | crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); |
138 | eahd->descTag.descCRCLength = cpu_to_le16(crclen); | 138 | eahd->descTag.descCRCLength = cpu_to_le16(crclen); |
139 | eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd + | 139 | eahd->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)eahd + |
140 | sizeof(tag), crclen, 0)); | 140 | sizeof(tag), crclen)); |
141 | eahd->descTag.tagChecksum = udf_tag_checksum(&eahd->descTag); | 141 | eahd->descTag.tagChecksum = udf_tag_checksum(&eahd->descTag); |
142 | iinfo->i_lenEAttr += size; | 142 | iinfo->i_lenEAttr += size; |
143 | return (struct genericFormat *)&ea[offset]; | 143 | return (struct genericFormat *)&ea[offset]; |
@@ -204,16 +204,15 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, | |||
204 | { | 204 | { |
205 | tag *tag_p; | 205 | tag *tag_p; |
206 | struct buffer_head *bh = NULL; | 206 | struct buffer_head *bh = NULL; |
207 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
208 | 207 | ||
209 | /* Read the block */ | 208 | /* Read the block */ |
210 | if (block == 0xFFFFFFFF) | 209 | if (block == 0xFFFFFFFF) |
211 | return NULL; | 210 | return NULL; |
212 | 211 | ||
213 | bh = udf_tread(sb, block + sbi->s_session); | 212 | bh = udf_tread(sb, block); |
214 | if (!bh) { | 213 | if (!bh) { |
215 | udf_debug("block=%d, location=%d: read failed\n", | 214 | udf_debug("block=%d, location=%d: read failed\n", |
216 | block + sbi->s_session, location); | 215 | block, location); |
217 | return NULL; | 216 | return NULL; |
218 | } | 217 | } |
219 | 218 | ||
@@ -223,8 +222,7 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, | |||
223 | 222 | ||
224 | if (location != le32_to_cpu(tag_p->tagLocation)) { | 223 | if (location != le32_to_cpu(tag_p->tagLocation)) { |
225 | udf_debug("location mismatch block %u, tag %u != %u\n", | 224 | udf_debug("location mismatch block %u, tag %u != %u\n", |
226 | block + sbi->s_session, | 225 | block, le32_to_cpu(tag_p->tagLocation), location); |
227 | le32_to_cpu(tag_p->tagLocation), location); | ||
228 | goto error_out; | 226 | goto error_out; |
229 | } | 227 | } |
230 | 228 | ||
@@ -244,13 +242,13 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, | |||
244 | 242 | ||
245 | /* Verify the descriptor CRC */ | 243 | /* Verify the descriptor CRC */ |
246 | if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || | 244 | if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || |
247 | le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag), | 245 | le16_to_cpu(tag_p->descCRC) == crc_itu_t(0, |
248 | le16_to_cpu(tag_p->descCRCLength), 0)) | 246 | bh->b_data + sizeof(tag), |
247 | le16_to_cpu(tag_p->descCRCLength))) | ||
249 | return bh; | 248 | return bh; |
250 | 249 | ||
251 | udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", | 250 | udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", block, |
252 | block + sbi->s_session, le16_to_cpu(tag_p->descCRC), | 251 | le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength)); |
253 | le16_to_cpu(tag_p->descCRCLength)); | ||
254 | 252 | ||
255 | error_out: | 253 | error_out: |
256 | brelse(bh); | 254 | brelse(bh); |
@@ -270,7 +268,7 @@ void udf_update_tag(char *data, int length) | |||
270 | length -= sizeof(tag); | 268 | length -= sizeof(tag); |
271 | 269 | ||
272 | tptr->descCRCLength = cpu_to_le16(length); | 270 | tptr->descCRCLength = cpu_to_le16(length); |
273 | tptr->descCRC = cpu_to_le16(udf_crc(data + sizeof(tag), length, 0)); | 271 | tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(tag), length)); |
274 | tptr->tagChecksum = udf_tag_checksum(tptr); | 272 | tptr->tagChecksum = udf_tag_checksum(tptr); |
275 | } | 273 | } |
276 | 274 | ||
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 112a5fb0b27b..ba5537d4bc15 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/buffer_head.h> | 32 | #include <linux/buffer_head.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/crc-itu-t.h> | ||
34 | 35 | ||
35 | static inline int udf_match(int len1, const char *name1, int len2, | 36 | static inline int udf_match(int len1, const char *name1, int len2, |
36 | const char *name2) | 37 | const char *name2) |
@@ -97,25 +98,23 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, | |||
97 | memset(fibh->ebh->b_data, 0x00, padlen + offset); | 98 | memset(fibh->ebh->b_data, 0x00, padlen + offset); |
98 | } | 99 | } |
99 | 100 | ||
100 | crc = udf_crc((uint8_t *)cfi + sizeof(tag), | 101 | crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(tag), |
101 | sizeof(struct fileIdentDesc) - sizeof(tag), 0); | 102 | sizeof(struct fileIdentDesc) - sizeof(tag)); |
102 | 103 | ||
103 | if (fibh->sbh == fibh->ebh) { | 104 | if (fibh->sbh == fibh->ebh) { |
104 | crc = udf_crc((uint8_t *)sfi->impUse, | 105 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, |
105 | crclen + sizeof(tag) - | 106 | crclen + sizeof(tag) - |
106 | sizeof(struct fileIdentDesc), crc); | 107 | sizeof(struct fileIdentDesc)); |
107 | } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { | 108 | } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { |
108 | crc = udf_crc(fibh->ebh->b_data + | 109 | crc = crc_itu_t(crc, fibh->ebh->b_data + |
109 | sizeof(struct fileIdentDesc) + | 110 | sizeof(struct fileIdentDesc) + |
110 | fibh->soffset, | 111 | fibh->soffset, |
111 | crclen + sizeof(tag) - | 112 | crclen + sizeof(tag) - |
112 | sizeof(struct fileIdentDesc), | 113 | sizeof(struct fileIdentDesc)); |
113 | crc); | ||
114 | } else { | 114 | } else { |
115 | crc = udf_crc((uint8_t *)sfi->impUse, | 115 | crc = crc_itu_t(crc, (uint8_t *)sfi->impUse, |
116 | -fibh->soffset - sizeof(struct fileIdentDesc), | 116 | -fibh->soffset - sizeof(struct fileIdentDesc)); |
117 | crc); | 117 | crc = crc_itu_t(crc, fibh->ebh->b_data, fibh->eoffset); |
118 | crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc); | ||
119 | } | 118 | } |
120 | 119 | ||
121 | cfi->descTag.descCRC = cpu_to_le16(crc); | 120 | cfi->descTag.descCRC = cpu_to_le16(crc); |
@@ -149,7 +148,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
149 | struct fileIdentDesc *fi = NULL; | 148 | struct fileIdentDesc *fi = NULL; |
150 | loff_t f_pos; | 149 | loff_t f_pos; |
151 | int block, flen; | 150 | int block, flen; |
152 | char fname[UDF_NAME_LEN]; | 151 | char *fname = NULL; |
153 | char *nameptr; | 152 | char *nameptr; |
154 | uint8_t lfi; | 153 | uint8_t lfi; |
155 | uint16_t liu; | 154 | uint16_t liu; |
@@ -163,12 +162,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
163 | size = udf_ext0_offset(dir) + dir->i_size; | 162 | size = udf_ext0_offset(dir) + dir->i_size; |
164 | f_pos = udf_ext0_offset(dir); | 163 | f_pos = udf_ext0_offset(dir); |
165 | 164 | ||
165 | fibh->sbh = fibh->ebh = NULL; | ||
166 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 166 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); |
167 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 167 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
168 | fibh->sbh = fibh->ebh = NULL; | 168 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, |
169 | else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, | 169 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) |
170 | &epos, &eloc, &elen, &offset) == | 170 | goto out_err; |
171 | (EXT_RECORDED_ALLOCATED >> 30)) { | ||
172 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 171 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
173 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 172 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
174 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 173 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
@@ -179,25 +178,19 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
179 | offset = 0; | 178 | offset = 0; |
180 | 179 | ||
181 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); | 180 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); |
182 | if (!fibh->sbh) { | 181 | if (!fibh->sbh) |
183 | brelse(epos.bh); | 182 | goto out_err; |
184 | return NULL; | ||
185 | } | ||
186 | } else { | ||
187 | brelse(epos.bh); | ||
188 | return NULL; | ||
189 | } | 183 | } |
190 | 184 | ||
185 | fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||
186 | if (!fname) | ||
187 | goto out_err; | ||
188 | |||
191 | while (f_pos < size) { | 189 | while (f_pos < size) { |
192 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, | 190 | fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, |
193 | &elen, &offset); | 191 | &elen, &offset); |
194 | if (!fi) { | 192 | if (!fi) |
195 | if (fibh->sbh != fibh->ebh) | 193 | goto out_err; |
196 | brelse(fibh->ebh); | ||
197 | brelse(fibh->sbh); | ||
198 | brelse(epos.bh); | ||
199 | return NULL; | ||
200 | } | ||
201 | 194 | ||
202 | liu = le16_to_cpu(cfi->lengthOfImpUse); | 195 | liu = le16_to_cpu(cfi->lengthOfImpUse); |
203 | lfi = cfi->lengthFileIdent; | 196 | lfi = cfi->lengthFileIdent; |
@@ -237,53 +230,22 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
237 | 230 | ||
238 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | 231 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); |
239 | if (flen && udf_match(flen, fname, dentry->d_name.len, | 232 | if (flen && udf_match(flen, fname, dentry->d_name.len, |
240 | dentry->d_name.name)) { | 233 | dentry->d_name.name)) |
241 | brelse(epos.bh); | 234 | goto out_ok; |
242 | return fi; | ||
243 | } | ||
244 | } | 235 | } |
245 | 236 | ||
237 | out_err: | ||
238 | fi = NULL; | ||
246 | if (fibh->sbh != fibh->ebh) | 239 | if (fibh->sbh != fibh->ebh) |
247 | brelse(fibh->ebh); | 240 | brelse(fibh->ebh); |
248 | brelse(fibh->sbh); | 241 | brelse(fibh->sbh); |
242 | out_ok: | ||
249 | brelse(epos.bh); | 243 | brelse(epos.bh); |
244 | kfree(fname); | ||
250 | 245 | ||
251 | return NULL; | 246 | return fi; |
252 | } | 247 | } |
253 | 248 | ||
254 | /* | ||
255 | * udf_lookup | ||
256 | * | ||
257 | * PURPOSE | ||
258 | * Look-up the inode for a given name. | ||
259 | * | ||
260 | * DESCRIPTION | ||
261 | * Required - lookup_dentry() will return -ENOTDIR if this routine is not | ||
262 | * available for a directory. The filesystem is useless if this routine is | ||
263 | * not available for at least the filesystem's root directory. | ||
264 | * | ||
265 | * This routine is passed an incomplete dentry - it must be completed by | ||
266 | * calling d_add(dentry, inode). If the name does not exist, then the | ||
267 | * specified inode must be set to null. An error should only be returned | ||
268 | * when the lookup fails for a reason other than the name not existing. | ||
269 | * Note that the directory inode semaphore is held during the call. | ||
270 | * | ||
271 | * Refer to lookup_dentry() in fs/namei.c | ||
272 | * lookup_dentry() -> lookup() -> real_lookup() -> . | ||
273 | * | ||
274 | * PRE-CONDITIONS | ||
275 | * dir Pointer to inode of parent directory. | ||
276 | * dentry Pointer to dentry to complete. | ||
277 | * nd Pointer to lookup nameidata | ||
278 | * | ||
279 | * POST-CONDITIONS | ||
280 | * <return> Zero on success. | ||
281 | * | ||
282 | * HISTORY | ||
283 | * July 1, 1997 - Andrew E. Mileski | ||
284 | * Written, tested, and released. | ||
285 | */ | ||
286 | |||
287 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | 249 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, |
288 | struct nameidata *nd) | 250 | struct nameidata *nd) |
289 | { | 251 | { |
@@ -336,11 +298,9 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
336 | { | 298 | { |
337 | struct super_block *sb = dir->i_sb; | 299 | struct super_block *sb = dir->i_sb; |
338 | struct fileIdentDesc *fi = NULL; | 300 | struct fileIdentDesc *fi = NULL; |
339 | char name[UDF_NAME_LEN], fname[UDF_NAME_LEN]; | 301 | char *name = NULL; |
340 | int namelen; | 302 | int namelen; |
341 | loff_t f_pos; | 303 | loff_t f_pos; |
342 | int flen; | ||
343 | char *nameptr; | ||
344 | loff_t size = udf_ext0_offset(dir) + dir->i_size; | 304 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
345 | int nfidlen; | 305 | int nfidlen; |
346 | uint8_t lfi; | 306 | uint8_t lfi; |
@@ -352,16 +312,23 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
352 | struct extent_position epos = {}; | 312 | struct extent_position epos = {}; |
353 | struct udf_inode_info *dinfo; | 313 | struct udf_inode_info *dinfo; |
354 | 314 | ||
315 | fibh->sbh = fibh->ebh = NULL; | ||
316 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||
317 | if (!name) { | ||
318 | *err = -ENOMEM; | ||
319 | goto out_err; | ||
320 | } | ||
321 | |||
355 | if (dentry) { | 322 | if (dentry) { |
356 | if (!dentry->d_name.len) { | 323 | if (!dentry->d_name.len) { |
357 | *err = -EINVAL; | 324 | *err = -EINVAL; |
358 | return NULL; | 325 | goto out_err; |
359 | } | 326 | } |
360 | namelen = udf_put_filename(sb, dentry->d_name.name, name, | 327 | namelen = udf_put_filename(sb, dentry->d_name.name, name, |
361 | dentry->d_name.len); | 328 | dentry->d_name.len); |
362 | if (!namelen) { | 329 | if (!namelen) { |
363 | *err = -ENAMETOOLONG; | 330 | *err = -ENAMETOOLONG; |
364 | return NULL; | 331 | goto out_err; |
365 | } | 332 | } |
366 | } else { | 333 | } else { |
367 | namelen = 0; | 334 | namelen = 0; |
@@ -373,11 +340,14 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
373 | 340 | ||
374 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 341 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); |
375 | dinfo = UDF_I(dir); | 342 | dinfo = UDF_I(dir); |
376 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 343 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
377 | fibh->sbh = fibh->ebh = NULL; | 344 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, |
378 | else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, | 345 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) { |
379 | &epos, &eloc, &elen, &offset) == | 346 | block = udf_get_lb_pblock(dir->i_sb, |
380 | (EXT_RECORDED_ALLOCATED >> 30)) { | 347 | dinfo->i_location, 0); |
348 | fibh->soffset = fibh->eoffset = sb->s_blocksize; | ||
349 | goto add; | ||
350 | } | ||
381 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 351 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
382 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 352 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
383 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 353 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
@@ -389,17 +359,11 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
389 | 359 | ||
390 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); | 360 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); |
391 | if (!fibh->sbh) { | 361 | if (!fibh->sbh) { |
392 | brelse(epos.bh); | ||
393 | *err = -EIO; | 362 | *err = -EIO; |
394 | return NULL; | 363 | goto out_err; |
395 | } | 364 | } |
396 | 365 | ||
397 | block = dinfo->i_location.logicalBlockNum; | 366 | block = dinfo->i_location.logicalBlockNum; |
398 | } else { | ||
399 | block = udf_get_lb_pblock(dir->i_sb, dinfo->i_location, 0); | ||
400 | fibh->sbh = fibh->ebh = NULL; | ||
401 | fibh->soffset = fibh->eoffset = sb->s_blocksize; | ||
402 | goto add; | ||
403 | } | 367 | } |
404 | 368 | ||
405 | while (f_pos < size) { | 369 | while (f_pos < size) { |
@@ -407,41 +371,16 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
407 | &elen, &offset); | 371 | &elen, &offset); |
408 | 372 | ||
409 | if (!fi) { | 373 | if (!fi) { |
410 | if (fibh->sbh != fibh->ebh) | ||
411 | brelse(fibh->ebh); | ||
412 | brelse(fibh->sbh); | ||
413 | brelse(epos.bh); | ||
414 | *err = -EIO; | 374 | *err = -EIO; |
415 | return NULL; | 375 | goto out_err; |
416 | } | 376 | } |
417 | 377 | ||
418 | liu = le16_to_cpu(cfi->lengthOfImpUse); | 378 | liu = le16_to_cpu(cfi->lengthOfImpUse); |
419 | lfi = cfi->lengthFileIdent; | 379 | lfi = cfi->lengthFileIdent; |
420 | 380 | ||
421 | if (fibh->sbh == fibh->ebh) | ||
422 | nameptr = fi->fileIdent + liu; | ||
423 | else { | ||
424 | int poffset; /* Unpaded ending offset */ | ||
425 | |||
426 | poffset = fibh->soffset + sizeof(struct fileIdentDesc) + | ||
427 | liu + lfi; | ||
428 | |||
429 | if (poffset >= lfi) | ||
430 | nameptr = (char *)(fibh->ebh->b_data + | ||
431 | poffset - lfi); | ||
432 | else { | ||
433 | nameptr = fname; | ||
434 | memcpy(nameptr, fi->fileIdent + liu, | ||
435 | lfi - poffset); | ||
436 | memcpy(nameptr + lfi - poffset, | ||
437 | fibh->ebh->b_data, poffset); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { | 381 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
442 | if (((sizeof(struct fileIdentDesc) + | 382 | if (((sizeof(struct fileIdentDesc) + |
443 | liu + lfi + 3) & ~3) == nfidlen) { | 383 | liu + lfi + 3) & ~3) == nfidlen) { |
444 | brelse(epos.bh); | ||
445 | cfi->descTag.tagSerialNum = cpu_to_le16(1); | 384 | cfi->descTag.tagSerialNum = cpu_to_le16(1); |
446 | cfi->fileVersionNum = cpu_to_le16(1); | 385 | cfi->fileVersionNum = cpu_to_le16(1); |
447 | cfi->fileCharacteristics = 0; | 386 | cfi->fileCharacteristics = 0; |
@@ -449,27 +388,13 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, | |||
449 | cfi->lengthOfImpUse = cpu_to_le16(0); | 388 | cfi->lengthOfImpUse = cpu_to_le16(0); |
450 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, | 389 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, |
451 | name)) | 390 | name)) |
452 | return fi; | 391 | goto out_ok; |
453 | else { | 392 | else { |
454 | *err = -EIO; | 393 | *err = -EIO; |
455 | return NULL; | 394 | goto out_err; |
456 | } | 395 | } |
457 | } | 396 | } |
458 | } | 397 | } |
459 | |||
460 | if (!lfi || !dentry) | ||
461 | continue; | ||
462 | |||
463 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | ||
464 | if (flen && udf_match(flen, fname, dentry->d_name.len, | ||
465 | dentry->d_name.name)) { | ||
466 | if (fibh->sbh != fibh->ebh) | ||
467 | brelse(fibh->ebh); | ||
468 | brelse(fibh->sbh); | ||
469 | brelse(epos.bh); | ||
470 | *err = -EEXIST; | ||
471 | return NULL; | ||
472 | } | ||
473 | } | 398 | } |
474 | 399 | ||
475 | add: | 400 | add: |
@@ -496,7 +421,7 @@ add: | |||
496 | fibh->sbh = fibh->ebh = | 421 | fibh->sbh = fibh->ebh = |
497 | udf_expand_dir_adinicb(dir, &block, err); | 422 | udf_expand_dir_adinicb(dir, &block, err); |
498 | if (!fibh->sbh) | 423 | if (!fibh->sbh) |
499 | return NULL; | 424 | goto out_err; |
500 | epos.block = dinfo->i_location; | 425 | epos.block = dinfo->i_location; |
501 | epos.offset = udf_file_entry_alloc_offset(dir); | 426 | epos.offset = udf_file_entry_alloc_offset(dir); |
502 | /* Load extent udf_expand_dir_adinicb() has created */ | 427 | /* Load extent udf_expand_dir_adinicb() has created */ |
@@ -537,11 +462,8 @@ add: | |||
537 | dir->i_sb->s_blocksize_bits); | 462 | dir->i_sb->s_blocksize_bits); |
538 | fibh->ebh = udf_bread(dir, | 463 | fibh->ebh = udf_bread(dir, |
539 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); | 464 | f_pos >> dir->i_sb->s_blocksize_bits, 1, err); |
540 | if (!fibh->ebh) { | 465 | if (!fibh->ebh) |
541 | brelse(epos.bh); | 466 | goto out_err; |
542 | brelse(fibh->sbh); | ||
543 | return NULL; | ||
544 | } | ||
545 | 467 | ||
546 | if (!fibh->soffset) { | 468 | if (!fibh->soffset) { |
547 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == | 469 | if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == |
@@ -572,20 +494,25 @@ add: | |||
572 | cfi->lengthFileIdent = namelen; | 494 | cfi->lengthFileIdent = namelen; |
573 | cfi->lengthOfImpUse = cpu_to_le16(0); | 495 | cfi->lengthOfImpUse = cpu_to_le16(0); |
574 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) { | 496 | if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) { |
575 | brelse(epos.bh); | ||
576 | dir->i_size += nfidlen; | 497 | dir->i_size += nfidlen; |
577 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 498 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
578 | dinfo->i_lenAlloc += nfidlen; | 499 | dinfo->i_lenAlloc += nfidlen; |
579 | mark_inode_dirty(dir); | 500 | mark_inode_dirty(dir); |
580 | return fi; | 501 | goto out_ok; |
581 | } else { | 502 | } else { |
582 | brelse(epos.bh); | ||
583 | if (fibh->sbh != fibh->ebh) | ||
584 | brelse(fibh->ebh); | ||
585 | brelse(fibh->sbh); | ||
586 | *err = -EIO; | 503 | *err = -EIO; |
587 | return NULL; | 504 | goto out_err; |
588 | } | 505 | } |
506 | |||
507 | out_err: | ||
508 | fi = NULL; | ||
509 | if (fibh->sbh != fibh->ebh) | ||
510 | brelse(fibh->ebh); | ||
511 | brelse(fibh->sbh); | ||
512 | out_ok: | ||
513 | brelse(epos.bh); | ||
514 | kfree(name); | ||
515 | return fi; | ||
589 | } | 516 | } |
590 | 517 | ||
591 | static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, | 518 | static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, |
@@ -940,7 +867,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
940 | char *ea; | 867 | char *ea; |
941 | int err; | 868 | int err; |
942 | int block; | 869 | int block; |
943 | char name[UDF_NAME_LEN]; | 870 | char *name = NULL; |
944 | int namelen; | 871 | int namelen; |
945 | struct buffer_head *bh; | 872 | struct buffer_head *bh; |
946 | struct udf_inode_info *iinfo; | 873 | struct udf_inode_info *iinfo; |
@@ -950,6 +877,12 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
950 | if (!inode) | 877 | if (!inode) |
951 | goto out; | 878 | goto out; |
952 | 879 | ||
880 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | ||
881 | if (!name) { | ||
882 | err = -ENOMEM; | ||
883 | goto out_no_entry; | ||
884 | } | ||
885 | |||
953 | iinfo = UDF_I(inode); | 886 | iinfo = UDF_I(inode); |
954 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 887 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
955 | inode->i_data.a_ops = &udf_symlink_aops; | 888 | inode->i_data.a_ops = &udf_symlink_aops; |
@@ -1089,6 +1022,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1089 | err = 0; | 1022 | err = 0; |
1090 | 1023 | ||
1091 | out: | 1024 | out: |
1025 | kfree(name); | ||
1092 | unlock_kernel(); | 1026 | unlock_kernel(); |
1093 | return err; | 1027 | return err; |
1094 | 1028 | ||
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index fc533345ab89..63610f026ae1 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/udf_fs.h> | ||
28 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
29 | #include <linux/buffer_head.h> | 28 | #include <linux/buffer_head.h> |
30 | 29 | ||
@@ -55,11 +54,10 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, | |||
55 | struct udf_sb_info *sbi = UDF_SB(sb); | 54 | struct udf_sb_info *sbi = UDF_SB(sb); |
56 | struct udf_part_map *map; | 55 | struct udf_part_map *map; |
57 | struct udf_virtual_data *vdata; | 56 | struct udf_virtual_data *vdata; |
58 | struct udf_inode_info *iinfo; | 57 | struct udf_inode_info *iinfo = UDF_I(sbi->s_vat_inode); |
59 | 58 | ||
60 | map = &sbi->s_partmaps[partition]; | 59 | map = &sbi->s_partmaps[partition]; |
61 | vdata = &map->s_type_specific.s_virtual; | 60 | vdata = &map->s_type_specific.s_virtual; |
62 | index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t); | ||
63 | 61 | ||
64 | if (block > vdata->s_num_entries) { | 62 | if (block > vdata->s_num_entries) { |
65 | udf_debug("Trying to access block beyond end of VAT " | 63 | udf_debug("Trying to access block beyond end of VAT " |
@@ -67,6 +65,12 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, | |||
67 | return 0xFFFFFFFF; | 65 | return 0xFFFFFFFF; |
68 | } | 66 | } |
69 | 67 | ||
68 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | ||
69 | loc = le32_to_cpu(((__le32 *)(iinfo->i_ext.i_data + | ||
70 | vdata->s_start_offset))[block]); | ||
71 | goto translate; | ||
72 | } | ||
73 | index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t); | ||
70 | if (block >= index) { | 74 | if (block >= index) { |
71 | block -= index; | 75 | block -= index; |
72 | newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t))); | 76 | newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t))); |
@@ -89,7 +93,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, | |||
89 | 93 | ||
90 | brelse(bh); | 94 | brelse(bh); |
91 | 95 | ||
92 | iinfo = UDF_I(sbi->s_vat_inode); | 96 | translate: |
93 | if (iinfo->i_location.partitionReferenceNum == partition) { | 97 | if (iinfo->i_location.partitionReferenceNum == partition) { |
94 | udf_debug("recursive call to udf_get_pblock!\n"); | 98 | udf_debug("recursive call to udf_get_pblock!\n"); |
95 | return 0xFFFFFFFF; | 99 | return 0xFFFFFFFF; |
@@ -263,3 +267,58 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
263 | 267 | ||
264 | return 0; | 268 | return 0; |
265 | } | 269 | } |
270 | |||
271 | static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, | ||
272 | uint16_t partition, uint32_t offset) | ||
273 | { | ||
274 | struct super_block *sb = inode->i_sb; | ||
275 | struct udf_part_map *map; | ||
276 | kernel_lb_addr eloc; | ||
277 | uint32_t elen; | ||
278 | sector_t ext_offset; | ||
279 | struct extent_position epos = {}; | ||
280 | uint32_t phyblock; | ||
281 | |||
282 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset) != | ||
283 | (EXT_RECORDED_ALLOCATED >> 30)) | ||
284 | phyblock = 0xFFFFFFFF; | ||
285 | else { | ||
286 | map = &UDF_SB(sb)->s_partmaps[partition]; | ||
287 | /* map to sparable/physical partition desc */ | ||
288 | phyblock = udf_get_pblock(sb, eloc.logicalBlockNum, | ||
289 | map->s_partition_num, ext_offset + offset); | ||
290 | } | ||
291 | |||
292 | brelse(epos.bh); | ||
293 | return phyblock; | ||
294 | } | ||
295 | |||
296 | uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block, | ||
297 | uint16_t partition, uint32_t offset) | ||
298 | { | ||
299 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
300 | struct udf_part_map *map; | ||
301 | struct udf_meta_data *mdata; | ||
302 | uint32_t retblk; | ||
303 | struct inode *inode; | ||
304 | |||
305 | udf_debug("READING from METADATA\n"); | ||
306 | |||
307 | map = &sbi->s_partmaps[partition]; | ||
308 | mdata = &map->s_type_specific.s_metadata; | ||
309 | inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe; | ||
310 | |||
311 | /* We shouldn't mount such media... */ | ||
312 | BUG_ON(!inode); | ||
313 | retblk = udf_try_read_meta(inode, block, partition, offset); | ||
314 | if (retblk == 0xFFFFFFFF) { | ||
315 | udf_warning(sb, __func__, "error reading from METADATA, " | ||
316 | "trying to read from MIRROR"); | ||
317 | inode = mdata->s_mirror_fe; | ||
318 | if (!inode) | ||
319 | return 0xFFFFFFFF; | ||
320 | retblk = udf_try_read_meta(inode, block, partition, offset); | ||
321 | } | ||
322 | |||
323 | return retblk; | ||
324 | } | ||
diff --git a/fs/udf/super.c b/fs/udf/super.c index f3ac4abfc946..b564fc140fe4 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -55,9 +55,10 @@ | |||
55 | #include <linux/errno.h> | 55 | #include <linux/errno.h> |
56 | #include <linux/mount.h> | 56 | #include <linux/mount.h> |
57 | #include <linux/seq_file.h> | 57 | #include <linux/seq_file.h> |
58 | #include <linux/bitmap.h> | ||
59 | #include <linux/crc-itu-t.h> | ||
58 | #include <asm/byteorder.h> | 60 | #include <asm/byteorder.h> |
59 | 61 | ||
60 | #include <linux/udf_fs.h> | ||
61 | #include "udf_sb.h" | 62 | #include "udf_sb.h" |
62 | #include "udf_i.h" | 63 | #include "udf_i.h" |
63 | 64 | ||
@@ -84,22 +85,19 @@ static void udf_write_super(struct super_block *); | |||
84 | static int udf_remount_fs(struct super_block *, int *, char *); | 85 | static int udf_remount_fs(struct super_block *, int *, char *); |
85 | static int udf_check_valid(struct super_block *, int, int); | 86 | static int udf_check_valid(struct super_block *, int, int); |
86 | static int udf_vrs(struct super_block *sb, int silent); | 87 | static int udf_vrs(struct super_block *sb, int silent); |
87 | static int udf_load_partition(struct super_block *, kernel_lb_addr *); | ||
88 | static int udf_load_logicalvol(struct super_block *, struct buffer_head *, | ||
89 | kernel_lb_addr *); | ||
90 | static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); | 88 | static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); |
91 | static void udf_find_anchor(struct super_block *); | 89 | static void udf_find_anchor(struct super_block *); |
92 | static int udf_find_fileset(struct super_block *, kernel_lb_addr *, | 90 | static int udf_find_fileset(struct super_block *, kernel_lb_addr *, |
93 | kernel_lb_addr *); | 91 | kernel_lb_addr *); |
94 | static void udf_load_pvoldesc(struct super_block *, struct buffer_head *); | ||
95 | static void udf_load_fileset(struct super_block *, struct buffer_head *, | 92 | static void udf_load_fileset(struct super_block *, struct buffer_head *, |
96 | kernel_lb_addr *); | 93 | kernel_lb_addr *); |
97 | static int udf_load_partdesc(struct super_block *, struct buffer_head *); | ||
98 | static void udf_open_lvid(struct super_block *); | 94 | static void udf_open_lvid(struct super_block *); |
99 | static void udf_close_lvid(struct super_block *); | 95 | static void udf_close_lvid(struct super_block *); |
100 | static unsigned int udf_count_free(struct super_block *); | 96 | static unsigned int udf_count_free(struct super_block *); |
101 | static int udf_statfs(struct dentry *, struct kstatfs *); | 97 | static int udf_statfs(struct dentry *, struct kstatfs *); |
102 | static int udf_show_options(struct seq_file *, struct vfsmount *); | 98 | static int udf_show_options(struct seq_file *, struct vfsmount *); |
99 | static void udf_error(struct super_block *sb, const char *function, | ||
100 | const char *fmt, ...); | ||
103 | 101 | ||
104 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) | 102 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) |
105 | { | 103 | { |
@@ -587,48 +585,10 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
587 | return 0; | 585 | return 0; |
588 | } | 586 | } |
589 | 587 | ||
590 | /* | ||
591 | * udf_set_blocksize | ||
592 | * | ||
593 | * PURPOSE | ||
594 | * Set the block size to be used in all transfers. | ||
595 | * | ||
596 | * DESCRIPTION | ||
597 | * To allow room for a DMA transfer, it is best to guess big when unsure. | ||
598 | * This routine picks 2048 bytes as the blocksize when guessing. This | ||
599 | * should be adequate until devices with larger block sizes become common. | ||
600 | * | ||
601 | * Note that the Linux kernel can currently only deal with blocksizes of | ||
602 | * 512, 1024, 2048, 4096, and 8192 bytes. | ||
603 | * | ||
604 | * PRE-CONDITIONS | ||
605 | * sb Pointer to _locked_ superblock. | ||
606 | * | ||
607 | * POST-CONDITIONS | ||
608 | * sb->s_blocksize Blocksize. | ||
609 | * sb->s_blocksize_bits log2 of blocksize. | ||
610 | * <return> 0 Blocksize is valid. | ||
611 | * <return> 1 Blocksize is invalid. | ||
612 | * | ||
613 | * HISTORY | ||
614 | * July 1, 1997 - Andrew E. Mileski | ||
615 | * Written, tested, and released. | ||
616 | */ | ||
617 | static int udf_set_blocksize(struct super_block *sb, int bsize) | ||
618 | { | ||
619 | if (!sb_min_blocksize(sb, bsize)) { | ||
620 | udf_debug("Bad block size (%d)\n", bsize); | ||
621 | printk(KERN_ERR "udf: bad block size (%d)\n", bsize); | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | return sb->s_blocksize; | ||
626 | } | ||
627 | |||
628 | static int udf_vrs(struct super_block *sb, int silent) | 588 | static int udf_vrs(struct super_block *sb, int silent) |
629 | { | 589 | { |
630 | struct volStructDesc *vsd = NULL; | 590 | struct volStructDesc *vsd = NULL; |
631 | int sector = 32768; | 591 | loff_t sector = 32768; |
632 | int sectorsize; | 592 | int sectorsize; |
633 | struct buffer_head *bh = NULL; | 593 | struct buffer_head *bh = NULL; |
634 | int iso9660 = 0; | 594 | int iso9660 = 0; |
@@ -649,7 +609,8 @@ static int udf_vrs(struct super_block *sb, int silent) | |||
649 | sector += (sbi->s_session << sb->s_blocksize_bits); | 609 | sector += (sbi->s_session << sb->s_blocksize_bits); |
650 | 610 | ||
651 | udf_debug("Starting at sector %u (%ld byte sectors)\n", | 611 | udf_debug("Starting at sector %u (%ld byte sectors)\n", |
652 | (sector >> sb->s_blocksize_bits), sb->s_blocksize); | 612 | (unsigned int)(sector >> sb->s_blocksize_bits), |
613 | sb->s_blocksize); | ||
653 | /* Process the sequence (if applicable) */ | 614 | /* Process the sequence (if applicable) */ |
654 | for (; !nsr02 && !nsr03; sector += sectorsize) { | 615 | for (; !nsr02 && !nsr03; sector += sectorsize) { |
655 | /* Read a block */ | 616 | /* Read a block */ |
@@ -719,162 +680,140 @@ static int udf_vrs(struct super_block *sb, int silent) | |||
719 | } | 680 | } |
720 | 681 | ||
721 | /* | 682 | /* |
722 | * udf_find_anchor | 683 | * Check whether there is an anchor block in the given block |
723 | * | ||
724 | * PURPOSE | ||
725 | * Find an anchor volume descriptor. | ||
726 | * | ||
727 | * PRE-CONDITIONS | ||
728 | * sb Pointer to _locked_ superblock. | ||
729 | * lastblock Last block on media. | ||
730 | * | ||
731 | * POST-CONDITIONS | ||
732 | * <return> 1 if not found, 0 if ok | ||
733 | * | ||
734 | * HISTORY | ||
735 | * July 1, 1997 - Andrew E. Mileski | ||
736 | * Written, tested, and released. | ||
737 | */ | 684 | */ |
738 | static void udf_find_anchor(struct super_block *sb) | 685 | static int udf_check_anchor_block(struct super_block *sb, sector_t block, |
686 | bool varconv) | ||
739 | { | 687 | { |
740 | int lastblock; | ||
741 | struct buffer_head *bh = NULL; | 688 | struct buffer_head *bh = NULL; |
689 | tag *t; | ||
742 | uint16_t ident; | 690 | uint16_t ident; |
743 | uint32_t location; | 691 | uint32_t location; |
744 | int i; | ||
745 | struct udf_sb_info *sbi; | ||
746 | 692 | ||
747 | sbi = UDF_SB(sb); | 693 | if (varconv) { |
748 | lastblock = sbi->s_last_block; | 694 | if (udf_fixed_to_variable(block) >= |
695 | sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) | ||
696 | return 0; | ||
697 | bh = sb_bread(sb, udf_fixed_to_variable(block)); | ||
698 | } | ||
699 | else | ||
700 | bh = sb_bread(sb, block); | ||
749 | 701 | ||
750 | if (lastblock) { | 702 | if (!bh) |
751 | int varlastblock = udf_variable_to_fixed(lastblock); | 703 | return 0; |
752 | int last[] = { lastblock, lastblock - 2, | ||
753 | lastblock - 150, lastblock - 152, | ||
754 | varlastblock, varlastblock - 2, | ||
755 | varlastblock - 150, varlastblock - 152 }; | ||
756 | |||
757 | lastblock = 0; | ||
758 | |||
759 | /* Search for an anchor volume descriptor pointer */ | ||
760 | |||
761 | /* according to spec, anchor is in either: | ||
762 | * block 256 | ||
763 | * lastblock-256 | ||
764 | * lastblock | ||
765 | * however, if the disc isn't closed, it could be 512 */ | ||
766 | |||
767 | for (i = 0; !lastblock && i < ARRAY_SIZE(last); i++) { | ||
768 | ident = location = 0; | ||
769 | if (last[i] >= 0) { | ||
770 | bh = sb_bread(sb, last[i]); | ||
771 | if (bh) { | ||
772 | tag *t = (tag *)bh->b_data; | ||
773 | ident = le16_to_cpu(t->tagIdent); | ||
774 | location = le32_to_cpu(t->tagLocation); | ||
775 | brelse(bh); | ||
776 | } | ||
777 | } | ||
778 | 704 | ||
779 | if (ident == TAG_IDENT_AVDP) { | 705 | t = (tag *)bh->b_data; |
780 | if (location == last[i] - sbi->s_session) { | 706 | ident = le16_to_cpu(t->tagIdent); |
781 | lastblock = last[i] - sbi->s_session; | 707 | location = le32_to_cpu(t->tagLocation); |
782 | sbi->s_anchor[0] = lastblock; | 708 | brelse(bh); |
783 | sbi->s_anchor[1] = lastblock - 256; | 709 | if (ident != TAG_IDENT_AVDP) |
784 | } else if (location == | 710 | return 0; |
785 | udf_variable_to_fixed(last[i]) - | 711 | return location == block; |
786 | sbi->s_session) { | 712 | } |
787 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
788 | lastblock = | ||
789 | udf_variable_to_fixed(last[i]) - | ||
790 | sbi->s_session; | ||
791 | sbi->s_anchor[0] = lastblock; | ||
792 | sbi->s_anchor[1] = lastblock - 256 - | ||
793 | sbi->s_session; | ||
794 | } else { | ||
795 | udf_debug("Anchor found at block %d, " | ||
796 | "location mismatch %d.\n", | ||
797 | last[i], location); | ||
798 | } | ||
799 | } else if (ident == TAG_IDENT_FE || | ||
800 | ident == TAG_IDENT_EFE) { | ||
801 | lastblock = last[i]; | ||
802 | sbi->s_anchor[3] = 512; | ||
803 | } else { | ||
804 | ident = location = 0; | ||
805 | if (last[i] >= 256) { | ||
806 | bh = sb_bread(sb, last[i] - 256); | ||
807 | if (bh) { | ||
808 | tag *t = (tag *)bh->b_data; | ||
809 | ident = le16_to_cpu( | ||
810 | t->tagIdent); | ||
811 | location = le32_to_cpu( | ||
812 | t->tagLocation); | ||
813 | brelse(bh); | ||
814 | } | ||
815 | } | ||
816 | 713 | ||
817 | if (ident == TAG_IDENT_AVDP && | 714 | /* Search for an anchor volume descriptor pointer */ |
818 | location == last[i] - 256 - | 715 | static sector_t udf_scan_anchors(struct super_block *sb, bool varconv, |
819 | sbi->s_session) { | 716 | sector_t lastblock) |
820 | lastblock = last[i]; | 717 | { |
821 | sbi->s_anchor[1] = last[i] - 256; | 718 | sector_t last[6]; |
822 | } else { | 719 | int i; |
823 | ident = location = 0; | 720 | struct udf_sb_info *sbi = UDF_SB(sb); |
824 | if (last[i] >= 312 + sbi->s_session) { | ||
825 | bh = sb_bread(sb, | ||
826 | last[i] - 312 - | ||
827 | sbi->s_session); | ||
828 | if (bh) { | ||
829 | tag *t = (tag *) | ||
830 | bh->b_data; | ||
831 | ident = le16_to_cpu( | ||
832 | t->tagIdent); | ||
833 | location = le32_to_cpu( | ||
834 | t->tagLocation); | ||
835 | brelse(bh); | ||
836 | } | ||
837 | } | ||
838 | 721 | ||
839 | if (ident == TAG_IDENT_AVDP && | 722 | last[0] = lastblock; |
840 | location == udf_variable_to_fixed(last[i]) - 256) { | 723 | last[1] = last[0] - 1; |
841 | UDF_SET_FLAG(sb, | 724 | last[2] = last[0] + 1; |
842 | UDF_FLAG_VARCONV); | 725 | last[3] = last[0] - 2; |
843 | lastblock = udf_variable_to_fixed(last[i]); | 726 | last[4] = last[0] - 150; |
844 | sbi->s_anchor[1] = lastblock - 256; | 727 | last[5] = last[0] - 152; |
845 | } | 728 | |
846 | } | 729 | /* according to spec, anchor is in either: |
847 | } | 730 | * block 256 |
731 | * lastblock-256 | ||
732 | * lastblock | ||
733 | * however, if the disc isn't closed, it could be 512 */ | ||
734 | |||
735 | for (i = 0; i < ARRAY_SIZE(last); i++) { | ||
736 | if (last[i] < 0) | ||
737 | continue; | ||
738 | if (last[i] >= sb->s_bdev->bd_inode->i_size >> | ||
739 | sb->s_blocksize_bits) | ||
740 | continue; | ||
741 | |||
742 | if (udf_check_anchor_block(sb, last[i], varconv)) { | ||
743 | sbi->s_anchor[0] = last[i]; | ||
744 | sbi->s_anchor[1] = last[i] - 256; | ||
745 | return last[i]; | ||
848 | } | 746 | } |
849 | } | ||
850 | 747 | ||
851 | if (!lastblock) { | 748 | if (last[i] < 256) |
852 | /* We haven't found the lastblock. check 312 */ | 749 | continue; |
853 | bh = sb_bread(sb, 312 + sbi->s_session); | ||
854 | if (bh) { | ||
855 | tag *t = (tag *)bh->b_data; | ||
856 | ident = le16_to_cpu(t->tagIdent); | ||
857 | location = le32_to_cpu(t->tagLocation); | ||
858 | brelse(bh); | ||
859 | 750 | ||
860 | if (ident == TAG_IDENT_AVDP && location == 256) | 751 | if (udf_check_anchor_block(sb, last[i] - 256, varconv)) { |
861 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | 752 | sbi->s_anchor[1] = last[i] - 256; |
753 | return last[i]; | ||
862 | } | 754 | } |
863 | } | 755 | } |
864 | 756 | ||
757 | if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) { | ||
758 | sbi->s_anchor[0] = sbi->s_session + 256; | ||
759 | return last[0]; | ||
760 | } | ||
761 | if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) { | ||
762 | sbi->s_anchor[0] = sbi->s_session + 512; | ||
763 | return last[0]; | ||
764 | } | ||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | /* | ||
769 | * Find an anchor volume descriptor. The function expects sbi->s_lastblock to | ||
770 | * be the last block on the media. | ||
771 | * | ||
772 | * Return 1 if not found, 0 if ok | ||
773 | * | ||
774 | */ | ||
775 | static void udf_find_anchor(struct super_block *sb) | ||
776 | { | ||
777 | sector_t lastblock; | ||
778 | struct buffer_head *bh = NULL; | ||
779 | uint16_t ident; | ||
780 | int i; | ||
781 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
782 | |||
783 | lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block); | ||
784 | if (lastblock) | ||
785 | goto check_anchor; | ||
786 | |||
787 | /* No anchor found? Try VARCONV conversion of block numbers */ | ||
788 | /* Firstly, we try to not convert number of the last block */ | ||
789 | lastblock = udf_scan_anchors(sb, 1, | ||
790 | udf_variable_to_fixed(sbi->s_last_block)); | ||
791 | if (lastblock) { | ||
792 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
793 | goto check_anchor; | ||
794 | } | ||
795 | |||
796 | /* Secondly, we try with converted number of the last block */ | ||
797 | lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block); | ||
798 | if (lastblock) | ||
799 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
800 | |||
801 | check_anchor: | ||
802 | /* | ||
803 | * Check located anchors and the anchor block supplied via | ||
804 | * mount options | ||
805 | */ | ||
865 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { | 806 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { |
866 | if (sbi->s_anchor[i]) { | 807 | if (!sbi->s_anchor[i]) |
867 | bh = udf_read_tagged(sb, sbi->s_anchor[i], | 808 | continue; |
868 | sbi->s_anchor[i], &ident); | 809 | bh = udf_read_tagged(sb, sbi->s_anchor[i], |
869 | if (!bh) | 810 | sbi->s_anchor[i], &ident); |
811 | if (!bh) | ||
812 | sbi->s_anchor[i] = 0; | ||
813 | else { | ||
814 | brelse(bh); | ||
815 | if (ident != TAG_IDENT_AVDP) | ||
870 | sbi->s_anchor[i] = 0; | 816 | sbi->s_anchor[i] = 0; |
871 | else { | ||
872 | brelse(bh); | ||
873 | if ((ident != TAG_IDENT_AVDP) && | ||
874 | (i || (ident != TAG_IDENT_FE && | ||
875 | ident != TAG_IDENT_EFE))) | ||
876 | sbi->s_anchor[i] = 0; | ||
877 | } | ||
878 | } | 817 | } |
879 | } | 818 | } |
880 | 819 | ||
@@ -971,27 +910,30 @@ static int udf_find_fileset(struct super_block *sb, | |||
971 | return 1; | 910 | return 1; |
972 | } | 911 | } |
973 | 912 | ||
974 | static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh) | 913 | static int udf_load_pvoldesc(struct super_block *sb, sector_t block) |
975 | { | 914 | { |
976 | struct primaryVolDesc *pvoldesc; | 915 | struct primaryVolDesc *pvoldesc; |
977 | time_t recording; | ||
978 | long recording_usec; | ||
979 | struct ustr instr; | 916 | struct ustr instr; |
980 | struct ustr outstr; | 917 | struct ustr outstr; |
918 | struct buffer_head *bh; | ||
919 | uint16_t ident; | ||
920 | |||
921 | bh = udf_read_tagged(sb, block, block, &ident); | ||
922 | if (!bh) | ||
923 | return 1; | ||
924 | BUG_ON(ident != TAG_IDENT_PVD); | ||
981 | 925 | ||
982 | pvoldesc = (struct primaryVolDesc *)bh->b_data; | 926 | pvoldesc = (struct primaryVolDesc *)bh->b_data; |
983 | 927 | ||
984 | if (udf_stamp_to_time(&recording, &recording_usec, | 928 | if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, |
985 | lets_to_cpu(pvoldesc->recordingDateAndTime))) { | 929 | pvoldesc->recordingDateAndTime)) { |
986 | kernel_timestamp ts; | 930 | #ifdef UDFFS_DEBUG |
987 | ts = lets_to_cpu(pvoldesc->recordingDateAndTime); | 931 | timestamp *ts = &pvoldesc->recordingDateAndTime; |
988 | udf_debug("recording time %ld/%ld, %04u/%02u/%02u" | 932 | udf_debug("recording time %04u/%02u/%02u" |
989 | " %02u:%02u (%x)\n", | 933 | " %02u:%02u (%x)\n", |
990 | recording, recording_usec, | 934 | le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, |
991 | ts.year, ts.month, ts.day, ts.hour, | 935 | ts->minute, le16_to_cpu(ts->typeAndTimezone)); |
992 | ts.minute, ts.typeAndTimezone); | 936 | #endif |
993 | UDF_SB(sb)->s_record_time.tv_sec = recording; | ||
994 | UDF_SB(sb)->s_record_time.tv_nsec = recording_usec * 1000; | ||
995 | } | 937 | } |
996 | 938 | ||
997 | if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) | 939 | if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) |
@@ -1005,6 +947,104 @@ static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh) | |||
1005 | if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) | 947 | if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) |
1006 | if (udf_CS0toUTF8(&outstr, &instr)) | 948 | if (udf_CS0toUTF8(&outstr, &instr)) |
1007 | udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); | 949 | udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); |
950 | |||
951 | brelse(bh); | ||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | static int udf_load_metadata_files(struct super_block *sb, int partition) | ||
956 | { | ||
957 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
958 | struct udf_part_map *map; | ||
959 | struct udf_meta_data *mdata; | ||
960 | kernel_lb_addr addr; | ||
961 | int fe_error = 0; | ||
962 | |||
963 | map = &sbi->s_partmaps[partition]; | ||
964 | mdata = &map->s_type_specific.s_metadata; | ||
965 | |||
966 | /* metadata address */ | ||
967 | addr.logicalBlockNum = mdata->s_meta_file_loc; | ||
968 | addr.partitionReferenceNum = map->s_partition_num; | ||
969 | |||
970 | udf_debug("Metadata file location: block = %d part = %d\n", | ||
971 | addr.logicalBlockNum, addr.partitionReferenceNum); | ||
972 | |||
973 | mdata->s_metadata_fe = udf_iget(sb, addr); | ||
974 | |||
975 | if (mdata->s_metadata_fe == NULL) { | ||
976 | udf_warning(sb, __func__, "metadata inode efe not found, " | ||
977 | "will try mirror inode."); | ||
978 | fe_error = 1; | ||
979 | } else if (UDF_I(mdata->s_metadata_fe)->i_alloc_type != | ||
980 | ICBTAG_FLAG_AD_SHORT) { | ||
981 | udf_warning(sb, __func__, "metadata inode efe does not have " | ||
982 | "short allocation descriptors!"); | ||
983 | fe_error = 1; | ||
984 | iput(mdata->s_metadata_fe); | ||
985 | mdata->s_metadata_fe = NULL; | ||
986 | } | ||
987 | |||
988 | /* mirror file entry */ | ||
989 | addr.logicalBlockNum = mdata->s_mirror_file_loc; | ||
990 | addr.partitionReferenceNum = map->s_partition_num; | ||
991 | |||
992 | udf_debug("Mirror metadata file location: block = %d part = %d\n", | ||
993 | addr.logicalBlockNum, addr.partitionReferenceNum); | ||
994 | |||
995 | mdata->s_mirror_fe = udf_iget(sb, addr); | ||
996 | |||
997 | if (mdata->s_mirror_fe == NULL) { | ||
998 | if (fe_error) { | ||
999 | udf_error(sb, __func__, "mirror inode efe not found " | ||
1000 | "and metadata inode is missing too, exiting..."); | ||
1001 | goto error_exit; | ||
1002 | } else | ||
1003 | udf_warning(sb, __func__, "mirror inode efe not found," | ||
1004 | " but metadata inode is OK"); | ||
1005 | } else if (UDF_I(mdata->s_mirror_fe)->i_alloc_type != | ||
1006 | ICBTAG_FLAG_AD_SHORT) { | ||
1007 | udf_warning(sb, __func__, "mirror inode efe does not have " | ||
1008 | "short allocation descriptors!"); | ||
1009 | iput(mdata->s_mirror_fe); | ||
1010 | mdata->s_mirror_fe = NULL; | ||
1011 | if (fe_error) | ||
1012 | goto error_exit; | ||
1013 | } | ||
1014 | |||
1015 | /* | ||
1016 | * bitmap file entry | ||
1017 | * Note: | ||
1018 | * Load only if bitmap file location differs from 0xFFFFFFFF (DCN-5102) | ||
1019 | */ | ||
1020 | if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) { | ||
1021 | addr.logicalBlockNum = mdata->s_bitmap_file_loc; | ||
1022 | addr.partitionReferenceNum = map->s_partition_num; | ||
1023 | |||
1024 | udf_debug("Bitmap file location: block = %d part = %d\n", | ||
1025 | addr.logicalBlockNum, addr.partitionReferenceNum); | ||
1026 | |||
1027 | mdata->s_bitmap_fe = udf_iget(sb, addr); | ||
1028 | |||
1029 | if (mdata->s_bitmap_fe == NULL) { | ||
1030 | if (sb->s_flags & MS_RDONLY) | ||
1031 | udf_warning(sb, __func__, "bitmap inode efe " | ||
1032 | "not found but it's ok since the disc" | ||
1033 | " is mounted read-only"); | ||
1034 | else { | ||
1035 | udf_error(sb, __func__, "bitmap inode efe not " | ||
1036 | "found and attempted read-write mount"); | ||
1037 | goto error_exit; | ||
1038 | } | ||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | udf_debug("udf_load_metadata_files Ok\n"); | ||
1043 | |||
1044 | return 0; | ||
1045 | |||
1046 | error_exit: | ||
1047 | return 1; | ||
1008 | } | 1048 | } |
1009 | 1049 | ||
1010 | static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, | 1050 | static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, |
@@ -1025,10 +1065,9 @@ static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, | |||
1025 | int udf_compute_nr_groups(struct super_block *sb, u32 partition) | 1065 | int udf_compute_nr_groups(struct super_block *sb, u32 partition) |
1026 | { | 1066 | { |
1027 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; | 1067 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
1028 | return (map->s_partition_len + | 1068 | return DIV_ROUND_UP(map->s_partition_len + |
1029 | (sizeof(struct spaceBitmapDesc) << 3) + | 1069 | (sizeof(struct spaceBitmapDesc) << 3), |
1030 | (sb->s_blocksize * 8) - 1) / | 1070 | sb->s_blocksize * 8); |
1031 | (sb->s_blocksize * 8); | ||
1032 | } | 1071 | } |
1033 | 1072 | ||
1034 | static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | 1073 | static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) |
@@ -1059,134 +1098,241 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
1059 | return bitmap; | 1098 | return bitmap; |
1060 | } | 1099 | } |
1061 | 1100 | ||
1062 | static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) | 1101 | static int udf_fill_partdesc_info(struct super_block *sb, |
1102 | struct partitionDesc *p, int p_index) | ||
1103 | { | ||
1104 | struct udf_part_map *map; | ||
1105 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1106 | struct partitionHeaderDesc *phd; | ||
1107 | |||
1108 | map = &sbi->s_partmaps[p_index]; | ||
1109 | |||
1110 | map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */ | ||
1111 | map->s_partition_root = le32_to_cpu(p->partitionStartingLocation); | ||
1112 | |||
1113 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY)) | ||
1114 | map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY; | ||
1115 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE)) | ||
1116 | map->s_partition_flags |= UDF_PART_FLAG_WRITE_ONCE; | ||
1117 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE)) | ||
1118 | map->s_partition_flags |= UDF_PART_FLAG_REWRITABLE; | ||
1119 | if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE)) | ||
1120 | map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE; | ||
1121 | |||
1122 | udf_debug("Partition (%d type %x) starts at physical %d, " | ||
1123 | "block length %d\n", p_index, | ||
1124 | map->s_partition_type, map->s_partition_root, | ||
1125 | map->s_partition_len); | ||
1126 | |||
1127 | if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) && | ||
1128 | strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) | ||
1129 | return 0; | ||
1130 | |||
1131 | phd = (struct partitionHeaderDesc *)p->partitionContentsUse; | ||
1132 | if (phd->unallocSpaceTable.extLength) { | ||
1133 | kernel_lb_addr loc = { | ||
1134 | .logicalBlockNum = le32_to_cpu( | ||
1135 | phd->unallocSpaceTable.extPosition), | ||
1136 | .partitionReferenceNum = p_index, | ||
1137 | }; | ||
1138 | |||
1139 | map->s_uspace.s_table = udf_iget(sb, loc); | ||
1140 | if (!map->s_uspace.s_table) { | ||
1141 | udf_debug("cannot load unallocSpaceTable (part %d)\n", | ||
1142 | p_index); | ||
1143 | return 1; | ||
1144 | } | ||
1145 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE; | ||
1146 | udf_debug("unallocSpaceTable (part %d) @ %ld\n", | ||
1147 | p_index, map->s_uspace.s_table->i_ino); | ||
1148 | } | ||
1149 | |||
1150 | if (phd->unallocSpaceBitmap.extLength) { | ||
1151 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); | ||
1152 | if (!bitmap) | ||
1153 | return 1; | ||
1154 | map->s_uspace.s_bitmap = bitmap; | ||
1155 | bitmap->s_extLength = le32_to_cpu( | ||
1156 | phd->unallocSpaceBitmap.extLength); | ||
1157 | bitmap->s_extPosition = le32_to_cpu( | ||
1158 | phd->unallocSpaceBitmap.extPosition); | ||
1159 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; | ||
1160 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", p_index, | ||
1161 | bitmap->s_extPosition); | ||
1162 | } | ||
1163 | |||
1164 | if (phd->partitionIntegrityTable.extLength) | ||
1165 | udf_debug("partitionIntegrityTable (part %d)\n", p_index); | ||
1166 | |||
1167 | if (phd->freedSpaceTable.extLength) { | ||
1168 | kernel_lb_addr loc = { | ||
1169 | .logicalBlockNum = le32_to_cpu( | ||
1170 | phd->freedSpaceTable.extPosition), | ||
1171 | .partitionReferenceNum = p_index, | ||
1172 | }; | ||
1173 | |||
1174 | map->s_fspace.s_table = udf_iget(sb, loc); | ||
1175 | if (!map->s_fspace.s_table) { | ||
1176 | udf_debug("cannot load freedSpaceTable (part %d)\n", | ||
1177 | p_index); | ||
1178 | return 1; | ||
1179 | } | ||
1180 | |||
1181 | map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE; | ||
1182 | udf_debug("freedSpaceTable (part %d) @ %ld\n", | ||
1183 | p_index, map->s_fspace.s_table->i_ino); | ||
1184 | } | ||
1185 | |||
1186 | if (phd->freedSpaceBitmap.extLength) { | ||
1187 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); | ||
1188 | if (!bitmap) | ||
1189 | return 1; | ||
1190 | map->s_fspace.s_bitmap = bitmap; | ||
1191 | bitmap->s_extLength = le32_to_cpu( | ||
1192 | phd->freedSpaceBitmap.extLength); | ||
1193 | bitmap->s_extPosition = le32_to_cpu( | ||
1194 | phd->freedSpaceBitmap.extPosition); | ||
1195 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; | ||
1196 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", p_index, | ||
1197 | bitmap->s_extPosition); | ||
1198 | } | ||
1199 | return 0; | ||
1200 | } | ||
1201 | |||
1202 | static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) | ||
1203 | { | ||
1204 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1205 | struct udf_part_map *map = &sbi->s_partmaps[p_index]; | ||
1206 | kernel_lb_addr ino; | ||
1207 | struct buffer_head *bh = NULL; | ||
1208 | struct udf_inode_info *vati; | ||
1209 | uint32_t pos; | ||
1210 | struct virtualAllocationTable20 *vat20; | ||
1211 | |||
1212 | /* VAT file entry is in the last recorded block */ | ||
1213 | ino.partitionReferenceNum = type1_index; | ||
1214 | ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root; | ||
1215 | sbi->s_vat_inode = udf_iget(sb, ino); | ||
1216 | if (!sbi->s_vat_inode) | ||
1217 | return 1; | ||
1218 | |||
1219 | if (map->s_partition_type == UDF_VIRTUAL_MAP15) { | ||
1220 | map->s_type_specific.s_virtual.s_start_offset = 0; | ||
1221 | map->s_type_specific.s_virtual.s_num_entries = | ||
1222 | (sbi->s_vat_inode->i_size - 36) >> 2; | ||
1223 | } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) { | ||
1224 | vati = UDF_I(sbi->s_vat_inode); | ||
1225 | if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||
1226 | pos = udf_block_map(sbi->s_vat_inode, 0); | ||
1227 | bh = sb_bread(sb, pos); | ||
1228 | if (!bh) | ||
1229 | return 1; | ||
1230 | vat20 = (struct virtualAllocationTable20 *)bh->b_data; | ||
1231 | } else { | ||
1232 | vat20 = (struct virtualAllocationTable20 *) | ||
1233 | vati->i_ext.i_data; | ||
1234 | } | ||
1235 | |||
1236 | map->s_type_specific.s_virtual.s_start_offset = | ||
1237 | le16_to_cpu(vat20->lengthHeader); | ||
1238 | map->s_type_specific.s_virtual.s_num_entries = | ||
1239 | (sbi->s_vat_inode->i_size - | ||
1240 | map->s_type_specific.s_virtual. | ||
1241 | s_start_offset) >> 2; | ||
1242 | brelse(bh); | ||
1243 | } | ||
1244 | return 0; | ||
1245 | } | ||
1246 | |||
1247 | static int udf_load_partdesc(struct super_block *sb, sector_t block) | ||
1063 | { | 1248 | { |
1249 | struct buffer_head *bh; | ||
1064 | struct partitionDesc *p; | 1250 | struct partitionDesc *p; |
1065 | int i; | ||
1066 | struct udf_part_map *map; | 1251 | struct udf_part_map *map; |
1067 | struct udf_sb_info *sbi; | 1252 | struct udf_sb_info *sbi = UDF_SB(sb); |
1253 | int i, type1_idx; | ||
1254 | uint16_t partitionNumber; | ||
1255 | uint16_t ident; | ||
1256 | int ret = 0; | ||
1257 | |||
1258 | bh = udf_read_tagged(sb, block, block, &ident); | ||
1259 | if (!bh) | ||
1260 | return 1; | ||
1261 | if (ident != TAG_IDENT_PD) | ||
1262 | goto out_bh; | ||
1068 | 1263 | ||
1069 | p = (struct partitionDesc *)bh->b_data; | 1264 | p = (struct partitionDesc *)bh->b_data; |
1070 | sbi = UDF_SB(sb); | 1265 | partitionNumber = le16_to_cpu(p->partitionNumber); |
1071 | 1266 | ||
1267 | /* First scan for TYPE1, SPARABLE and METADATA partitions */ | ||
1072 | for (i = 0; i < sbi->s_partitions; i++) { | 1268 | for (i = 0; i < sbi->s_partitions; i++) { |
1073 | map = &sbi->s_partmaps[i]; | 1269 | map = &sbi->s_partmaps[i]; |
1074 | udf_debug("Searching map: (%d == %d)\n", | 1270 | udf_debug("Searching map: (%d == %d)\n", |
1075 | map->s_partition_num, | 1271 | map->s_partition_num, partitionNumber); |
1076 | le16_to_cpu(p->partitionNumber)); | 1272 | if (map->s_partition_num == partitionNumber && |
1077 | if (map->s_partition_num == | 1273 | (map->s_partition_type == UDF_TYPE1_MAP15 || |
1078 | le16_to_cpu(p->partitionNumber)) { | 1274 | map->s_partition_type == UDF_SPARABLE_MAP15)) |
1079 | map->s_partition_len = | ||
1080 | le32_to_cpu(p->partitionLength); /* blocks */ | ||
1081 | map->s_partition_root = | ||
1082 | le32_to_cpu(p->partitionStartingLocation); | ||
1083 | if (p->accessType == | ||
1084 | cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY)) | ||
1085 | map->s_partition_flags |= | ||
1086 | UDF_PART_FLAG_READ_ONLY; | ||
1087 | if (p->accessType == | ||
1088 | cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE)) | ||
1089 | map->s_partition_flags |= | ||
1090 | UDF_PART_FLAG_WRITE_ONCE; | ||
1091 | if (p->accessType == | ||
1092 | cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE)) | ||
1093 | map->s_partition_flags |= | ||
1094 | UDF_PART_FLAG_REWRITABLE; | ||
1095 | if (p->accessType == | ||
1096 | cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE)) | ||
1097 | map->s_partition_flags |= | ||
1098 | UDF_PART_FLAG_OVERWRITABLE; | ||
1099 | |||
1100 | if (!strcmp(p->partitionContents.ident, | ||
1101 | PD_PARTITION_CONTENTS_NSR02) || | ||
1102 | !strcmp(p->partitionContents.ident, | ||
1103 | PD_PARTITION_CONTENTS_NSR03)) { | ||
1104 | struct partitionHeaderDesc *phd; | ||
1105 | |||
1106 | phd = (struct partitionHeaderDesc *) | ||
1107 | (p->partitionContentsUse); | ||
1108 | if (phd->unallocSpaceTable.extLength) { | ||
1109 | kernel_lb_addr loc = { | ||
1110 | .logicalBlockNum = le32_to_cpu(phd->unallocSpaceTable.extPosition), | ||
1111 | .partitionReferenceNum = i, | ||
1112 | }; | ||
1113 | |||
1114 | map->s_uspace.s_table = | ||
1115 | udf_iget(sb, loc); | ||
1116 | if (!map->s_uspace.s_table) { | ||
1117 | udf_debug("cannot load unallocSpaceTable (part %d)\n", i); | ||
1118 | return 1; | ||
1119 | } | ||
1120 | map->s_partition_flags |= | ||
1121 | UDF_PART_FLAG_UNALLOC_TABLE; | ||
1122 | udf_debug("unallocSpaceTable (part %d) @ %ld\n", | ||
1123 | i, map->s_uspace.s_table->i_ino); | ||
1124 | } | ||
1125 | if (phd->unallocSpaceBitmap.extLength) { | ||
1126 | struct udf_bitmap *bitmap = | ||
1127 | udf_sb_alloc_bitmap(sb, i); | ||
1128 | map->s_uspace.s_bitmap = bitmap; | ||
1129 | if (bitmap != NULL) { | ||
1130 | bitmap->s_extLength = | ||
1131 | le32_to_cpu(phd->unallocSpaceBitmap.extLength); | ||
1132 | bitmap->s_extPosition = | ||
1133 | le32_to_cpu(phd->unallocSpaceBitmap.extPosition); | ||
1134 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; | ||
1135 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", | ||
1136 | i, bitmap->s_extPosition); | ||
1137 | } | ||
1138 | } | ||
1139 | if (phd->partitionIntegrityTable.extLength) | ||
1140 | udf_debug("partitionIntegrityTable (part %d)\n", i); | ||
1141 | if (phd->freedSpaceTable.extLength) { | ||
1142 | kernel_lb_addr loc = { | ||
1143 | .logicalBlockNum = le32_to_cpu(phd->freedSpaceTable.extPosition), | ||
1144 | .partitionReferenceNum = i, | ||
1145 | }; | ||
1146 | |||
1147 | map->s_fspace.s_table = | ||
1148 | udf_iget(sb, loc); | ||
1149 | if (!map->s_fspace.s_table) { | ||
1150 | udf_debug("cannot load freedSpaceTable (part %d)\n", i); | ||
1151 | return 1; | ||
1152 | } | ||
1153 | map->s_partition_flags |= | ||
1154 | UDF_PART_FLAG_FREED_TABLE; | ||
1155 | udf_debug("freedSpaceTable (part %d) @ %ld\n", | ||
1156 | i, map->s_fspace.s_table->i_ino); | ||
1157 | } | ||
1158 | if (phd->freedSpaceBitmap.extLength) { | ||
1159 | struct udf_bitmap *bitmap = | ||
1160 | udf_sb_alloc_bitmap(sb, i); | ||
1161 | map->s_fspace.s_bitmap = bitmap; | ||
1162 | if (bitmap != NULL) { | ||
1163 | bitmap->s_extLength = | ||
1164 | le32_to_cpu(phd->freedSpaceBitmap.extLength); | ||
1165 | bitmap->s_extPosition = | ||
1166 | le32_to_cpu(phd->freedSpaceBitmap.extPosition); | ||
1167 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; | ||
1168 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", | ||
1169 | i, bitmap->s_extPosition); | ||
1170 | } | ||
1171 | } | ||
1172 | } | ||
1173 | break; | 1275 | break; |
1174 | } | ||
1175 | } | 1276 | } |
1176 | if (i == sbi->s_partitions) | 1277 | |
1278 | if (i >= sbi->s_partitions) { | ||
1177 | udf_debug("Partition (%d) not found in partition map\n", | 1279 | udf_debug("Partition (%d) not found in partition map\n", |
1178 | le16_to_cpu(p->partitionNumber)); | 1280 | partitionNumber); |
1179 | else | 1281 | goto out_bh; |
1180 | udf_debug("Partition (%d:%d type %x) starts at physical %d, " | 1282 | } |
1181 | "block length %d\n", | 1283 | |
1182 | le16_to_cpu(p->partitionNumber), i, | 1284 | ret = udf_fill_partdesc_info(sb, p, i); |
1183 | map->s_partition_type, | 1285 | |
1184 | map->s_partition_root, | 1286 | /* |
1185 | map->s_partition_len); | 1287 | * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and |
1186 | return 0; | 1288 | * PHYSICAL partitions are already set up |
1289 | */ | ||
1290 | type1_idx = i; | ||
1291 | for (i = 0; i < sbi->s_partitions; i++) { | ||
1292 | map = &sbi->s_partmaps[i]; | ||
1293 | |||
1294 | if (map->s_partition_num == partitionNumber && | ||
1295 | (map->s_partition_type == UDF_VIRTUAL_MAP15 || | ||
1296 | map->s_partition_type == UDF_VIRTUAL_MAP20 || | ||
1297 | map->s_partition_type == UDF_METADATA_MAP25)) | ||
1298 | break; | ||
1299 | } | ||
1300 | |||
1301 | if (i >= sbi->s_partitions) | ||
1302 | goto out_bh; | ||
1303 | |||
1304 | ret = udf_fill_partdesc_info(sb, p, i); | ||
1305 | if (ret) | ||
1306 | goto out_bh; | ||
1307 | |||
1308 | if (map->s_partition_type == UDF_METADATA_MAP25) { | ||
1309 | ret = udf_load_metadata_files(sb, i); | ||
1310 | if (ret) { | ||
1311 | printk(KERN_ERR "UDF-fs: error loading MetaData " | ||
1312 | "partition map %d\n", i); | ||
1313 | goto out_bh; | ||
1314 | } | ||
1315 | } else { | ||
1316 | ret = udf_load_vat(sb, i, type1_idx); | ||
1317 | if (ret) | ||
1318 | goto out_bh; | ||
1319 | /* | ||
1320 | * Mark filesystem read-only if we have a partition with | ||
1321 | * virtual map since we don't handle writing to it (we | ||
1322 | * overwrite blocks instead of relocating them). | ||
1323 | */ | ||
1324 | sb->s_flags |= MS_RDONLY; | ||
1325 | printk(KERN_NOTICE "UDF-fs: Filesystem marked read-only " | ||
1326 | "because writing to pseudooverwrite partition is " | ||
1327 | "not implemented.\n"); | ||
1328 | } | ||
1329 | out_bh: | ||
1330 | /* In case loading failed, we handle cleanup in udf_fill_super */ | ||
1331 | brelse(bh); | ||
1332 | return ret; | ||
1187 | } | 1333 | } |
1188 | 1334 | ||
1189 | static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | 1335 | static int udf_load_logicalvol(struct super_block *sb, sector_t block, |
1190 | kernel_lb_addr *fileset) | 1336 | kernel_lb_addr *fileset) |
1191 | { | 1337 | { |
1192 | struct logicalVolDesc *lvd; | 1338 | struct logicalVolDesc *lvd; |
@@ -1194,12 +1340,21 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
1194 | uint8_t type; | 1340 | uint8_t type; |
1195 | struct udf_sb_info *sbi = UDF_SB(sb); | 1341 | struct udf_sb_info *sbi = UDF_SB(sb); |
1196 | struct genericPartitionMap *gpm; | 1342 | struct genericPartitionMap *gpm; |
1343 | uint16_t ident; | ||
1344 | struct buffer_head *bh; | ||
1345 | int ret = 0; | ||
1197 | 1346 | ||
1347 | bh = udf_read_tagged(sb, block, block, &ident); | ||
1348 | if (!bh) | ||
1349 | return 1; | ||
1350 | BUG_ON(ident != TAG_IDENT_LVD); | ||
1198 | lvd = (struct logicalVolDesc *)bh->b_data; | 1351 | lvd = (struct logicalVolDesc *)bh->b_data; |
1199 | 1352 | ||
1200 | i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); | 1353 | i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); |
1201 | if (i != 0) | 1354 | if (i != 0) { |
1202 | return i; | 1355 | ret = i; |
1356 | goto out_bh; | ||
1357 | } | ||
1203 | 1358 | ||
1204 | for (i = 0, offset = 0; | 1359 | for (i = 0, offset = 0; |
1205 | i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); | 1360 | i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); |
@@ -1223,12 +1378,12 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
1223 | u16 suf = | 1378 | u16 suf = |
1224 | le16_to_cpu(((__le16 *)upm2->partIdent. | 1379 | le16_to_cpu(((__le16 *)upm2->partIdent. |
1225 | identSuffix)[0]); | 1380 | identSuffix)[0]); |
1226 | if (suf == 0x0150) { | 1381 | if (suf < 0x0200) { |
1227 | map->s_partition_type = | 1382 | map->s_partition_type = |
1228 | UDF_VIRTUAL_MAP15; | 1383 | UDF_VIRTUAL_MAP15; |
1229 | map->s_partition_func = | 1384 | map->s_partition_func = |
1230 | udf_get_pblock_virt15; | 1385 | udf_get_pblock_virt15; |
1231 | } else if (suf == 0x0200) { | 1386 | } else { |
1232 | map->s_partition_type = | 1387 | map->s_partition_type = |
1233 | UDF_VIRTUAL_MAP20; | 1388 | UDF_VIRTUAL_MAP20; |
1234 | map->s_partition_func = | 1389 | map->s_partition_func = |
@@ -1238,7 +1393,6 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
1238 | UDF_ID_SPARABLE, | 1393 | UDF_ID_SPARABLE, |
1239 | strlen(UDF_ID_SPARABLE))) { | 1394 | strlen(UDF_ID_SPARABLE))) { |
1240 | uint32_t loc; | 1395 | uint32_t loc; |
1241 | uint16_t ident; | ||
1242 | struct sparingTable *st; | 1396 | struct sparingTable *st; |
1243 | struct sparablePartitionMap *spm = | 1397 | struct sparablePartitionMap *spm = |
1244 | (struct sparablePartitionMap *)gpm; | 1398 | (struct sparablePartitionMap *)gpm; |
@@ -1256,22 +1410,64 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
1256 | map->s_type_specific.s_sparing. | 1410 | map->s_type_specific.s_sparing. |
1257 | s_spar_map[j] = bh2; | 1411 | s_spar_map[j] = bh2; |
1258 | 1412 | ||
1259 | if (bh2 != NULL) { | 1413 | if (bh2 == NULL) |
1260 | st = (struct sparingTable *) | 1414 | continue; |
1261 | bh2->b_data; | 1415 | |
1262 | if (ident != 0 || strncmp( | 1416 | st = (struct sparingTable *)bh2->b_data; |
1263 | st->sparingIdent.ident, | 1417 | if (ident != 0 || strncmp( |
1264 | UDF_ID_SPARING, | 1418 | st->sparingIdent.ident, |
1265 | strlen(UDF_ID_SPARING))) { | 1419 | UDF_ID_SPARING, |
1266 | brelse(bh2); | 1420 | strlen(UDF_ID_SPARING))) { |
1267 | map->s_type_specific. | 1421 | brelse(bh2); |
1268 | s_sparing. | 1422 | map->s_type_specific.s_sparing. |
1269 | s_spar_map[j] = | 1423 | s_spar_map[j] = NULL; |
1270 | NULL; | ||
1271 | } | ||
1272 | } | 1424 | } |
1273 | } | 1425 | } |
1274 | map->s_partition_func = udf_get_pblock_spar15; | 1426 | map->s_partition_func = udf_get_pblock_spar15; |
1427 | } else if (!strncmp(upm2->partIdent.ident, | ||
1428 | UDF_ID_METADATA, | ||
1429 | strlen(UDF_ID_METADATA))) { | ||
1430 | struct udf_meta_data *mdata = | ||
1431 | &map->s_type_specific.s_metadata; | ||
1432 | struct metadataPartitionMap *mdm = | ||
1433 | (struct metadataPartitionMap *) | ||
1434 | &(lvd->partitionMaps[offset]); | ||
1435 | udf_debug("Parsing Logical vol part %d " | ||
1436 | "type %d id=%s\n", i, type, | ||
1437 | UDF_ID_METADATA); | ||
1438 | |||
1439 | map->s_partition_type = UDF_METADATA_MAP25; | ||
1440 | map->s_partition_func = udf_get_pblock_meta25; | ||
1441 | |||
1442 | mdata->s_meta_file_loc = | ||
1443 | le32_to_cpu(mdm->metadataFileLoc); | ||
1444 | mdata->s_mirror_file_loc = | ||
1445 | le32_to_cpu(mdm->metadataMirrorFileLoc); | ||
1446 | mdata->s_bitmap_file_loc = | ||
1447 | le32_to_cpu(mdm->metadataBitmapFileLoc); | ||
1448 | mdata->s_alloc_unit_size = | ||
1449 | le32_to_cpu(mdm->allocUnitSize); | ||
1450 | mdata->s_align_unit_size = | ||
1451 | le16_to_cpu(mdm->alignUnitSize); | ||
1452 | mdata->s_dup_md_flag = | ||
1453 | mdm->flags & 0x01; | ||
1454 | |||
1455 | udf_debug("Metadata Ident suffix=0x%x\n", | ||
1456 | (le16_to_cpu( | ||
1457 | ((__le16 *) | ||
1458 | mdm->partIdent.identSuffix)[0]))); | ||
1459 | udf_debug("Metadata part num=%d\n", | ||
1460 | le16_to_cpu(mdm->partitionNum)); | ||
1461 | udf_debug("Metadata part alloc unit size=%d\n", | ||
1462 | le32_to_cpu(mdm->allocUnitSize)); | ||
1463 | udf_debug("Metadata file loc=%d\n", | ||
1464 | le32_to_cpu(mdm->metadataFileLoc)); | ||
1465 | udf_debug("Mirror file loc=%d\n", | ||
1466 | le32_to_cpu(mdm->metadataMirrorFileLoc)); | ||
1467 | udf_debug("Bitmap file loc=%d\n", | ||
1468 | le32_to_cpu(mdm->metadataBitmapFileLoc)); | ||
1469 | udf_debug("Duplicate Flag: %d %d\n", | ||
1470 | mdata->s_dup_md_flag, mdm->flags); | ||
1275 | } else { | 1471 | } else { |
1276 | udf_debug("Unknown ident: %s\n", | 1472 | udf_debug("Unknown ident: %s\n", |
1277 | upm2->partIdent.ident); | 1473 | upm2->partIdent.ident); |
@@ -1296,7 +1492,9 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, | |||
1296 | if (lvd->integritySeqExt.extLength) | 1492 | if (lvd->integritySeqExt.extLength) |
1297 | udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); | 1493 | udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); |
1298 | 1494 | ||
1299 | return 0; | 1495 | out_bh: |
1496 | brelse(bh); | ||
1497 | return ret; | ||
1300 | } | 1498 | } |
1301 | 1499 | ||
1302 | /* | 1500 | /* |
@@ -1345,7 +1543,7 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc) | |||
1345 | * July 1, 1997 - Andrew E. Mileski | 1543 | * July 1, 1997 - Andrew E. Mileski |
1346 | * Written, tested, and released. | 1544 | * Written, tested, and released. |
1347 | */ | 1545 | */ |
1348 | static int udf_process_sequence(struct super_block *sb, long block, | 1546 | static noinline int udf_process_sequence(struct super_block *sb, long block, |
1349 | long lastblock, kernel_lb_addr *fileset) | 1547 | long lastblock, kernel_lb_addr *fileset) |
1350 | { | 1548 | { |
1351 | struct buffer_head *bh = NULL; | 1549 | struct buffer_head *bh = NULL; |
@@ -1354,19 +1552,25 @@ static int udf_process_sequence(struct super_block *sb, long block, | |||
1354 | struct generic_desc *gd; | 1552 | struct generic_desc *gd; |
1355 | struct volDescPtr *vdp; | 1553 | struct volDescPtr *vdp; |
1356 | int done = 0; | 1554 | int done = 0; |
1357 | int i, j; | ||
1358 | uint32_t vdsn; | 1555 | uint32_t vdsn; |
1359 | uint16_t ident; | 1556 | uint16_t ident; |
1360 | long next_s = 0, next_e = 0; | 1557 | long next_s = 0, next_e = 0; |
1361 | 1558 | ||
1362 | memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); | 1559 | memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); |
1363 | 1560 | ||
1364 | /* Read the main descriptor sequence */ | 1561 | /* |
1562 | * Read the main descriptor sequence and find which descriptors | ||
1563 | * are in it. | ||
1564 | */ | ||
1365 | for (; (!done && block <= lastblock); block++) { | 1565 | for (; (!done && block <= lastblock); block++) { |
1366 | 1566 | ||
1367 | bh = udf_read_tagged(sb, block, block, &ident); | 1567 | bh = udf_read_tagged(sb, block, block, &ident); |
1368 | if (!bh) | 1568 | if (!bh) { |
1369 | break; | 1569 | printk(KERN_ERR "udf: Block %Lu of volume descriptor " |
1570 | "sequence is corrupted or we could not read " | ||
1571 | "it.\n", (unsigned long long)block); | ||
1572 | return 1; | ||
1573 | } | ||
1370 | 1574 | ||
1371 | /* Process each descriptor (ISO 13346 3/8.3-8.4) */ | 1575 | /* Process each descriptor (ISO 13346 3/8.3-8.4) */ |
1372 | gd = (struct generic_desc *)bh->b_data; | 1576 | gd = (struct generic_desc *)bh->b_data; |
@@ -1432,41 +1636,31 @@ static int udf_process_sequence(struct super_block *sb, long block, | |||
1432 | } | 1636 | } |
1433 | brelse(bh); | 1637 | brelse(bh); |
1434 | } | 1638 | } |
1435 | for (i = 0; i < VDS_POS_LENGTH; i++) { | 1639 | /* |
1436 | if (vds[i].block) { | 1640 | * Now read interesting descriptors again and process them |
1437 | bh = udf_read_tagged(sb, vds[i].block, vds[i].block, | 1641 | * in a suitable order |
1438 | &ident); | 1642 | */ |
1439 | 1643 | if (!vds[VDS_POS_PRIMARY_VOL_DESC].block) { | |
1440 | if (i == VDS_POS_PRIMARY_VOL_DESC) { | 1644 | printk(KERN_ERR "udf: Primary Volume Descriptor not found!\n"); |
1441 | udf_load_pvoldesc(sb, bh); | 1645 | return 1; |
1442 | } else if (i == VDS_POS_LOGICAL_VOL_DESC) { | 1646 | } |
1443 | if (udf_load_logicalvol(sb, bh, fileset)) { | 1647 | if (udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block)) |
1444 | brelse(bh); | 1648 | return 1; |
1445 | return 1; | 1649 | |
1446 | } | 1650 | if (vds[VDS_POS_LOGICAL_VOL_DESC].block && udf_load_logicalvol(sb, |
1447 | } else if (i == VDS_POS_PARTITION_DESC) { | 1651 | vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset)) |
1448 | struct buffer_head *bh2 = NULL; | 1652 | return 1; |
1449 | if (udf_load_partdesc(sb, bh)) { | 1653 | |
1450 | brelse(bh); | 1654 | if (vds[VDS_POS_PARTITION_DESC].block) { |
1451 | return 1; | 1655 | /* |
1452 | } | 1656 | * We rescan the whole descriptor sequence to find |
1453 | for (j = vds[i].block + 1; | 1657 | * partition descriptor blocks and process them. |
1454 | j < vds[VDS_POS_TERMINATING_DESC].block; | 1658 | */ |
1455 | j++) { | 1659 | for (block = vds[VDS_POS_PARTITION_DESC].block; |
1456 | bh2 = udf_read_tagged(sb, j, j, &ident); | 1660 | block < vds[VDS_POS_TERMINATING_DESC].block; |
1457 | gd = (struct generic_desc *)bh2->b_data; | 1661 | block++) |
1458 | if (ident == TAG_IDENT_PD) | 1662 | if (udf_load_partdesc(sb, block)) |
1459 | if (udf_load_partdesc(sb, | 1663 | return 1; |
1460 | bh2)) { | ||
1461 | brelse(bh); | ||
1462 | brelse(bh2); | ||
1463 | return 1; | ||
1464 | } | ||
1465 | brelse(bh2); | ||
1466 | } | ||
1467 | } | ||
1468 | brelse(bh); | ||
1469 | } | ||
1470 | } | 1664 | } |
1471 | 1665 | ||
1472 | return 0; | 1666 | return 0; |
@@ -1478,6 +1672,7 @@ static int udf_process_sequence(struct super_block *sb, long block, | |||
1478 | static int udf_check_valid(struct super_block *sb, int novrs, int silent) | 1672 | static int udf_check_valid(struct super_block *sb, int novrs, int silent) |
1479 | { | 1673 | { |
1480 | long block; | 1674 | long block; |
1675 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1481 | 1676 | ||
1482 | if (novrs) { | 1677 | if (novrs) { |
1483 | udf_debug("Validity check skipped because of novrs option\n"); | 1678 | udf_debug("Validity check skipped because of novrs option\n"); |
@@ -1485,27 +1680,22 @@ static int udf_check_valid(struct super_block *sb, int novrs, int silent) | |||
1485 | } | 1680 | } |
1486 | /* Check that it is NSR02 compliant */ | 1681 | /* Check that it is NSR02 compliant */ |
1487 | /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ | 1682 | /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ |
1488 | else { | 1683 | block = udf_vrs(sb, silent); |
1489 | block = udf_vrs(sb, silent); | 1684 | if (block == -1) |
1490 | if (block == -1) { | 1685 | udf_debug("Failed to read byte 32768. Assuming open " |
1491 | struct udf_sb_info *sbi = UDF_SB(sb); | 1686 | "disc. Skipping validity check\n"); |
1492 | udf_debug("Failed to read byte 32768. Assuming open " | 1687 | if (block && !sbi->s_last_block) |
1493 | "disc. Skipping validity check\n"); | 1688 | sbi->s_last_block = udf_get_last_block(sb); |
1494 | if (!sbi->s_last_block) | 1689 | return !block; |
1495 | sbi->s_last_block = udf_get_last_block(sb); | ||
1496 | return 0; | ||
1497 | } else | ||
1498 | return !block; | ||
1499 | } | ||
1500 | } | 1690 | } |
1501 | 1691 | ||
1502 | static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | 1692 | static int udf_load_sequence(struct super_block *sb, kernel_lb_addr *fileset) |
1503 | { | 1693 | { |
1504 | struct anchorVolDescPtr *anchor; | 1694 | struct anchorVolDescPtr *anchor; |
1505 | uint16_t ident; | 1695 | uint16_t ident; |
1506 | struct buffer_head *bh; | 1696 | struct buffer_head *bh; |
1507 | long main_s, main_e, reserve_s, reserve_e; | 1697 | long main_s, main_e, reserve_s, reserve_e; |
1508 | int i, j; | 1698 | int i; |
1509 | struct udf_sb_info *sbi; | 1699 | struct udf_sb_info *sbi; |
1510 | 1700 | ||
1511 | if (!sb) | 1701 | if (!sb) |
@@ -1515,6 +1705,7 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
1515 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { | 1705 | for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { |
1516 | if (!sbi->s_anchor[i]) | 1706 | if (!sbi->s_anchor[i]) |
1517 | continue; | 1707 | continue; |
1708 | |||
1518 | bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i], | 1709 | bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i], |
1519 | &ident); | 1710 | &ident); |
1520 | if (!bh) | 1711 | if (!bh) |
@@ -1553,76 +1744,6 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) | |||
1553 | } | 1744 | } |
1554 | udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]); | 1745 | udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]); |
1555 | 1746 | ||
1556 | for (i = 0; i < sbi->s_partitions; i++) { | ||
1557 | kernel_lb_addr uninitialized_var(ino); | ||
1558 | struct udf_part_map *map = &sbi->s_partmaps[i]; | ||
1559 | switch (map->s_partition_type) { | ||
1560 | case UDF_VIRTUAL_MAP15: | ||
1561 | case UDF_VIRTUAL_MAP20: | ||
1562 | if (!sbi->s_last_block) { | ||
1563 | sbi->s_last_block = udf_get_last_block(sb); | ||
1564 | udf_find_anchor(sb); | ||
1565 | } | ||
1566 | |||
1567 | if (!sbi->s_last_block) { | ||
1568 | udf_debug("Unable to determine Lastblock (For " | ||
1569 | "Virtual Partition)\n"); | ||
1570 | return 1; | ||
1571 | } | ||
1572 | |||
1573 | for (j = 0; j < sbi->s_partitions; j++) { | ||
1574 | struct udf_part_map *map2 = &sbi->s_partmaps[j]; | ||
1575 | if (j != i && | ||
1576 | map->s_volumeseqnum == | ||
1577 | map2->s_volumeseqnum && | ||
1578 | map->s_partition_num == | ||
1579 | map2->s_partition_num) { | ||
1580 | ino.partitionReferenceNum = j; | ||
1581 | ino.logicalBlockNum = | ||
1582 | sbi->s_last_block - | ||
1583 | map2->s_partition_root; | ||
1584 | break; | ||
1585 | } | ||
1586 | } | ||
1587 | |||
1588 | if (j == sbi->s_partitions) | ||
1589 | return 1; | ||
1590 | |||
1591 | sbi->s_vat_inode = udf_iget(sb, ino); | ||
1592 | if (!sbi->s_vat_inode) | ||
1593 | return 1; | ||
1594 | |||
1595 | if (map->s_partition_type == UDF_VIRTUAL_MAP15) { | ||
1596 | map->s_type_specific.s_virtual.s_start_offset = | ||
1597 | udf_ext0_offset(sbi->s_vat_inode); | ||
1598 | map->s_type_specific.s_virtual.s_num_entries = | ||
1599 | (sbi->s_vat_inode->i_size - 36) >> 2; | ||
1600 | } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) { | ||
1601 | uint32_t pos; | ||
1602 | struct virtualAllocationTable20 *vat20; | ||
1603 | |||
1604 | pos = udf_block_map(sbi->s_vat_inode, 0); | ||
1605 | bh = sb_bread(sb, pos); | ||
1606 | if (!bh) | ||
1607 | return 1; | ||
1608 | vat20 = (struct virtualAllocationTable20 *) | ||
1609 | bh->b_data + | ||
1610 | udf_ext0_offset(sbi->s_vat_inode); | ||
1611 | map->s_type_specific.s_virtual.s_start_offset = | ||
1612 | le16_to_cpu(vat20->lengthHeader) + | ||
1613 | udf_ext0_offset(sbi->s_vat_inode); | ||
1614 | map->s_type_specific.s_virtual.s_num_entries = | ||
1615 | (sbi->s_vat_inode->i_size - | ||
1616 | map->s_type_specific.s_virtual. | ||
1617 | s_start_offset) >> 2; | ||
1618 | brelse(bh); | ||
1619 | } | ||
1620 | map->s_partition_root = udf_get_pblock(sb, 0, i, 0); | ||
1621 | map->s_partition_len = | ||
1622 | sbi->s_partmaps[ino.partitionReferenceNum]. | ||
1623 | s_partition_len; | ||
1624 | } | ||
1625 | } | ||
1626 | return 0; | 1747 | return 0; |
1627 | } | 1748 | } |
1628 | 1749 | ||
@@ -1630,65 +1751,61 @@ static void udf_open_lvid(struct super_block *sb) | |||
1630 | { | 1751 | { |
1631 | struct udf_sb_info *sbi = UDF_SB(sb); | 1752 | struct udf_sb_info *sbi = UDF_SB(sb); |
1632 | struct buffer_head *bh = sbi->s_lvid_bh; | 1753 | struct buffer_head *bh = sbi->s_lvid_bh; |
1633 | if (bh) { | 1754 | struct logicalVolIntegrityDesc *lvid; |
1634 | kernel_timestamp cpu_time; | 1755 | struct logicalVolIntegrityDescImpUse *lvidiu; |
1635 | struct logicalVolIntegrityDesc *lvid = | 1756 | if (!bh) |
1636 | (struct logicalVolIntegrityDesc *)bh->b_data; | 1757 | return; |
1637 | struct logicalVolIntegrityDescImpUse *lvidiu = | ||
1638 | udf_sb_lvidiu(sbi); | ||
1639 | 1758 | ||
1640 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1759 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1641 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1760 | lvidiu = udf_sb_lvidiu(sbi); |
1642 | if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) | ||
1643 | lvid->recordingDateAndTime = cpu_to_lets(cpu_time); | ||
1644 | lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; | ||
1645 | 1761 | ||
1646 | lvid->descTag.descCRC = cpu_to_le16( | 1762 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1647 | udf_crc((char *)lvid + sizeof(tag), | 1763 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1648 | le16_to_cpu(lvid->descTag.descCRCLength), | 1764 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, |
1649 | 0)); | 1765 | CURRENT_TIME); |
1766 | lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; | ||
1650 | 1767 | ||
1651 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1768 | lvid->descTag.descCRC = cpu_to_le16( |
1652 | mark_buffer_dirty(bh); | 1769 | crc_itu_t(0, (char *)lvid + sizeof(tag), |
1653 | } | 1770 | le16_to_cpu(lvid->descTag.descCRCLength))); |
1771 | |||
1772 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | ||
1773 | mark_buffer_dirty(bh); | ||
1654 | } | 1774 | } |
1655 | 1775 | ||
1656 | static void udf_close_lvid(struct super_block *sb) | 1776 | static void udf_close_lvid(struct super_block *sb) |
1657 | { | 1777 | { |
1658 | kernel_timestamp cpu_time; | ||
1659 | struct udf_sb_info *sbi = UDF_SB(sb); | 1778 | struct udf_sb_info *sbi = UDF_SB(sb); |
1660 | struct buffer_head *bh = sbi->s_lvid_bh; | 1779 | struct buffer_head *bh = sbi->s_lvid_bh; |
1661 | struct logicalVolIntegrityDesc *lvid; | 1780 | struct logicalVolIntegrityDesc *lvid; |
1781 | struct logicalVolIntegrityDescImpUse *lvidiu; | ||
1662 | 1782 | ||
1663 | if (!bh) | 1783 | if (!bh) |
1664 | return; | 1784 | return; |
1665 | 1785 | ||
1666 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1786 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1667 | 1787 | ||
1668 | if (lvid->integrityType == LVID_INTEGRITY_TYPE_OPEN) { | 1788 | if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN) |
1669 | struct logicalVolIntegrityDescImpUse *lvidiu = | 1789 | return; |
1670 | udf_sb_lvidiu(sbi); | 1790 | |
1671 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1791 | lvidiu = udf_sb_lvidiu(sbi); |
1672 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1792 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1673 | if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) | 1793 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1674 | lvid->recordingDateAndTime = cpu_to_lets(cpu_time); | 1794 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); |
1675 | if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) | 1795 | if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) |
1676 | lvidiu->maxUDFWriteRev = | 1796 | lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION); |
1677 | cpu_to_le16(UDF_MAX_WRITE_VERSION); | 1797 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) |
1678 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) | 1798 | lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev); |
1679 | lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev); | 1799 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev)) |
1680 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev)) | 1800 | lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev); |
1681 | lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev); | 1801 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); |
1682 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); | 1802 | |
1683 | 1803 | lvid->descTag.descCRC = cpu_to_le16( | |
1684 | lvid->descTag.descCRC = cpu_to_le16( | 1804 | crc_itu_t(0, (char *)lvid + sizeof(tag), |
1685 | udf_crc((char *)lvid + sizeof(tag), | 1805 | le16_to_cpu(lvid->descTag.descCRCLength))); |
1686 | le16_to_cpu(lvid->descTag.descCRCLength), | 1806 | |
1687 | 0)); | 1807 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1688 | 1808 | mark_buffer_dirty(bh); | |
1689 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | ||
1690 | mark_buffer_dirty(bh); | ||
1691 | } | ||
1692 | } | 1809 | } |
1693 | 1810 | ||
1694 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | 1811 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) |
@@ -1708,22 +1825,35 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | |||
1708 | vfree(bitmap); | 1825 | vfree(bitmap); |
1709 | } | 1826 | } |
1710 | 1827 | ||
1711 | /* | 1828 | static void udf_free_partition(struct udf_part_map *map) |
1712 | * udf_read_super | 1829 | { |
1713 | * | 1830 | int i; |
1714 | * PURPOSE | 1831 | struct udf_meta_data *mdata; |
1715 | * Complete the specified super block. | 1832 | |
1716 | * | 1833 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) |
1717 | * PRE-CONDITIONS | 1834 | iput(map->s_uspace.s_table); |
1718 | * sb Pointer to superblock to complete - never NULL. | 1835 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
1719 | * sb->s_dev Device to read suberblock from. | 1836 | iput(map->s_fspace.s_table); |
1720 | * options Pointer to mount options. | 1837 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
1721 | * silent Silent flag. | 1838 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); |
1722 | * | 1839 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
1723 | * HISTORY | 1840 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); |
1724 | * July 1, 1997 - Andrew E. Mileski | 1841 | if (map->s_partition_type == UDF_SPARABLE_MAP15) |
1725 | * Written, tested, and released. | 1842 | for (i = 0; i < 4; i++) |
1726 | */ | 1843 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); |
1844 | else if (map->s_partition_type == UDF_METADATA_MAP25) { | ||
1845 | mdata = &map->s_type_specific.s_metadata; | ||
1846 | iput(mdata->s_metadata_fe); | ||
1847 | mdata->s_metadata_fe = NULL; | ||
1848 | |||
1849 | iput(mdata->s_mirror_fe); | ||
1850 | mdata->s_mirror_fe = NULL; | ||
1851 | |||
1852 | iput(mdata->s_bitmap_fe); | ||
1853 | mdata->s_bitmap_fe = NULL; | ||
1854 | } | ||
1855 | } | ||
1856 | |||
1727 | static int udf_fill_super(struct super_block *sb, void *options, int silent) | 1857 | static int udf_fill_super(struct super_block *sb, void *options, int silent) |
1728 | { | 1858 | { |
1729 | int i; | 1859 | int i; |
@@ -1776,8 +1906,11 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1776 | sbi->s_nls_map = uopt.nls_map; | 1906 | sbi->s_nls_map = uopt.nls_map; |
1777 | 1907 | ||
1778 | /* Set the block size for all transfers */ | 1908 | /* Set the block size for all transfers */ |
1779 | if (!udf_set_blocksize(sb, uopt.blocksize)) | 1909 | if (!sb_min_blocksize(sb, uopt.blocksize)) { |
1910 | udf_debug("Bad block size (%d)\n", uopt.blocksize); | ||
1911 | printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize); | ||
1780 | goto error_out; | 1912 | goto error_out; |
1913 | } | ||
1781 | 1914 | ||
1782 | if (uopt.session == 0xFFFFFFFF) | 1915 | if (uopt.session == 0xFFFFFFFF) |
1783 | sbi->s_session = udf_get_last_session(sb); | 1916 | sbi->s_session = udf_get_last_session(sb); |
@@ -1789,7 +1922,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1789 | sbi->s_last_block = uopt.lastblock; | 1922 | sbi->s_last_block = uopt.lastblock; |
1790 | sbi->s_anchor[0] = sbi->s_anchor[1] = 0; | 1923 | sbi->s_anchor[0] = sbi->s_anchor[1] = 0; |
1791 | sbi->s_anchor[2] = uopt.anchor; | 1924 | sbi->s_anchor[2] = uopt.anchor; |
1792 | sbi->s_anchor[3] = 256; | ||
1793 | 1925 | ||
1794 | if (udf_check_valid(sb, uopt.novrs, silent)) { | 1926 | if (udf_check_valid(sb, uopt.novrs, silent)) { |
1795 | /* read volume recognition sequences */ | 1927 | /* read volume recognition sequences */ |
@@ -1806,7 +1938,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1806 | sb->s_magic = UDF_SUPER_MAGIC; | 1938 | sb->s_magic = UDF_SUPER_MAGIC; |
1807 | sb->s_time_gran = 1000; | 1939 | sb->s_time_gran = 1000; |
1808 | 1940 | ||
1809 | if (udf_load_partition(sb, &fileset)) { | 1941 | if (udf_load_sequence(sb, &fileset)) { |
1810 | printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); | 1942 | printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); |
1811 | goto error_out; | 1943 | goto error_out; |
1812 | } | 1944 | } |
@@ -1856,12 +1988,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1856 | } | 1988 | } |
1857 | 1989 | ||
1858 | if (!silent) { | 1990 | if (!silent) { |
1859 | kernel_timestamp ts; | 1991 | timestamp ts; |
1860 | udf_time_to_stamp(&ts, sbi->s_record_time); | 1992 | udf_time_to_disk_stamp(&ts, sbi->s_record_time); |
1861 | udf_info("UDF: Mounting volume '%s', " | 1993 | udf_info("UDF: Mounting volume '%s', " |
1862 | "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", | 1994 | "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", |
1863 | sbi->s_volume_ident, ts.year, ts.month, ts.day, | 1995 | sbi->s_volume_ident, le16_to_cpu(ts.year), ts.month, ts.day, |
1864 | ts.hour, ts.minute, ts.typeAndTimezone); | 1996 | ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone)); |
1865 | } | 1997 | } |
1866 | if (!(sb->s_flags & MS_RDONLY)) | 1998 | if (!(sb->s_flags & MS_RDONLY)) |
1867 | udf_open_lvid(sb); | 1999 | udf_open_lvid(sb); |
@@ -1890,21 +2022,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1890 | error_out: | 2022 | error_out: |
1891 | if (sbi->s_vat_inode) | 2023 | if (sbi->s_vat_inode) |
1892 | iput(sbi->s_vat_inode); | 2024 | iput(sbi->s_vat_inode); |
1893 | if (sbi->s_partitions) { | 2025 | if (sbi->s_partitions) |
1894 | struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; | 2026 | for (i = 0; i < sbi->s_partitions; i++) |
1895 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 2027 | udf_free_partition(&sbi->s_partmaps[i]); |
1896 | iput(map->s_uspace.s_table); | ||
1897 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | ||
1898 | iput(map->s_fspace.s_table); | ||
1899 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | ||
1900 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); | ||
1901 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
1902 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); | ||
1903 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | ||
1904 | for (i = 0; i < 4; i++) | ||
1905 | brelse(map->s_type_specific.s_sparing. | ||
1906 | s_spar_map[i]); | ||
1907 | } | ||
1908 | #ifdef CONFIG_UDF_NLS | 2028 | #ifdef CONFIG_UDF_NLS |
1909 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) | 2029 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
1910 | unload_nls(sbi->s_nls_map); | 2030 | unload_nls(sbi->s_nls_map); |
@@ -1920,8 +2040,8 @@ error_out: | |||
1920 | return -EINVAL; | 2040 | return -EINVAL; |
1921 | } | 2041 | } |
1922 | 2042 | ||
1923 | void udf_error(struct super_block *sb, const char *function, | 2043 | static void udf_error(struct super_block *sb, const char *function, |
1924 | const char *fmt, ...) | 2044 | const char *fmt, ...) |
1925 | { | 2045 | { |
1926 | va_list args; | 2046 | va_list args; |
1927 | 2047 | ||
@@ -1948,19 +2068,6 @@ void udf_warning(struct super_block *sb, const char *function, | |||
1948 | sb->s_id, function, error_buf); | 2068 | sb->s_id, function, error_buf); |
1949 | } | 2069 | } |
1950 | 2070 | ||
1951 | /* | ||
1952 | * udf_put_super | ||
1953 | * | ||
1954 | * PURPOSE | ||
1955 | * Prepare for destruction of the superblock. | ||
1956 | * | ||
1957 | * DESCRIPTION | ||
1958 | * Called before the filesystem is unmounted. | ||
1959 | * | ||
1960 | * HISTORY | ||
1961 | * July 1, 1997 - Andrew E. Mileski | ||
1962 | * Written, tested, and released. | ||
1963 | */ | ||
1964 | static void udf_put_super(struct super_block *sb) | 2071 | static void udf_put_super(struct super_block *sb) |
1965 | { | 2072 | { |
1966 | int i; | 2073 | int i; |
@@ -1969,21 +2076,9 @@ static void udf_put_super(struct super_block *sb) | |||
1969 | sbi = UDF_SB(sb); | 2076 | sbi = UDF_SB(sb); |
1970 | if (sbi->s_vat_inode) | 2077 | if (sbi->s_vat_inode) |
1971 | iput(sbi->s_vat_inode); | 2078 | iput(sbi->s_vat_inode); |
1972 | if (sbi->s_partitions) { | 2079 | if (sbi->s_partitions) |
1973 | struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; | 2080 | for (i = 0; i < sbi->s_partitions; i++) |
1974 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 2081 | udf_free_partition(&sbi->s_partmaps[i]); |
1975 | iput(map->s_uspace.s_table); | ||
1976 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | ||
1977 | iput(map->s_fspace.s_table); | ||
1978 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | ||
1979 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); | ||
1980 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
1981 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); | ||
1982 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | ||
1983 | for (i = 0; i < 4; i++) | ||
1984 | brelse(map->s_type_specific.s_sparing. | ||
1985 | s_spar_map[i]); | ||
1986 | } | ||
1987 | #ifdef CONFIG_UDF_NLS | 2082 | #ifdef CONFIG_UDF_NLS |
1988 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) | 2083 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
1989 | unload_nls(sbi->s_nls_map); | 2084 | unload_nls(sbi->s_nls_map); |
@@ -1996,19 +2091,6 @@ static void udf_put_super(struct super_block *sb) | |||
1996 | sb->s_fs_info = NULL; | 2091 | sb->s_fs_info = NULL; |
1997 | } | 2092 | } |
1998 | 2093 | ||
1999 | /* | ||
2000 | * udf_stat_fs | ||
2001 | * | ||
2002 | * PURPOSE | ||
2003 | * Return info about the filesystem. | ||
2004 | * | ||
2005 | * DESCRIPTION | ||
2006 | * Called by sys_statfs() | ||
2007 | * | ||
2008 | * HISTORY | ||
2009 | * July 1, 1997 - Andrew E. Mileski | ||
2010 | * Written, tested, and released. | ||
2011 | */ | ||
2012 | static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | 2094 | static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) |
2013 | { | 2095 | { |
2014 | struct super_block *sb = dentry->d_sb; | 2096 | struct super_block *sb = dentry->d_sb; |
@@ -2035,10 +2117,6 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
2035 | return 0; | 2117 | return 0; |
2036 | } | 2118 | } |
2037 | 2119 | ||
2038 | static unsigned char udf_bitmap_lookup[16] = { | ||
2039 | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 | ||
2040 | }; | ||
2041 | |||
2042 | static unsigned int udf_count_free_bitmap(struct super_block *sb, | 2120 | static unsigned int udf_count_free_bitmap(struct super_block *sb, |
2043 | struct udf_bitmap *bitmap) | 2121 | struct udf_bitmap *bitmap) |
2044 | { | 2122 | { |
@@ -2048,7 +2126,6 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2048 | int block = 0, newblock; | 2126 | int block = 0, newblock; |
2049 | kernel_lb_addr loc; | 2127 | kernel_lb_addr loc; |
2050 | uint32_t bytes; | 2128 | uint32_t bytes; |
2051 | uint8_t value; | ||
2052 | uint8_t *ptr; | 2129 | uint8_t *ptr; |
2053 | uint16_t ident; | 2130 | uint16_t ident; |
2054 | struct spaceBitmapDesc *bm; | 2131 | struct spaceBitmapDesc *bm; |
@@ -2074,13 +2151,10 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2074 | ptr = (uint8_t *)bh->b_data; | 2151 | ptr = (uint8_t *)bh->b_data; |
2075 | 2152 | ||
2076 | while (bytes > 0) { | 2153 | while (bytes > 0) { |
2077 | while ((bytes > 0) && (index < sb->s_blocksize)) { | 2154 | u32 cur_bytes = min_t(u32, bytes, sb->s_blocksize - index); |
2078 | value = ptr[index]; | 2155 | accum += bitmap_weight((const unsigned long *)(ptr + index), |
2079 | accum += udf_bitmap_lookup[value & 0x0f]; | 2156 | cur_bytes * 8); |
2080 | accum += udf_bitmap_lookup[value >> 4]; | 2157 | bytes -= cur_bytes; |
2081 | index++; | ||
2082 | bytes--; | ||
2083 | } | ||
2084 | if (bytes) { | 2158 | if (bytes) { |
2085 | brelse(bh); | 2159 | brelse(bh); |
2086 | newblock = udf_get_lb_pblock(sb, loc, ++block); | 2160 | newblock = udf_get_lb_pblock(sb, loc, ++block); |
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 6ec99221e50c..c3265e1385d4 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/udf_fs.h> | ||
27 | #include <linux/time.h> | 26 | #include <linux/time.h> |
28 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
29 | #include <linux/stat.h> | 28 | #include <linux/stat.h> |
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index fe61be17cdab..65e19b4f9424 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "udfdecl.h" | 22 | #include "udfdecl.h" |
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/udf_fs.h> | ||
26 | #include <linux/buffer_head.h> | 25 | #include <linux/buffer_head.h> |
27 | 26 | ||
28 | #include "udf_i.h" | 27 | #include "udf_i.h" |
@@ -180,6 +179,24 @@ void udf_discard_prealloc(struct inode *inode) | |||
180 | brelse(epos.bh); | 179 | brelse(epos.bh); |
181 | } | 180 | } |
182 | 181 | ||
182 | static void udf_update_alloc_ext_desc(struct inode *inode, | ||
183 | struct extent_position *epos, | ||
184 | u32 lenalloc) | ||
185 | { | ||
186 | struct super_block *sb = inode->i_sb; | ||
187 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
188 | |||
189 | struct allocExtDesc *aed = (struct allocExtDesc *) (epos->bh->b_data); | ||
190 | int len = sizeof(struct allocExtDesc); | ||
191 | |||
192 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | ||
193 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || sbi->s_udfrev >= 0x0201) | ||
194 | len += lenalloc; | ||
195 | |||
196 | udf_update_tag(epos->bh->b_data, len); | ||
197 | mark_buffer_dirty_inode(epos->bh, inode); | ||
198 | } | ||
199 | |||
183 | void udf_truncate_extents(struct inode *inode) | 200 | void udf_truncate_extents(struct inode *inode) |
184 | { | 201 | { |
185 | struct extent_position epos; | 202 | struct extent_position epos; |
@@ -187,7 +204,6 @@ void udf_truncate_extents(struct inode *inode) | |||
187 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; | 204 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; |
188 | int8_t etype; | 205 | int8_t etype; |
189 | struct super_block *sb = inode->i_sb; | 206 | struct super_block *sb = inode->i_sb; |
190 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
191 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; | 207 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; |
192 | loff_t byte_offset; | 208 | loff_t byte_offset; |
193 | int adsize; | 209 | int adsize; |
@@ -224,35 +240,15 @@ void udf_truncate_extents(struct inode *inode) | |||
224 | if (indirect_ext_len) { | 240 | if (indirect_ext_len) { |
225 | /* We managed to free all extents in the | 241 | /* We managed to free all extents in the |
226 | * indirect extent - free it too */ | 242 | * indirect extent - free it too */ |
227 | if (!epos.bh) | 243 | BUG_ON(!epos.bh); |
228 | BUG(); | ||
229 | udf_free_blocks(sb, inode, epos.block, | 244 | udf_free_blocks(sb, inode, epos.block, |
230 | 0, indirect_ext_len); | 245 | 0, indirect_ext_len); |
231 | } else { | 246 | } else if (!epos.bh) { |
232 | if (!epos.bh) { | 247 | iinfo->i_lenAlloc = lenalloc; |
233 | iinfo->i_lenAlloc = | 248 | mark_inode_dirty(inode); |
234 | lenalloc; | 249 | } else |
235 | mark_inode_dirty(inode); | 250 | udf_update_alloc_ext_desc(inode, |
236 | } else { | 251 | &epos, lenalloc); |
237 | struct allocExtDesc *aed = | ||
238 | (struct allocExtDesc *) | ||
239 | (epos.bh->b_data); | ||
240 | int len = | ||
241 | sizeof(struct allocExtDesc); | ||
242 | |||
243 | aed->lengthAllocDescs = | ||
244 | cpu_to_le32(lenalloc); | ||
245 | if (!UDF_QUERY_FLAG(sb, | ||
246 | UDF_FLAG_STRICT) || | ||
247 | sbi->s_udfrev >= 0x0201) | ||
248 | len += lenalloc; | ||
249 | |||
250 | udf_update_tag(epos.bh->b_data, | ||
251 | len); | ||
252 | mark_buffer_dirty_inode( | ||
253 | epos.bh, inode); | ||
254 | } | ||
255 | } | ||
256 | brelse(epos.bh); | 252 | brelse(epos.bh); |
257 | epos.offset = sizeof(struct allocExtDesc); | 253 | epos.offset = sizeof(struct allocExtDesc); |
258 | epos.block = eloc; | 254 | epos.block = eloc; |
@@ -272,29 +268,14 @@ void udf_truncate_extents(struct inode *inode) | |||
272 | } | 268 | } |
273 | 269 | ||
274 | if (indirect_ext_len) { | 270 | if (indirect_ext_len) { |
275 | if (!epos.bh) | 271 | BUG_ON(!epos.bh); |
276 | BUG(); | ||
277 | udf_free_blocks(sb, inode, epos.block, 0, | 272 | udf_free_blocks(sb, inode, epos.block, 0, |
278 | indirect_ext_len); | 273 | indirect_ext_len); |
279 | } else { | 274 | } else if (!epos.bh) { |
280 | if (!epos.bh) { | 275 | iinfo->i_lenAlloc = lenalloc; |
281 | iinfo->i_lenAlloc = lenalloc; | 276 | mark_inode_dirty(inode); |
282 | mark_inode_dirty(inode); | 277 | } else |
283 | } else { | 278 | udf_update_alloc_ext_desc(inode, &epos, lenalloc); |
284 | struct allocExtDesc *aed = | ||
285 | (struct allocExtDesc *)(epos.bh->b_data); | ||
286 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | ||
287 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || | ||
288 | sbi->s_udfrev >= 0x0201) | ||
289 | udf_update_tag(epos.bh->b_data, | ||
290 | lenalloc + | ||
291 | sizeof(struct allocExtDesc)); | ||
292 | else | ||
293 | udf_update_tag(epos.bh->b_data, | ||
294 | sizeof(struct allocExtDesc)); | ||
295 | mark_buffer_dirty_inode(epos.bh, inode); | ||
296 | } | ||
297 | } | ||
298 | } else if (inode->i_size) { | 279 | } else if (inode->i_size) { |
299 | if (byte_offset) { | 280 | if (byte_offset) { |
300 | kernel_long_ad extent; | 281 | kernel_long_ad extent; |
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index ccc52f16bf7d..4f86b1d98a5d 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h | |||
@@ -1,10 +1,32 @@ | |||
1 | #ifndef __LINUX_UDF_I_H | 1 | #ifndef _UDF_I_H |
2 | #define __LINUX_UDF_I_H | 2 | #define _UDF_I_H |
3 | |||
4 | struct udf_inode_info { | ||
5 | struct timespec i_crtime; | ||
6 | /* Physical address of inode */ | ||
7 | kernel_lb_addr i_location; | ||
8 | __u64 i_unique; | ||
9 | __u32 i_lenEAttr; | ||
10 | __u32 i_lenAlloc; | ||
11 | __u64 i_lenExtents; | ||
12 | __u32 i_next_alloc_block; | ||
13 | __u32 i_next_alloc_goal; | ||
14 | unsigned i_alloc_type : 3; | ||
15 | unsigned i_efe : 1; /* extendedFileEntry */ | ||
16 | unsigned i_use : 1; /* unallocSpaceEntry */ | ||
17 | unsigned i_strat4096 : 1; | ||
18 | unsigned reserved : 26; | ||
19 | union { | ||
20 | short_ad *i_sad; | ||
21 | long_ad *i_lad; | ||
22 | __u8 *i_data; | ||
23 | } i_ext; | ||
24 | struct inode vfs_inode; | ||
25 | }; | ||
3 | 26 | ||
4 | #include <linux/udf_fs_i.h> | ||
5 | static inline struct udf_inode_info *UDF_I(struct inode *inode) | 27 | static inline struct udf_inode_info *UDF_I(struct inode *inode) |
6 | { | 28 | { |
7 | return list_entry(inode, struct udf_inode_info, vfs_inode); | 29 | return list_entry(inode, struct udf_inode_info, vfs_inode); |
8 | } | 30 | } |
9 | 31 | ||
10 | #endif /* !defined(_LINUX_UDF_I_H) */ | 32 | #endif /* _UDF_I_H) */ |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 737d1c604eea..1c1c514a9725 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -1,10 +1,12 @@ | |||
1 | #ifndef __LINUX_UDF_SB_H | 1 | #ifndef __LINUX_UDF_SB_H |
2 | #define __LINUX_UDF_SB_H | 2 | #define __LINUX_UDF_SB_H |
3 | 3 | ||
4 | #include <linux/mutex.h> | ||
5 | |||
4 | /* Since UDF 2.01 is ISO 13346 based... */ | 6 | /* Since UDF 2.01 is ISO 13346 based... */ |
5 | #define UDF_SUPER_MAGIC 0x15013346 | 7 | #define UDF_SUPER_MAGIC 0x15013346 |
6 | 8 | ||
7 | #define UDF_MAX_READ_VERSION 0x0201 | 9 | #define UDF_MAX_READ_VERSION 0x0250 |
8 | #define UDF_MAX_WRITE_VERSION 0x0201 | 10 | #define UDF_MAX_WRITE_VERSION 0x0201 |
9 | 11 | ||
10 | #define UDF_FLAG_USE_EXTENDED_FE 0 | 12 | #define UDF_FLAG_USE_EXTENDED_FE 0 |
@@ -38,6 +40,111 @@ | |||
38 | #define UDF_PART_FLAG_REWRITABLE 0x0040 | 40 | #define UDF_PART_FLAG_REWRITABLE 0x0040 |
39 | #define UDF_PART_FLAG_OVERWRITABLE 0x0080 | 41 | #define UDF_PART_FLAG_OVERWRITABLE 0x0080 |
40 | 42 | ||
43 | #define UDF_MAX_BLOCK_LOADED 8 | ||
44 | |||
45 | #define UDF_TYPE1_MAP15 0x1511U | ||
46 | #define UDF_VIRTUAL_MAP15 0x1512U | ||
47 | #define UDF_VIRTUAL_MAP20 0x2012U | ||
48 | #define UDF_SPARABLE_MAP15 0x1522U | ||
49 | #define UDF_METADATA_MAP25 0x2511U | ||
50 | |||
51 | #pragma pack(1) /* XXX(hch): Why? This file just defines in-core structures */ | ||
52 | |||
53 | struct udf_meta_data { | ||
54 | __u32 s_meta_file_loc; | ||
55 | __u32 s_mirror_file_loc; | ||
56 | __u32 s_bitmap_file_loc; | ||
57 | __u32 s_alloc_unit_size; | ||
58 | __u16 s_align_unit_size; | ||
59 | __u8 s_dup_md_flag; | ||
60 | struct inode *s_metadata_fe; | ||
61 | struct inode *s_mirror_fe; | ||
62 | struct inode *s_bitmap_fe; | ||
63 | }; | ||
64 | |||
65 | struct udf_sparing_data { | ||
66 | __u16 s_packet_len; | ||
67 | struct buffer_head *s_spar_map[4]; | ||
68 | }; | ||
69 | |||
70 | struct udf_virtual_data { | ||
71 | __u32 s_num_entries; | ||
72 | __u16 s_start_offset; | ||
73 | }; | ||
74 | |||
75 | struct udf_bitmap { | ||
76 | __u32 s_extLength; | ||
77 | __u32 s_extPosition; | ||
78 | __u16 s_nr_groups; | ||
79 | struct buffer_head **s_block_bitmap; | ||
80 | }; | ||
81 | |||
82 | struct udf_part_map { | ||
83 | union { | ||
84 | struct udf_bitmap *s_bitmap; | ||
85 | struct inode *s_table; | ||
86 | } s_uspace; | ||
87 | union { | ||
88 | struct udf_bitmap *s_bitmap; | ||
89 | struct inode *s_table; | ||
90 | } s_fspace; | ||
91 | __u32 s_partition_root; | ||
92 | __u32 s_partition_len; | ||
93 | __u16 s_partition_type; | ||
94 | __u16 s_partition_num; | ||
95 | union { | ||
96 | struct udf_sparing_data s_sparing; | ||
97 | struct udf_virtual_data s_virtual; | ||
98 | struct udf_meta_data s_metadata; | ||
99 | } s_type_specific; | ||
100 | __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32); | ||
101 | __u16 s_volumeseqnum; | ||
102 | __u16 s_partition_flags; | ||
103 | }; | ||
104 | |||
105 | #pragma pack() | ||
106 | |||
107 | struct udf_sb_info { | ||
108 | struct udf_part_map *s_partmaps; | ||
109 | __u8 s_volume_ident[32]; | ||
110 | |||
111 | /* Overall info */ | ||
112 | __u16 s_partitions; | ||
113 | __u16 s_partition; | ||
114 | |||
115 | /* Sector headers */ | ||
116 | __s32 s_session; | ||
117 | __u32 s_anchor[3]; | ||
118 | __u32 s_last_block; | ||
119 | |||
120 | struct buffer_head *s_lvid_bh; | ||
121 | |||
122 | /* Default permissions */ | ||
123 | mode_t s_umask; | ||
124 | gid_t s_gid; | ||
125 | uid_t s_uid; | ||
126 | |||
127 | /* Root Info */ | ||
128 | struct timespec s_record_time; | ||
129 | |||
130 | /* Fileset Info */ | ||
131 | __u16 s_serial_number; | ||
132 | |||
133 | /* highest UDF revision we have recorded to this media */ | ||
134 | __u16 s_udfrev; | ||
135 | |||
136 | /* Miscellaneous flags */ | ||
137 | __u32 s_flags; | ||
138 | |||
139 | /* Encoding info */ | ||
140 | struct nls_table *s_nls_map; | ||
141 | |||
142 | /* VAT inode */ | ||
143 | struct inode *s_vat_inode; | ||
144 | |||
145 | struct mutex s_alloc_mutex; | ||
146 | }; | ||
147 | |||
41 | static inline struct udf_sb_info *UDF_SB(struct super_block *sb) | 148 | static inline struct udf_sb_info *UDF_SB(struct super_block *sb) |
42 | { | 149 | { |
43 | return sb->s_fs_info; | 150 | return sb->s_fs_info; |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 681dc2b66cdb..f3f45d029277 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -1,17 +1,37 @@ | |||
1 | #ifndef __UDF_DECL_H | 1 | #ifndef __UDF_DECL_H |
2 | #define __UDF_DECL_H | 2 | #define __UDF_DECL_H |
3 | 3 | ||
4 | #include <linux/udf_fs.h> | ||
5 | #include "ecma_167.h" | 4 | #include "ecma_167.h" |
6 | #include "osta_udf.h" | 5 | #include "osta_udf.h" |
7 | 6 | ||
8 | #include <linux/fs.h> | 7 | #include <linux/fs.h> |
9 | #include <linux/types.h> | 8 | #include <linux/types.h> |
10 | #include <linux/udf_fs_i.h> | ||
11 | #include <linux/udf_fs_sb.h> | ||
12 | #include <linux/buffer_head.h> | 9 | #include <linux/buffer_head.h> |
10 | #include <linux/udf_fs_i.h> | ||
13 | 11 | ||
12 | #include "udf_sb.h" | ||
14 | #include "udfend.h" | 13 | #include "udfend.h" |
14 | #include "udf_i.h" | ||
15 | |||
16 | #define UDF_PREALLOCATE | ||
17 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 | ||
18 | |||
19 | #define UDFFS_DEBUG | ||
20 | |||
21 | #ifdef UDFFS_DEBUG | ||
22 | #define udf_debug(f, a...) \ | ||
23 | do { \ | ||
24 | printk(KERN_DEBUG "UDF-fs DEBUG %s:%d:%s: ", \ | ||
25 | __FILE__, __LINE__, __func__); \ | ||
26 | printk(f, ##a); \ | ||
27 | } while (0) | ||
28 | #else | ||
29 | #define udf_debug(f, a...) /**/ | ||
30 | #endif | ||
31 | |||
32 | #define udf_info(f, a...) \ | ||
33 | printk(KERN_INFO "UDF-fs INFO " f, ##a); | ||
34 | |||
15 | 35 | ||
16 | #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) | 36 | #define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) |
17 | #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) | 37 | #define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) |
@@ -23,16 +43,24 @@ | |||
23 | #define UDF_NAME_LEN 256 | 43 | #define UDF_NAME_LEN 256 |
24 | #define UDF_PATH_LEN 1023 | 44 | #define UDF_PATH_LEN 1023 |
25 | 45 | ||
26 | #define udf_file_entry_alloc_offset(inode)\ | 46 | static inline size_t udf_file_entry_alloc_offset(struct inode *inode) |
27 | (UDF_I(inode)->i_use ?\ | 47 | { |
28 | sizeof(struct unallocSpaceEntry) :\ | 48 | struct udf_inode_info *iinfo = UDF_I(inode); |
29 | ((UDF_I(inode)->i_efe ?\ | 49 | if (iinfo->i_use) |
30 | sizeof(struct extendedFileEntry) :\ | 50 | return sizeof(struct unallocSpaceEntry); |
31 | sizeof(struct fileEntry)) + UDF_I(inode)->i_lenEAttr)) | 51 | else if (iinfo->i_efe) |
32 | 52 | return sizeof(struct extendedFileEntry) + iinfo->i_lenEAttr; | |
33 | #define udf_ext0_offset(inode)\ | 53 | else |
34 | (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ?\ | 54 | return sizeof(struct fileEntry) + iinfo->i_lenEAttr; |
35 | udf_file_entry_alloc_offset(inode) : 0) | 55 | } |
56 | |||
57 | static inline size_t udf_ext0_offset(struct inode *inode) | ||
58 | { | ||
59 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
60 | return udf_file_entry_alloc_offset(inode); | ||
61 | else | ||
62 | return 0; | ||
63 | } | ||
36 | 64 | ||
37 | #define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset)) | 65 | #define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset)) |
38 | 66 | ||
@@ -83,7 +111,6 @@ struct extent_position { | |||
83 | }; | 111 | }; |
84 | 112 | ||
85 | /* super.c */ | 113 | /* super.c */ |
86 | extern void udf_error(struct super_block *, const char *, const char *, ...); | ||
87 | extern void udf_warning(struct super_block *, const char *, const char *, ...); | 114 | extern void udf_warning(struct super_block *, const char *, const char *, ...); |
88 | 115 | ||
89 | /* namei.c */ | 116 | /* namei.c */ |
@@ -150,6 +177,8 @@ extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t, | |||
150 | uint32_t); | 177 | uint32_t); |
151 | extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, | 178 | extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, |
152 | uint32_t); | 179 | uint32_t); |
180 | extern uint32_t udf_get_pblock_meta25(struct super_block *, uint32_t, uint16_t, | ||
181 | uint32_t); | ||
153 | extern int udf_relocate_blocks(struct super_block *, long, long *); | 182 | extern int udf_relocate_blocks(struct super_block *, long, long *); |
154 | 183 | ||
155 | /* unicode.c */ | 184 | /* unicode.c */ |
@@ -157,7 +186,7 @@ extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); | |||
157 | extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, | 186 | extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, |
158 | int); | 187 | int); |
159 | extern int udf_build_ustr(struct ustr *, dstring *, int); | 188 | extern int udf_build_ustr(struct ustr *, dstring *, int); |
160 | extern int udf_CS0toUTF8(struct ustr *, struct ustr *); | 189 | extern int udf_CS0toUTF8(struct ustr *, const struct ustr *); |
161 | 190 | ||
162 | /* ialloc.c */ | 191 | /* ialloc.c */ |
163 | extern void udf_free_inode(struct inode *); | 192 | extern void udf_free_inode(struct inode *); |
@@ -191,11 +220,9 @@ extern struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, | |||
191 | extern long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int); | 220 | extern long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int); |
192 | extern short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int); | 221 | extern short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int); |
193 | 222 | ||
194 | /* crc.c */ | ||
195 | extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t); | ||
196 | |||
197 | /* udftime.c */ | 223 | /* udftime.c */ |
198 | extern time_t *udf_stamp_to_time(time_t *, long *, kernel_timestamp); | 224 | extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest, |
199 | extern kernel_timestamp *udf_time_to_stamp(kernel_timestamp *, struct timespec); | 225 | timestamp src); |
226 | extern timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec src); | ||
200 | 227 | ||
201 | #endif /* __UDF_DECL_H */ | 228 | #endif /* __UDF_DECL_H */ |
diff --git a/fs/udf/udfend.h b/fs/udf/udfend.h index c4bd1203f857..489f52fb428c 100644 --- a/fs/udf/udfend.h +++ b/fs/udf/udfend.h | |||
@@ -24,17 +24,6 @@ static inline lb_addr cpu_to_lelb(kernel_lb_addr in) | |||
24 | return out; | 24 | return out; |
25 | } | 25 | } |
26 | 26 | ||
27 | static inline kernel_timestamp lets_to_cpu(timestamp in) | ||
28 | { | ||
29 | kernel_timestamp out; | ||
30 | |||
31 | memcpy(&out, &in, sizeof(timestamp)); | ||
32 | out.typeAndTimezone = le16_to_cpu(in.typeAndTimezone); | ||
33 | out.year = le16_to_cpu(in.year); | ||
34 | |||
35 | return out; | ||
36 | } | ||
37 | |||
38 | static inline short_ad lesa_to_cpu(short_ad in) | 27 | static inline short_ad lesa_to_cpu(short_ad in) |
39 | { | 28 | { |
40 | short_ad out; | 29 | short_ad out; |
@@ -85,15 +74,4 @@ static inline kernel_extent_ad leea_to_cpu(extent_ad in) | |||
85 | return out; | 74 | return out; |
86 | } | 75 | } |
87 | 76 | ||
88 | static inline timestamp cpu_to_lets(kernel_timestamp in) | ||
89 | { | ||
90 | timestamp out; | ||
91 | |||
92 | memcpy(&out, &in, sizeof(timestamp)); | ||
93 | out.typeAndTimezone = cpu_to_le16(in.typeAndTimezone); | ||
94 | out.year = cpu_to_le16(in.year); | ||
95 | |||
96 | return out; | ||
97 | } | ||
98 | |||
99 | #endif /* __UDF_ENDIAN_H */ | 77 | #endif /* __UDF_ENDIAN_H */ |
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c index ce595732ba6f..5f811655c9b5 100644 --- a/fs/udf/udftime.c +++ b/fs/udf/udftime.c | |||
@@ -85,39 +85,38 @@ extern struct timezone sys_tz; | |||
85 | #define SECS_PER_HOUR (60 * 60) | 85 | #define SECS_PER_HOUR (60 * 60) |
86 | #define SECS_PER_DAY (SECS_PER_HOUR * 24) | 86 | #define SECS_PER_DAY (SECS_PER_HOUR * 24) |
87 | 87 | ||
88 | time_t *udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src) | 88 | struct timespec *udf_disk_stamp_to_time(struct timespec *dest, timestamp src) |
89 | { | 89 | { |
90 | int yday; | 90 | int yday; |
91 | uint8_t type = src.typeAndTimezone >> 12; | 91 | u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone); |
92 | u16 year = le16_to_cpu(src.year); | ||
93 | uint8_t type = typeAndTimezone >> 12; | ||
92 | int16_t offset; | 94 | int16_t offset; |
93 | 95 | ||
94 | if (type == 1) { | 96 | if (type == 1) { |
95 | offset = src.typeAndTimezone << 4; | 97 | offset = typeAndTimezone << 4; |
96 | /* sign extent offset */ | 98 | /* sign extent offset */ |
97 | offset = (offset >> 4); | 99 | offset = (offset >> 4); |
98 | if (offset == -2047) /* unspecified offset */ | 100 | if (offset == -2047) /* unspecified offset */ |
99 | offset = 0; | 101 | offset = 0; |
100 | } else { | 102 | } else |
101 | offset = 0; | 103 | offset = 0; |
102 | } | ||
103 | 104 | ||
104 | if ((src.year < EPOCH_YEAR) || | 105 | if ((year < EPOCH_YEAR) || |
105 | (src.year >= EPOCH_YEAR + MAX_YEAR_SECONDS)) { | 106 | (year >= EPOCH_YEAR + MAX_YEAR_SECONDS)) { |
106 | *dest = -1; | ||
107 | *dest_usec = -1; | ||
108 | return NULL; | 107 | return NULL; |
109 | } | 108 | } |
110 | *dest = year_seconds[src.year - EPOCH_YEAR]; | 109 | dest->tv_sec = year_seconds[year - EPOCH_YEAR]; |
111 | *dest -= offset * 60; | 110 | dest->tv_sec -= offset * 60; |
112 | 111 | ||
113 | yday = ((__mon_yday[__isleap(src.year)][src.month - 1]) + src.day - 1); | 112 | yday = ((__mon_yday[__isleap(year)][src.month - 1]) + src.day - 1); |
114 | *dest += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second; | 113 | dest->tv_sec += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second; |
115 | *dest_usec = src.centiseconds * 10000 + | 114 | dest->tv_nsec = 1000 * (src.centiseconds * 10000 + |
116 | src.hundredsOfMicroseconds * 100 + src.microseconds; | 115 | src.hundredsOfMicroseconds * 100 + src.microseconds); |
117 | return dest; | 116 | return dest; |
118 | } | 117 | } |
119 | 118 | ||
120 | kernel_timestamp *udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts) | 119 | timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec ts) |
121 | { | 120 | { |
122 | long int days, rem, y; | 121 | long int days, rem, y; |
123 | const unsigned short int *ip; | 122 | const unsigned short int *ip; |
@@ -128,7 +127,7 @@ kernel_timestamp *udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts) | |||
128 | if (!dest) | 127 | if (!dest) |
129 | return NULL; | 128 | return NULL; |
130 | 129 | ||
131 | dest->typeAndTimezone = 0x1000 | (offset & 0x0FFF); | 130 | dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF)); |
132 | 131 | ||
133 | ts.tv_sec += offset * 60; | 132 | ts.tv_sec += offset * 60; |
134 | days = ts.tv_sec / SECS_PER_DAY; | 133 | days = ts.tv_sec / SECS_PER_DAY; |
@@ -151,7 +150,7 @@ kernel_timestamp *udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts) | |||
151 | - LEAPS_THRU_END_OF(y - 1)); | 150 | - LEAPS_THRU_END_OF(y - 1)); |
152 | y = yg; | 151 | y = yg; |
153 | } | 152 | } |
154 | dest->year = y; | 153 | dest->year = cpu_to_le16(y); |
155 | ip = __mon_yday[__isleap(y)]; | 154 | ip = __mon_yday[__isleap(y)]; |
156 | for (y = 11; days < (long int)ip[y]; --y) | 155 | for (y = 11; days < (long int)ip[y]; --y) |
157 | continue; | 156 | continue; |
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index e533b11703bf..9fdf8c93c58e 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/string.h> /* for memset */ | 24 | #include <linux/string.h> /* for memset */ |
25 | #include <linux/nls.h> | 25 | #include <linux/nls.h> |
26 | #include <linux/udf_fs.h> | 26 | #include <linux/crc-itu-t.h> |
27 | 27 | ||
28 | #include "udf_sb.h" | 28 | #include "udf_sb.h" |
29 | 29 | ||
@@ -49,14 +49,16 @@ int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) | |||
49 | { | 49 | { |
50 | int usesize; | 50 | int usesize; |
51 | 51 | ||
52 | if ((!dest) || (!ptr) || (!size)) | 52 | if (!dest || !ptr || !size) |
53 | return -1; | 53 | return -1; |
54 | BUG_ON(size < 2); | ||
54 | 55 | ||
55 | memset(dest, 0, sizeof(struct ustr)); | 56 | usesize = min_t(size_t, ptr[size - 1], sizeof(dest->u_name)); |
56 | usesize = (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size; | 57 | usesize = min(usesize, size - 2); |
57 | dest->u_cmpID = ptr[0]; | 58 | dest->u_cmpID = ptr[0]; |
58 | dest->u_len = ptr[size - 1]; | 59 | dest->u_len = usesize; |
59 | memcpy(dest->u_name, ptr + 1, usesize - 1); | 60 | memcpy(dest->u_name, ptr + 1, usesize); |
61 | memset(dest->u_name + usesize, 0, sizeof(dest->u_name) - usesize); | ||
60 | 62 | ||
61 | return 0; | 63 | return 0; |
62 | } | 64 | } |
@@ -83,9 +85,6 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) | |||
83 | * PURPOSE | 85 | * PURPOSE |
84 | * Convert OSTA Compressed Unicode to the UTF-8 equivalent. | 86 | * Convert OSTA Compressed Unicode to the UTF-8 equivalent. |
85 | * | 87 | * |
86 | * DESCRIPTION | ||
87 | * This routine is only called by udf_filldir(). | ||
88 | * | ||
89 | * PRE-CONDITIONS | 88 | * PRE-CONDITIONS |
90 | * utf Pointer to UTF-8 output buffer. | 89 | * utf Pointer to UTF-8 output buffer. |
91 | * ocu Pointer to OSTA Compressed Unicode input buffer | 90 | * ocu Pointer to OSTA Compressed Unicode input buffer |
@@ -99,43 +98,39 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) | |||
99 | * November 12, 1997 - Andrew E. Mileski | 98 | * November 12, 1997 - Andrew E. Mileski |
100 | * Written, tested, and released. | 99 | * Written, tested, and released. |
101 | */ | 100 | */ |
102 | int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i) | 101 | int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) |
103 | { | 102 | { |
104 | uint8_t *ocu; | 103 | const uint8_t *ocu; |
105 | uint32_t c; | ||
106 | uint8_t cmp_id, ocu_len; | 104 | uint8_t cmp_id, ocu_len; |
107 | int i; | 105 | int i; |
108 | 106 | ||
109 | ocu = ocu_i->u_name; | ||
110 | |||
111 | ocu_len = ocu_i->u_len; | 107 | ocu_len = ocu_i->u_len; |
112 | cmp_id = ocu_i->u_cmpID; | ||
113 | utf_o->u_len = 0; | ||
114 | |||
115 | if (ocu_len == 0) { | 108 | if (ocu_len == 0) { |
116 | memset(utf_o, 0, sizeof(struct ustr)); | 109 | memset(utf_o, 0, sizeof(struct ustr)); |
117 | utf_o->u_cmpID = 0; | ||
118 | utf_o->u_len = 0; | ||
119 | return 0; | 110 | return 0; |
120 | } | 111 | } |
121 | 112 | ||
122 | if ((cmp_id != 8) && (cmp_id != 16)) { | 113 | cmp_id = ocu_i->u_cmpID; |
114 | if (cmp_id != 8 && cmp_id != 16) { | ||
115 | memset(utf_o, 0, sizeof(struct ustr)); | ||
123 | printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", | 116 | printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", |
124 | cmp_id, ocu_i->u_name); | 117 | cmp_id, ocu_i->u_name); |
125 | return 0; | 118 | return 0; |
126 | } | 119 | } |
127 | 120 | ||
121 | ocu = ocu_i->u_name; | ||
122 | utf_o->u_len = 0; | ||
128 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { | 123 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { |
129 | 124 | ||
130 | /* Expand OSTA compressed Unicode to Unicode */ | 125 | /* Expand OSTA compressed Unicode to Unicode */ |
131 | c = ocu[i++]; | 126 | uint32_t c = ocu[i++]; |
132 | if (cmp_id == 16) | 127 | if (cmp_id == 16) |
133 | c = (c << 8) | ocu[i++]; | 128 | c = (c << 8) | ocu[i++]; |
134 | 129 | ||
135 | /* Compress Unicode to UTF-8 */ | 130 | /* Compress Unicode to UTF-8 */ |
136 | if (c < 0x80U) { | 131 | if (c < 0x80U) |
137 | utf_o->u_name[utf_o->u_len++] = (uint8_t)c; | 132 | utf_o->u_name[utf_o->u_len++] = (uint8_t)c; |
138 | } else if (c < 0x800U) { | 133 | else if (c < 0x800U) { |
139 | utf_o->u_name[utf_o->u_len++] = | 134 | utf_o->u_name[utf_o->u_len++] = |
140 | (uint8_t)(0xc0 | (c >> 6)); | 135 | (uint8_t)(0xc0 | (c >> 6)); |
141 | utf_o->u_name[utf_o->u_len++] = | 136 | utf_o->u_name[utf_o->u_len++] = |
@@ -255,35 +250,32 @@ error_out: | |||
255 | } | 250 | } |
256 | 251 | ||
257 | static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, | 252 | static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, |
258 | struct ustr *ocu_i) | 253 | const struct ustr *ocu_i) |
259 | { | 254 | { |
260 | uint8_t *ocu; | 255 | const uint8_t *ocu; |
261 | uint32_t c; | ||
262 | uint8_t cmp_id, ocu_len; | 256 | uint8_t cmp_id, ocu_len; |
263 | int i; | 257 | int i; |
264 | 258 | ||
265 | ocu = ocu_i->u_name; | ||
266 | 259 | ||
267 | ocu_len = ocu_i->u_len; | 260 | ocu_len = ocu_i->u_len; |
268 | cmp_id = ocu_i->u_cmpID; | ||
269 | utf_o->u_len = 0; | ||
270 | |||
271 | if (ocu_len == 0) { | 261 | if (ocu_len == 0) { |
272 | memset(utf_o, 0, sizeof(struct ustr)); | 262 | memset(utf_o, 0, sizeof(struct ustr)); |
273 | utf_o->u_cmpID = 0; | ||
274 | utf_o->u_len = 0; | ||
275 | return 0; | 263 | return 0; |
276 | } | 264 | } |
277 | 265 | ||
278 | if ((cmp_id != 8) && (cmp_id != 16)) { | 266 | cmp_id = ocu_i->u_cmpID; |
267 | if (cmp_id != 8 && cmp_id != 16) { | ||
268 | memset(utf_o, 0, sizeof(struct ustr)); | ||
279 | printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", | 269 | printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", |
280 | cmp_id, ocu_i->u_name); | 270 | cmp_id, ocu_i->u_name); |
281 | return 0; | 271 | return 0; |
282 | } | 272 | } |
283 | 273 | ||
274 | ocu = ocu_i->u_name; | ||
275 | utf_o->u_len = 0; | ||
284 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { | 276 | for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { |
285 | /* Expand OSTA compressed Unicode to Unicode */ | 277 | /* Expand OSTA compressed Unicode to Unicode */ |
286 | c = ocu[i++]; | 278 | uint32_t c = ocu[i++]; |
287 | if (cmp_id == 16) | 279 | if (cmp_id == 16) |
288 | c = (c << 8) | ocu[i++]; | 280 | c = (c << 8) | ocu[i++]; |
289 | 281 | ||
@@ -463,7 +455,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, | |||
463 | } else if (newIndex > 250) | 455 | } else if (newIndex > 250) |
464 | newIndex = 250; | 456 | newIndex = 250; |
465 | newName[newIndex++] = CRC_MARK; | 457 | newName[newIndex++] = CRC_MARK; |
466 | valueCRC = udf_crc(fidName, fidNameLen, 0); | 458 | valueCRC = crc_itu_t(0, fidName, fidNameLen); |
467 | newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12]; | 459 | newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12]; |
468 | newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8]; | 460 | newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8]; |
469 | newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4]; | 461 | newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4]; |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index b3d9ccde0c27..34624835d90f 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -150,6 +150,7 @@ header-y += tiocl.h | |||
150 | header-y += tipc.h | 150 | header-y += tipc.h |
151 | header-y += tipc_config.h | 151 | header-y += tipc_config.h |
152 | header-y += toshiba.h | 152 | header-y += toshiba.h |
153 | header-y += udf_fs_i.h | ||
153 | header-y += ultrasound.h | 154 | header-y += ultrasound.h |
154 | header-y += un.h | 155 | header-y += un.h |
155 | header-y += utime.h | 156 | header-y += utime.h |
@@ -334,7 +335,6 @@ unifdef-y += time.h | |||
334 | unifdef-y += timex.h | 335 | unifdef-y += timex.h |
335 | unifdef-y += tty.h | 336 | unifdef-y += tty.h |
336 | unifdef-y += types.h | 337 | unifdef-y += types.h |
337 | unifdef-y += udf_fs_i.h | ||
338 | unifdef-y += udp.h | 338 | unifdef-y += udp.h |
339 | unifdef-y += uinput.h | 339 | unifdef-y += uinput.h |
340 | unifdef-y += uio.h | 340 | unifdef-y += uio.h |
diff --git a/include/linux/udf_fs.h b/include/linux/udf_fs.h deleted file mode 100644 index aa88654eb76b..000000000000 --- a/include/linux/udf_fs.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | * udf_fs.h | ||
3 | * | ||
4 | * PURPOSE | ||
5 | * Included by fs/filesystems.c | ||
6 | * | ||
7 | * DESCRIPTION | ||
8 | * OSTA-UDF(tm) = Optical Storage Technology Association | ||
9 | * Universal Disk Format. | ||
10 | * | ||
11 | * This code is based on version 2.50 of the UDF specification, | ||
12 | * and revision 3 of the ECMA 167 standard [equivalent to ISO 13346]. | ||
13 | * http://www.osta.org/ * http://www.ecma.ch/ | ||
14 | * http://www.iso.org/ | ||
15 | * | ||
16 | * COPYRIGHT | ||
17 | * This file is distributed under the terms of the GNU General Public | ||
18 | * License (GPL). Copies of the GPL can be obtained from: | ||
19 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | ||
20 | * Each contributing author retains all rights to their own work. | ||
21 | * | ||
22 | * (C) 1999-2004 Ben Fennema | ||
23 | * (C) 1999-2000 Stelias Computing Inc | ||
24 | * | ||
25 | * HISTORY | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #ifndef _UDF_FS_H | ||
30 | #define _UDF_FS_H 1 | ||
31 | |||
32 | #define UDF_PREALLOCATE | ||
33 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 | ||
34 | |||
35 | #undef UDFFS_DEBUG | ||
36 | |||
37 | #ifdef UDFFS_DEBUG | ||
38 | #define udf_debug(f, a...) \ | ||
39 | do { \ | ||
40 | printk (KERN_DEBUG "UDF-fs DEBUG %s:%d:%s: ", \ | ||
41 | __FILE__, __LINE__, __FUNCTION__); \ | ||
42 | printk (f, ##a); \ | ||
43 | } while (0) | ||
44 | #else | ||
45 | #define udf_debug(f, a...) /**/ | ||
46 | #endif | ||
47 | |||
48 | #define udf_info(f, a...) \ | ||
49 | printk (KERN_INFO "UDF-fs INFO " f, ##a); | ||
50 | |||
51 | #endif /* _UDF_FS_H */ | ||
diff --git a/include/linux/udf_fs_i.h b/include/linux/udf_fs_i.h index ffaf05679ffb..3536965913b0 100644 --- a/include/linux/udf_fs_i.h +++ b/include/linux/udf_fs_i.h | |||
@@ -9,41 +9,10 @@ | |||
9 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | 9 | * ftp://prep.ai.mit.edu/pub/gnu/GPL |
10 | * Each contributing author retains all rights to their own work. | 10 | * Each contributing author retains all rights to their own work. |
11 | */ | 11 | */ |
12 | |||
13 | #ifndef _UDF_FS_I_H | 12 | #ifndef _UDF_FS_I_H |
14 | #define _UDF_FS_I_H 1 | 13 | #define _UDF_FS_I_H 1 |
15 | 14 | ||
16 | #ifdef __KERNEL__ | ||
17 | |||
18 | struct udf_inode_info | ||
19 | { | ||
20 | struct timespec i_crtime; | ||
21 | /* Physical address of inode */ | ||
22 | kernel_lb_addr i_location; | ||
23 | __u64 i_unique; | ||
24 | __u32 i_lenEAttr; | ||
25 | __u32 i_lenAlloc; | ||
26 | __u64 i_lenExtents; | ||
27 | __u32 i_next_alloc_block; | ||
28 | __u32 i_next_alloc_goal; | ||
29 | unsigned i_alloc_type : 3; | ||
30 | unsigned i_efe : 1; | ||
31 | unsigned i_use : 1; | ||
32 | unsigned i_strat4096 : 1; | ||
33 | unsigned reserved : 26; | ||
34 | union | ||
35 | { | ||
36 | short_ad *i_sad; | ||
37 | long_ad *i_lad; | ||
38 | __u8 *i_data; | ||
39 | } i_ext; | ||
40 | struct inode vfs_inode; | ||
41 | }; | ||
42 | |||
43 | #endif | ||
44 | |||
45 | /* exported IOCTLs, we have 'l', 0x40-0x7f */ | 15 | /* exported IOCTLs, we have 'l', 0x40-0x7f */ |
46 | |||
47 | #define UDF_GETEASIZE _IOR('l', 0x40, int) | 16 | #define UDF_GETEASIZE _IOR('l', 0x40, int) |
48 | #define UDF_GETEABLOCK _IOR('l', 0x41, void *) | 17 | #define UDF_GETEABLOCK _IOR('l', 0x41, void *) |
49 | #define UDF_GETVOLIDENT _IOR('l', 0x42, void *) | 18 | #define UDF_GETVOLIDENT _IOR('l', 0x42, void *) |
diff --git a/include/linux/udf_fs_sb.h b/include/linux/udf_fs_sb.h deleted file mode 100644 index 9bc47352b6b4..000000000000 --- a/include/linux/udf_fs_sb.h +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | /* | ||
2 | * udf_fs_sb.h | ||
3 | * | ||
4 | * This include file is for the Linux kernel/module. | ||
5 | * | ||
6 | * COPYRIGHT | ||
7 | * This file is distributed under the terms of the GNU General Public | ||
8 | * License (GPL). Copies of the GPL can be obtained from: | ||
9 | * ftp://prep.ai.mit.edu/pub/gnu/GPL | ||
10 | * Each contributing author retains all rights to their own work. | ||
11 | */ | ||
12 | |||
13 | #ifndef _UDF_FS_SB_H | ||
14 | #define _UDF_FS_SB_H 1 | ||
15 | |||
16 | #include <linux/mutex.h> | ||
17 | |||
18 | #pragma pack(1) | ||
19 | |||
20 | #define UDF_MAX_BLOCK_LOADED 8 | ||
21 | |||
22 | #define UDF_TYPE1_MAP15 0x1511U | ||
23 | #define UDF_VIRTUAL_MAP15 0x1512U | ||
24 | #define UDF_VIRTUAL_MAP20 0x2012U | ||
25 | #define UDF_SPARABLE_MAP15 0x1522U | ||
26 | |||
27 | struct udf_sparing_data | ||
28 | { | ||
29 | __u16 s_packet_len; | ||
30 | struct buffer_head *s_spar_map[4]; | ||
31 | }; | ||
32 | |||
33 | struct udf_virtual_data | ||
34 | { | ||
35 | __u32 s_num_entries; | ||
36 | __u16 s_start_offset; | ||
37 | }; | ||
38 | |||
39 | struct udf_bitmap | ||
40 | { | ||
41 | __u32 s_extLength; | ||
42 | __u32 s_extPosition; | ||
43 | __u16 s_nr_groups; | ||
44 | struct buffer_head **s_block_bitmap; | ||
45 | }; | ||
46 | |||
47 | struct udf_part_map | ||
48 | { | ||
49 | union | ||
50 | { | ||
51 | struct udf_bitmap *s_bitmap; | ||
52 | struct inode *s_table; | ||
53 | } s_uspace; | ||
54 | union | ||
55 | { | ||
56 | struct udf_bitmap *s_bitmap; | ||
57 | struct inode *s_table; | ||
58 | } s_fspace; | ||
59 | __u32 s_partition_root; | ||
60 | __u32 s_partition_len; | ||
61 | __u16 s_partition_type; | ||
62 | __u16 s_partition_num; | ||
63 | union | ||
64 | { | ||
65 | struct udf_sparing_data s_sparing; | ||
66 | struct udf_virtual_data s_virtual; | ||
67 | } s_type_specific; | ||
68 | __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32); | ||
69 | __u16 s_volumeseqnum; | ||
70 | __u16 s_partition_flags; | ||
71 | }; | ||
72 | |||
73 | #pragma pack() | ||
74 | |||
75 | struct udf_sb_info | ||
76 | { | ||
77 | struct udf_part_map *s_partmaps; | ||
78 | __u8 s_volume_ident[32]; | ||
79 | |||
80 | /* Overall info */ | ||
81 | __u16 s_partitions; | ||
82 | __u16 s_partition; | ||
83 | |||
84 | /* Sector headers */ | ||
85 | __s32 s_session; | ||
86 | __u32 s_anchor[4]; | ||
87 | __u32 s_last_block; | ||
88 | |||
89 | struct buffer_head *s_lvid_bh; | ||
90 | |||
91 | /* Default permissions */ | ||
92 | mode_t s_umask; | ||
93 | gid_t s_gid; | ||
94 | uid_t s_uid; | ||
95 | |||
96 | /* Root Info */ | ||
97 | struct timespec s_record_time; | ||
98 | |||
99 | /* Fileset Info */ | ||
100 | __u16 s_serial_number; | ||
101 | |||
102 | /* highest UDF revision we have recorded to this media */ | ||
103 | __u16 s_udfrev; | ||
104 | |||
105 | /* Miscellaneous flags */ | ||
106 | __u32 s_flags; | ||
107 | |||
108 | /* Encoding info */ | ||
109 | struct nls_table *s_nls_map; | ||
110 | |||
111 | /* VAT inode */ | ||
112 | struct inode *s_vat_inode; | ||
113 | |||
114 | struct mutex s_alloc_mutex; | ||
115 | }; | ||
116 | |||
117 | #endif /* _UDF_FS_SB_H */ | ||