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

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

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

  1 /*
  2  * partition.c
  3  *
  4  * PURPOSE
  5  *      Partition handling routines for the OSTA-UDF(tm) filesystem.
  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  *  (C) 1998-2000 Ben Fennema
 19  *
 20  * HISTORY
 21  *
 22  * 12/06/98 blf  Created file. 
 23  *
 24  */
 25 
 26 #include "udfdecl.h"
 27 #include "udf_sb.h"
 28 #include "udf_i.h"
 29 
 30 #include <linux/fs.h>
 31 #include <linux/string.h>
 32 #include <linux/udf_fs.h>
 33 #include <linux/malloc.h>
 34 
 35 inline Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
 36 {
 37         if (partition >= UDF_SB_NUMPARTS(sb))
 38         {
 39                 udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n",
 40                         block, partition, offset);
 41                 return 0xFFFFFFFF;
 42         }
 43         if (UDF_SB_PARTFUNC(sb, partition))
 44                 return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset);
 45         else
 46                 return UDF_SB_PARTROOT(sb, partition) + block + offset;
 47 }
 48 
 49 Uint32 udf_get_pblock_virt15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
 50 {
 51         struct buffer_head *bh = NULL;
 52         Uint32 newblock;
 53         Uint32 index;
 54         Uint32 loc;
 55 
 56         index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(Uint32);
 57 
 58         if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries)
 59         {
 60                 udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
 61                         block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries);
 62                 return 0xFFFFFFFF;
 63         }
 64 
 65         if (block >= index)
 66         {
 67                 block -= index;
 68                 newblock = 1 + (block / (sb->s_blocksize / sizeof(Uint32)));
 69                 index = block % (sb->s_blocksize / sizeof(Uint32));
 70         }
 71         else
 72         {
 73                 newblock = 0;
 74                 index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block;
 75         }
 76 
 77         loc = udf_locked_block_map(UDF_SB_VAT(sb), newblock);
 78 
 79         if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize)))
 80         {
 81                 udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
 82                         sb, block, partition, loc, index);
 83                 return 0xFFFFFFFF;
 84         }
 85 
 86         loc = le32_to_cpu(((Uint32 *)bh->b_data)[index]);
 87 
 88         udf_release_data(bh);
 89 
 90         if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
 91         {
 92                 udf_debug("recursive call to udf_get_pblock!\n");
 93                 return 0xFFFFFFFF;
 94         }
 95 
 96         return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset);
 97 }
 98 
 99 inline Uint32 udf_get_pblock_virt20(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
100 {
101         return udf_get_pblock_virt15(sb, block, partition, offset);
102 }
103 
104 Uint32 udf_get_pblock_spar15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
105 {
106         Uint32 packet = (block + offset) >> UDF_SB_TYPESPAR(sb,partition).s_spar_pshift;
107         Uint32 index = 0;
108 
109         if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 8)
110                 index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap8[packet];
111         else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 16)
112                 index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap16[packet];
113         else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 32)
114                 index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap32[packet];
115 
116         if (index == ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize)-1))
117                 return UDF_SB_PARTROOT(sb,partition) + block + offset;
118 
119         packet = UDF_SB_TYPESPAR(sb,partition).s_spar_map[index];
120         return packet + ((block + offset) & ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_pshift)-1));
121 }
122 
123 void udf_fill_spartable(struct super_block *sb, struct udf_sparing_data *sdata, int partlen)
124 {
125         Uint16 ident;
126         Uint32 spartable;
127         int i;
128         struct buffer_head *bh;
129         struct SparingTable *st;
130 
131         for (i=0; i<4; i++)
132         {
133                 if (!(spartable = sdata->s_spar_loc[i]))
134                         continue;
135 
136                 bh = udf_read_tagged(sb, spartable, spartable, &ident);
137 
138                 if (!bh)
139                 {
140                         sdata->s_spar_loc[i] = 0;
141                         continue;
142                 }
143 
144                 if (ident == 0)
145                 {
146                         st = (struct SparingTable *)bh->b_data;
147                         if (!strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
148                         {
149                                 SparingEntry *se;
150                                 Uint16 rtl = le16_to_cpu(st->reallocationTableLen);
151                                 int index;
152 
153                                 if (!sdata->s_spar_map)
154                                 {
155                                         int num = 1, mapsize;
156                                         sdata->s_spar_indexsize = 8;
157                                         while (rtl*sizeof(Uint32) >= (1 << sdata->s_spar_indexsize))
158                                         {
159                                                 num ++;
160                                                 sdata->s_spar_indexsize <<= 1;
161                                         }
162                                         mapsize = (rtl * sizeof(Uint32)) +
163                                                 ((partlen/(1 << sdata->s_spar_pshift)) * sizeof(Uint8) * num);
164                                         sdata->s_spar_map = kmalloc(mapsize, GFP_KERNEL);
165                                         sdata->s_spar_remap.s_spar_remap32 = &sdata->s_spar_map[rtl];
166                                         memset(sdata->s_spar_map, 0xFF, mapsize);
167                                 }
168 
169                                 index = sizeof(struct SparingTable);
170                                 for (i=0; i<rtl; i++)
171                                 {
172                                         if (index > sb->s_blocksize)
173                                         {
174                                                 udf_release_data(bh);
175                                                 bh = udf_tread(sb, ++spartable, sb->s_blocksize);
176                                                 if (!bh)
177                                                 {
178                                                         sdata->s_spar_loc[i] = 0;
179                                                         continue;
180                                                 }
181                                                 index = 0;
182                                         }
183                                         se = (SparingEntry *)&(bh->b_data[index]);
184                                         index += sizeof(SparingEntry);
185 
186                                         if (sdata->s_spar_map[i] == 0xFFFFFFFF)
187                                                 sdata->s_spar_map[i] = le32_to_cpu(se->mappedLocation);
188                                         else if (sdata->s_spar_map[i] != le32_to_cpu(se->mappedLocation))
189                                         {
190                                                 udf_debug("Found conflicting Sparing Data (%d vs %d for entry %d)\n",
191                                                         sdata->s_spar_map[i], le32_to_cpu(se->mappedLocation), i);
192                                         }
193 
194                                         if (le32_to_cpu(se->origLocation) < 0xFFFFFFF0)
195                                         {
196                                                 int packet = le32_to_cpu(se->origLocation) >> sdata->s_spar_pshift;
197                                                 if (sdata->s_spar_indexsize == 8)
198                                                 {
199                                                         if (sdata->s_spar_remap.s_spar_remap8[packet] == 0xFF)
200                                                                 sdata->s_spar_remap.s_spar_remap8[packet] = i;
201                                                         else if (sdata->s_spar_remap.s_spar_remap8[packet] != i)
202                                                         {
203                                                                 udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
204                                                                         sdata->s_spar_remap.s_spar_remap8[packet], i);
205                                                         }
206                                                 }
207                                                 else if (sdata->s_spar_indexsize == 16)
208                                                 {
209                                                         if (sdata->s_spar_remap.s_spar_remap16[packet] == 0xFFFF)
210                                                                 sdata->s_spar_remap.s_spar_remap16[packet] = i;
211                                                         else if (sdata->s_spar_remap.s_spar_remap16[packet] != i)
212                                                         {
213                                                                 udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
214                                                                         sdata->s_spar_remap.s_spar_remap16[packet], i);
215                                                         }
216                                                 }
217                                                 else if (sdata->s_spar_indexsize == 32)
218                                                 {
219                                                         if (sdata->s_spar_remap.s_spar_remap32[packet] == 0xFFFFFFFF)
220                                                                 sdata->s_spar_remap.s_spar_remap32[packet] = i;
221                                                         else if (sdata->s_spar_remap.s_spar_remap32[packet] != i)
222                                                         {
223                                                                 udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
224                                                                         sdata->s_spar_remap.s_spar_remap32[packet], i);
225                                                         }
226                                                 }
227                                         }
228                                 }
229                         }
230                 }
231                 udf_release_data(bh);
232         }
233 }
234 

~ [ 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.