~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/udf/directory.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * directory.c
  3  *
  4  * PURPOSE
  5  *      Directory related functions
  6  *
  7  * CONTACTS
  8  *      E-mail regarding any portion of the Linux UDF file system should be
  9  *      directed to the development team mailing list (run by majordomo):
 10  *              linux_udf@hootie.lvld.hp.com
 11  *
 12  * COPYRIGHT
 13  *      This file is distributed under the terms of the GNU General Public
 14  *      License (GPL). Copies of the GPL can be obtained from:
 15  *              ftp://prep.ai.mit.edu/pub/gnu/GPL
 16  *      Each contributing author retains all rights to their own work.
 17  */
 18 
 19 #include "udfdecl.h"
 20 
 21 #if defined(__linux__) && defined(__KERNEL__)
 22 
 23 #include <linux/fs.h>
 24 #include <linux/string.h>
 25 #include <linux/udf_fs.h>
 26 
 27 #else
 28 
 29 #include <sys/types.h>
 30 #include <stdio.h>
 31 #include <unistd.h>
 32 
 33 #endif
 34 
 35 #ifdef __KERNEL__
 36 
 37 Uint8 * udf_filead_read(struct inode *dir, Uint8 *tmpad, Uint8 ad_size,
 38         lb_addr fe_loc, int *pos, int *offset, struct buffer_head **bh, int *error)
 39 {
 40         int loffset = *offset;
 41         int block;
 42         Uint8 *ad;
 43         int remainder;
 44 
 45         *error = 0;
 46 
 47         ad = (Uint8 *)(*bh)->b_data + *offset;
 48         *offset += ad_size;
 49 
 50         if (!ad)
 51         {
 52                 udf_release_data(*bh);
 53                 *error = 1;
 54                 return NULL;
 55         }
 56 
 57         if (*offset == dir->i_sb->s_blocksize)
 58         {
 59                 udf_release_data(*bh);
 60                 block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
 61                 if (!block)
 62                         return NULL;
 63                 if (!(*bh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
 64                         return NULL;
 65         }
 66         else if (*offset > dir->i_sb->s_blocksize)
 67         {
 68                 ad = tmpad;
 69 
 70                 remainder = dir->i_sb->s_blocksize - loffset;
 71                 memcpy((Uint8 *)ad, (*bh)->b_data + loffset, remainder);
 72 
 73                 udf_release_data(*bh);
 74                 block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
 75                 if (!block)
 76                         return NULL;
 77                 if (!((*bh) = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
 78                         return NULL;
 79 
 80                 memcpy((Uint8 *)ad + remainder, (*bh)->b_data, ad_size - remainder);
 81                 *offset = ad_size - remainder;
 82         }
 83         return ad;
 84 }
 85 
 86 struct FileIdentDesc *
 87 udf_fileident_read(struct inode *dir, loff_t *nf_pos,
 88         struct udf_fileident_bh *fibh,
 89         struct FileIdentDesc *cfi,
 90         lb_addr *bloc, Uint32 *extoffset, 
 91         lb_addr *eloc, Uint32 *elen,
 92         Uint32 *offset, struct buffer_head **bh)
 93 {
 94         struct FileIdentDesc *fi;
 95         int block;
 96 
 97         fibh->soffset = fibh->eoffset;
 98 
 99         if (fibh->eoffset == dir->i_sb->s_blocksize)
100         {
101                 int lextoffset = *extoffset;
102 
103                 if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
104                         EXTENT_RECORDED_ALLOCATED)
105                 {
106                         return NULL;
107                 }
108 
109                 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
110 
111                 (*offset) ++;
112 
113                 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
114                         *offset = 0;
115                 else
116                         *extoffset = lextoffset;
117 
118                 udf_release_data(fibh->sbh);
119                 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
120                         return NULL;
121                 fibh->soffset = fibh->eoffset = 0;
122         }
123         else if (fibh->sbh != fibh->ebh)
124         {
125                 udf_release_data(fibh->sbh);
126                 fibh->sbh = fibh->ebh;
127         }
128 
129         fi = udf_get_fileident(fibh->sbh->b_data, dir->i_sb->s_blocksize,
130                 &(fibh->eoffset));
131 
132         if (!fi)
133                 return NULL;
134 
135         *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
136 
137         if (fibh->eoffset <= dir->i_sb->s_blocksize)
138         {
139                 memcpy((Uint8 *)cfi, (Uint8 *)fi, sizeof(struct FileIdentDesc));
140         }
141         else if (fibh->eoffset > dir->i_sb->s_blocksize)
142         {
143                 int lextoffset = *extoffset;
144 
145                 if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
146                         EXTENT_RECORDED_ALLOCATED)
147                 {
148                         return NULL;
149                 }
150 
151                 block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
152 
153                 (*offset) ++;
154 
155                 if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
156                         *offset = 0;
157                 else
158                         *extoffset = lextoffset;
159 
160                 fibh->soffset -= dir->i_sb->s_blocksize;
161                 fibh->eoffset -= dir->i_sb->s_blocksize;
162 
163                 if (!(fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
164                         return NULL;
165 
166                 if (sizeof(struct FileIdentDesc) > - fibh->soffset)
167                 {
168                         int fi_len;
169 
170                         memcpy((Uint8 *)cfi, (Uint8 *)fi, - fibh->soffset);
171                         memcpy((Uint8 *)cfi - fibh->soffset, fibh->ebh->b_data,
172                                 sizeof(struct FileIdentDesc) + fibh->soffset);
173 
174                         fi_len = (sizeof(struct FileIdentDesc) + cfi->lengthFileIdent +
175                                 le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
176 
177                         *nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
178                         fibh->eoffset = fibh->soffset + fi_len;
179                 }
180                 else
181                 {
182                         memcpy((Uint8 *)cfi, (Uint8 *)fi, sizeof(struct FileIdentDesc));
183                 }
184         }
185         return fi;
186 }
187 #endif
188 
189 struct FileIdentDesc * 
190 udf_get_fileident(void * buffer, int bufsize, int * offset)
191 {
192         struct FileIdentDesc *fi;
193         int lengthThisIdent;
194         Uint8 * ptr;
195         int padlen;
196 
197         if ( (!buffer) || (!offset) ) {
198 #ifdef __KERNEL__
199                 udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer, offset);
200 #endif
201                 return NULL;
202         }
203 
204         ptr = buffer;
205 
206         if ( (*offset > 0) && (*offset < bufsize) ) {
207                 ptr += *offset;
208         }
209         fi=(struct FileIdentDesc *)ptr;
210         if (le16_to_cpu(fi->descTag.tagIdent) != TID_FILE_IDENT_DESC)
211         {
212 #ifdef __KERNEL__
213                 udf_debug("0x%x != TID_FILE_IDENT_DESC\n",
214                         le16_to_cpu(fi->descTag.tagIdent));
215                 udf_debug("offset: %u sizeof: %lu bufsize: %u\n",
216                         *offset, (unsigned long)sizeof(struct FileIdentDesc), bufsize);
217 #endif
218                 return NULL;
219         }
220         if ( (*offset + sizeof(struct FileIdentDesc)) > bufsize )
221         {
222                 lengthThisIdent = sizeof(struct FileIdentDesc);
223         }
224         else
225                 lengthThisIdent = sizeof(struct FileIdentDesc) +
226                         fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
227 
228         /* we need to figure padding, too! */
229         padlen = lengthThisIdent % UDF_NAME_PAD;
230         if (padlen)
231                 lengthThisIdent += (UDF_NAME_PAD - padlen);
232         *offset = *offset + lengthThisIdent;
233 
234         return fi;
235 }
236 
237 extent_ad *
238 udf_get_fileextent(void * buffer, int bufsize, int * offset)
239 {
240         extent_ad * ext;
241         struct FileEntry *fe;
242         Uint8 * ptr;
243 
244         if ( (!buffer) || (!offset) )
245         {
246 #ifdef __KERNEL__
247                 printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
248 #endif
249                 return NULL;
250         }
251 
252         fe = (struct FileEntry *)buffer;
253 
254         if ( le16_to_cpu(fe->descTag.tagIdent) != TID_FILE_ENTRY )
255         {
256 #ifdef __KERNEL__
257                 udf_debug("0x%x != TID_FILE_ENTRY\n",
258                         le16_to_cpu(fe->descTag.tagIdent));
259 #endif
260                 return NULL;
261         }
262 
263         ptr=(Uint8 *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr);
264 
265         if ( (*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)) )
266         {
267                 ptr += *offset;
268         }
269 
270         ext = (extent_ad *)ptr;
271 
272         *offset = *offset + sizeof(extent_ad);
273         return ext;
274 }
275 
276 short_ad *
277 udf_get_fileshortad(void * buffer, int maxoffset, int *offset, int inc)
278 {
279         short_ad * sa;
280         Uint8 * ptr;
281 
282         if ( (!buffer) || (!offset) )
283         {
284 #ifdef __KERNEL__
285                 printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
286 #endif
287                 return NULL;
288         }
289 
290         ptr = (Uint8 *)buffer;
291 
292         if ( (*offset > 0) && (*offset < maxoffset) )
293                 ptr += *offset;
294         else
295                 return NULL;
296 
297         if ((sa = (short_ad *)ptr)->extLength == 0)
298                 return NULL;
299         else if (inc)
300                 (*offset) += sizeof(short_ad);
301         return sa;
302 }
303 
304 long_ad *
305 udf_get_filelongad(void * buffer, int maxoffset, int * offset, int inc)
306 {
307         long_ad * la;
308         Uint8 * ptr;
309 
310         if ( (!buffer) || !(offset) ) 
311         {
312 #ifdef __KERNEL__
313                 printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
314 #endif
315                 return NULL;
316         }
317 
318         ptr = (Uint8 *)buffer;
319 
320         if ( (*offset > 0) && (*offset < maxoffset) )
321                 ptr += *offset;
322         else
323                 return NULL;
324 
325         if ((la = (long_ad *)ptr)->extLength == 0)
326                 return NULL;
327         else if (inc)
328                 (*offset) += sizeof(long_ad);
329         return la;
330 }
331 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.