aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/directory.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/directory.c')
-rw-r--r--fs/udf/directory.c173
1 files changed, 75 insertions, 98 deletions
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 198caa33027a..ff8c08fd7bf5 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -19,10 +19,10 @@
19#include <linux/buffer_head.h> 19#include <linux/buffer_head.h>
20 20
21#if 0 21#if 0
22static uint8_t * 22static uint8_t *udf_filead_read(struct inode *dir, uint8_t * tmpad,
23udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size, 23 uint8_t ad_size, kernel_lb_addr fe_loc,
24 kernel_lb_addr fe_loc, int *pos, int *offset, 24 int *pos, int *offset, struct buffer_head **bh,
25 struct buffer_head **bh, int *error) 25 int *error)
26{ 26{
27 int loffset = *offset; 27 int loffset = *offset;
28 int block; 28 int block;
@@ -34,24 +34,20 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
34 ad = (uint8_t *)(*bh)->b_data + *offset; 34 ad = (uint8_t *)(*bh)->b_data + *offset;
35 *offset += ad_size; 35 *offset += ad_size;
36 36
37 if (!ad) 37 if (!ad) {
38 {
39 brelse(*bh); 38 brelse(*bh);
40 *error = 1; 39 *error = 1;
41 return NULL; 40 return NULL;
42 } 41 }
43 42
44 if (*offset == dir->i_sb->s_blocksize) 43 if (*offset == dir->i_sb->s_blocksize) {
45 {
46 brelse(*bh); 44 brelse(*bh);
47 block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos); 45 block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
48 if (!block) 46 if (!block)
49 return NULL; 47 return NULL;
50 if (!(*bh = udf_tread(dir->i_sb, block))) 48 if (!(*bh = udf_tread(dir->i_sb, block)))
51 return NULL; 49 return NULL;
52 } 50 } else if (*offset > dir->i_sb->s_blocksize) {
53 else if (*offset > dir->i_sb->s_blocksize)
54 {
55 ad = tmpad; 51 ad = tmpad;
56 52
57 remainder = dir->i_sb->s_blocksize - loffset; 53 remainder = dir->i_sb->s_blocksize - loffset;
@@ -67,53 +63,51 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
67 memcpy((uint8_t *)ad + remainder, (*bh)->b_data, ad_size - remainder); 63 memcpy((uint8_t *)ad + remainder, (*bh)->b_data, ad_size - remainder);
68 *offset = ad_size - remainder; 64 *offset = ad_size - remainder;
69 } 65 }
66
70 return ad; 67 return ad;
71} 68}
72#endif 69#endif
73 70
74struct fileIdentDesc * 71struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t * nf_pos,
75udf_fileident_read(struct inode *dir, loff_t *nf_pos, 72 struct udf_fileident_bh *fibh,
76 struct udf_fileident_bh *fibh, 73 struct fileIdentDesc *cfi,
77 struct fileIdentDesc *cfi, 74 struct extent_position *epos,
78 struct extent_position *epos, 75 kernel_lb_addr * eloc, uint32_t * elen,
79 kernel_lb_addr *eloc, uint32_t *elen, 76 sector_t * offset)
80 sector_t *offset)
81{ 77{
82 struct fileIdentDesc *fi; 78 struct fileIdentDesc *fi;
83 int i, num, block; 79 int i, num, block;
84 struct buffer_head * tmp, * bha[16]; 80 struct buffer_head *tmp, *bha[16];
85 81
86 fibh->soffset = fibh->eoffset; 82 fibh->soffset = fibh->eoffset;
87 83
88 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 84 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
89 {
90 fi = udf_get_fileident(UDF_I_DATA(dir) - 85 fi = udf_get_fileident(UDF_I_DATA(dir) -
91 (UDF_I_EFE(dir) ? 86 (UDF_I_EFE(dir) ?
92 sizeof(struct extendedFileEntry) : 87 sizeof(struct extendedFileEntry) :
93 sizeof(struct fileEntry)), 88 sizeof(struct fileEntry)),
94 dir->i_sb->s_blocksize, &(fibh->eoffset)); 89 dir->i_sb->s_blocksize, &(fibh->eoffset));
95
96 if (!fi) 90 if (!fi)
97 return NULL; 91 return NULL;
98 92
99 *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2); 93 *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
100 94
101 memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc)); 95 memcpy((uint8_t *)cfi, (uint8_t *)fi,
96 sizeof(struct fileIdentDesc));
102 97
103 return fi; 98 return fi;
104 } 99 }
105 100
106 if (fibh->eoffset == dir->i_sb->s_blocksize) 101 if (fibh->eoffset == dir->i_sb->s_blocksize) {
107 {
108 int lextoffset = epos->offset; 102 int lextoffset = epos->offset;
109 103
110 if (udf_next_aext(dir, epos, eloc, elen, 1) != 104 if (udf_next_aext(dir, epos, eloc, elen, 1) !=
111 (EXT_RECORDED_ALLOCATED >> 30)) 105 (EXT_RECORDED_ALLOCATED >> 30))
112 return NULL; 106 return NULL;
113 107
114 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); 108 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
115 109
116 (*offset) ++; 110 (*offset)++;
117 111
118 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) 112 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
119 *offset = 0; 113 *offset = 0;
@@ -125,57 +119,50 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
125 return NULL; 119 return NULL;
126 fibh->soffset = fibh->eoffset = 0; 120 fibh->soffset = fibh->eoffset = 0;
127 121
128 if (!(*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1))) 122 if (!(*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) {
129 {
130 i = 16 >> (dir->i_sb->s_blocksize_bits - 9); 123 i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
131 if (i+*offset > (*elen >> dir->i_sb->s_blocksize_bits)) 124 if (i + *offset > (*elen >> dir->i_sb->s_blocksize_bits))
132 i = (*elen >> dir->i_sb->s_blocksize_bits)-*offset; 125 i = (*elen >> dir->i_sb->s_blocksize_bits)-*offset;
133 for (num=0; i>0; i--) 126 for (num = 0; i > 0; i--) {
134 { 127 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset + i);
135 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset+i);
136 tmp = udf_tgetblk(dir->i_sb, block); 128 tmp = udf_tgetblk(dir->i_sb, block);
137 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) 129 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
138 bha[num++] = tmp; 130 bha[num++] = tmp;
139 else 131 else
140 brelse(tmp); 132 brelse(tmp);
141 } 133 }
142 if (num) 134 if (num) {
143 {
144 ll_rw_block(READA, num, bha); 135 ll_rw_block(READA, num, bha);
145 for (i=0; i<num; i++) 136 for (i = 0; i < num; i++)
146 brelse(bha[i]); 137 brelse(bha[i]);
147 } 138 }
148 } 139 }
149 } 140 } else if (fibh->sbh != fibh->ebh) {
150 else if (fibh->sbh != fibh->ebh)
151 {
152 brelse(fibh->sbh); 141 brelse(fibh->sbh);
153 fibh->sbh = fibh->ebh; 142 fibh->sbh = fibh->ebh;
154 } 143 }
155 144
156 fi = udf_get_fileident(fibh->sbh->b_data, dir->i_sb->s_blocksize, 145 fi = udf_get_fileident(fibh->sbh->b_data, dir->i_sb->s_blocksize,
157 &(fibh->eoffset)); 146 &(fibh->eoffset));
158 147
159 if (!fi) 148 if (!fi)
160 return NULL; 149 return NULL;
161 150
162 *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2); 151 *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
163 152
164 if (fibh->eoffset <= dir->i_sb->s_blocksize) 153 if (fibh->eoffset <= dir->i_sb->s_blocksize) {
165 { 154 memcpy((uint8_t *)cfi, (uint8_t *)fi,
166 memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc)); 155 sizeof(struct fileIdentDesc));
167 } 156 } else if (fibh->eoffset > dir->i_sb->s_blocksize) {
168 else if (fibh->eoffset > dir->i_sb->s_blocksize)
169 {
170 int lextoffset = epos->offset; 157 int lextoffset = epos->offset;
171 158
172 if (udf_next_aext(dir, epos, eloc, elen, 1) != 159 if (udf_next_aext(dir, epos, eloc, elen, 1) !=
173 (EXT_RECORDED_ALLOCATED >> 30)) 160 (EXT_RECORDED_ALLOCATED >> 30))
174 return NULL; 161 return NULL;
175 162
176 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); 163 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
177 164
178 (*offset) ++; 165 (*offset)++;
179 166
180 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) 167 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
181 *offset = 0; 168 *offset = 0;
@@ -188,62 +175,59 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
188 if (!(fibh->ebh = udf_tread(dir->i_sb, block))) 175 if (!(fibh->ebh = udf_tread(dir->i_sb, block)))
189 return NULL; 176 return NULL;
190 177
191 if (sizeof(struct fileIdentDesc) > - fibh->soffset) 178 if (sizeof(struct fileIdentDesc) > -fibh->soffset) {
192 {
193 int fi_len; 179 int fi_len;
194 180
195 memcpy((uint8_t *)cfi, (uint8_t *)fi, - fibh->soffset); 181 memcpy((uint8_t *)cfi, (uint8_t *)fi, -fibh->soffset);
196 memcpy((uint8_t *)cfi - fibh->soffset, fibh->ebh->b_data, 182 memcpy((uint8_t *)cfi - fibh->soffset, fibh->ebh->b_data,
197 sizeof(struct fileIdentDesc) + fibh->soffset); 183 sizeof(struct fileIdentDesc) + fibh->soffset);
198 184
199 fi_len = (sizeof(struct fileIdentDesc) + cfi->lengthFileIdent + 185 fi_len = (sizeof(struct fileIdentDesc) + cfi->lengthFileIdent +
200 le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3; 186 le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
201 187
202 *nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2); 188 *nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
203 fibh->eoffset = fibh->soffset + fi_len; 189 fibh->eoffset = fibh->soffset + fi_len;
204 } 190 } else {
205 else 191 memcpy((uint8_t *)cfi, (uint8_t *)fi,
206 { 192 sizeof(struct fileIdentDesc));
207 memcpy((uint8_t *)cfi, (uint8_t *)fi, sizeof(struct fileIdentDesc));
208 } 193 }
209 } 194 }
210 return fi; 195 return fi;
211} 196}
212 197
213struct fileIdentDesc * 198struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset)
214udf_get_fileident(void * buffer, int bufsize, int * offset)
215{ 199{
216 struct fileIdentDesc *fi; 200 struct fileIdentDesc *fi;
217 int lengthThisIdent; 201 int lengthThisIdent;
218 uint8_t * ptr; 202 uint8_t *ptr;
219 int padlen; 203 int padlen;
220 204
221 if ( (!buffer) || (!offset) ) { 205 if ((!buffer) || (!offset)) {
222 udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer, offset); 206 udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer,
207 offset);
223 return NULL; 208 return NULL;
224 } 209 }
225 210
226 ptr = buffer; 211 ptr = buffer;
227 212
228 if ( (*offset > 0) && (*offset < bufsize) ) { 213 if ((*offset > 0) && (*offset < bufsize)) {
229 ptr += *offset; 214 ptr += *offset;
230 } 215 }
231 fi=(struct fileIdentDesc *)ptr; 216 fi = (struct fileIdentDesc *)ptr;
232 if (le16_to_cpu(fi->descTag.tagIdent) != TAG_IDENT_FID) 217 if (le16_to_cpu(fi->descTag.tagIdent) != TAG_IDENT_FID) {
233 {
234 udf_debug("0x%x != TAG_IDENT_FID\n", 218 udf_debug("0x%x != TAG_IDENT_FID\n",
235 le16_to_cpu(fi->descTag.tagIdent)); 219 le16_to_cpu(fi->descTag.tagIdent));
236 udf_debug("offset: %u sizeof: %lu bufsize: %u\n", 220 udf_debug("offset: %u sizeof: %lu bufsize: %u\n",
237 *offset, (unsigned long)sizeof(struct fileIdentDesc), bufsize); 221 *offset, (unsigned long)sizeof(struct fileIdentDesc),
222 bufsize);
238 return NULL; 223 return NULL;
239 } 224 }
240 if ( (*offset + sizeof(struct fileIdentDesc)) > bufsize ) 225 if ((*offset + sizeof(struct fileIdentDesc)) > bufsize) {
241 {
242 lengthThisIdent = sizeof(struct fileIdentDesc); 226 lengthThisIdent = sizeof(struct fileIdentDesc);
243 } 227 } else {
244 else
245 lengthThisIdent = sizeof(struct fileIdentDesc) + 228 lengthThisIdent = sizeof(struct fileIdentDesc) +
246 fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse); 229 fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
230 }
247 231
248 /* we need to figure padding, too! */ 232 /* we need to figure padding, too! */
249 padlen = lengthThisIdent % UDF_NAME_PAD; 233 padlen = lengthThisIdent % UDF_NAME_PAD;
@@ -255,32 +239,28 @@ udf_get_fileident(void * buffer, int bufsize, int * offset)
255} 239}
256 240
257#if 0 241#if 0
258static extent_ad * 242static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
259udf_get_fileextent(void * buffer, int bufsize, int * offset)
260{ 243{
261 extent_ad * ext; 244 extent_ad *ext;
262 struct fileEntry *fe; 245 struct fileEntry *fe;
263 uint8_t * ptr; 246 uint8_t *ptr;
264 247
265 if ( (!buffer) || (!offset) ) 248 if ((!buffer) || (!offset)) {
266 {
267 printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n"); 249 printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
268 return NULL; 250 return NULL;
269 } 251 }
270 252
271 fe = (struct fileEntry *)buffer; 253 fe = (struct fileEntry *)buffer;
272 254
273 if ( le16_to_cpu(fe->descTag.tagIdent) != TAG_IDENT_FE ) 255 if (le16_to_cpu(fe->descTag.tagIdent) != TAG_IDENT_FE) {
274 {
275 udf_debug("0x%x != TAG_IDENT_FE\n", 256 udf_debug("0x%x != TAG_IDENT_FE\n",
276 le16_to_cpu(fe->descTag.tagIdent)); 257 le16_to_cpu(fe->descTag.tagIdent));
277 return NULL; 258 return NULL;
278 } 259 }
279 260
280 ptr=(uint8_t *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr); 261 ptr = (uint8_t *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr);
281 262
282 if ( (*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)) ) 263 if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs))) {
283 {
284 ptr += *offset; 264 ptr += *offset;
285 } 265 }
286 266
@@ -291,18 +271,17 @@ udf_get_fileextent(void * buffer, int bufsize, int * offset)
291} 271}
292#endif 272#endif
293 273
294short_ad * 274short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset,
295udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset, int inc) 275 int inc)
296{ 276{
297 short_ad *sa; 277 short_ad *sa;
298 278
299 if ( (!ptr) || (!offset) ) 279 if ((!ptr) || (!offset)) {
300 {
301 printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n"); 280 printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
302 return NULL; 281 return NULL;
303 } 282 }
304 283
305 if ( (*offset < 0) || ((*offset + sizeof(short_ad)) > maxoffset) ) 284 if ((*offset < 0) || ((*offset + sizeof(short_ad)) > maxoffset))
306 return NULL; 285 return NULL;
307 else if ((sa = (short_ad *)ptr)->extLength == 0) 286 else if ((sa = (short_ad *)ptr)->extLength == 0)
308 return NULL; 287 return NULL;
@@ -312,18 +291,16 @@ udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset, int inc)
312 return sa; 291 return sa;
313} 292}
314 293
315long_ad * 294long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, int *offset, int inc)
316udf_get_filelongad(uint8_t *ptr, int maxoffset, int * offset, int inc)
317{ 295{
318 long_ad *la; 296 long_ad *la;
319 297
320 if ( (!ptr) || (!offset) ) 298 if ((!ptr) || (!offset)) {
321 {
322 printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n"); 299 printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
323 return NULL; 300 return NULL;
324 } 301 }
325 302
326 if ( (*offset < 0) || ((*offset + sizeof(long_ad)) > maxoffset) ) 303 if ((*offset < 0) || ((*offset + sizeof(long_ad)) > maxoffset))
327 return NULL; 304 return NULL;
328 else if ((la = (long_ad *)ptr)->extLength == 0) 305 else if ((la = (long_ad *)ptr)->extLength == 0)
329 return NULL; 306 return NULL;