OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [udf/] [partition.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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@hpesjro.fc.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-2001 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/slab.h>
34
 
35
inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t 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_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
50
{
51
        struct buffer_head *bh = NULL;
52
        uint32_t newblock;
53
        uint32_t index;
54
        uint32_t loc;
55
 
56
        index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t);
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_t)));
69
                index = block % (sb->s_blocksize / sizeof(uint32_t));
70
        }
71
        else
72
        {
73
                newblock = 0;
74
                index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block;
75
        }
76
 
77
        loc = udf_block_map(UDF_SB_VAT(sb), newblock);
78
 
79
        if (!(bh = sb_bread(sb, loc)))
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_t *)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_t udf_get_pblock_virt20(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
100
{
101
        return udf_get_pblock_virt15(sb, block, partition, offset);
102
}
103
 
104
uint32_t udf_get_pblock_spar15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset)
105
{
106
        int i;
107
        struct sparingTable *st = NULL;
108
        uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1);
109
 
110
        for (i=0; i<4; i++)
111
        {
112
                if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL)
113
                {
114
                        st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data;
115
                        break;
116
                }
117
        }
118
 
119
        if (st)
120
        {
121
                for (i=0; i<st->reallocationTableLen; i++)
122
                {
123
                        if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0)
124
                                break;
125
                        else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet)
126
                        {
127
                                return le32_to_cpu(st->mapEntry[i].mappedLocation) +
128
                                        ((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1));
129
                        }
130
                        else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet)
131
                                break;
132
                }
133
        }
134
        return UDF_SB_PARTROOT(sb,partition) + block + offset;
135
}
136
 
137
int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
138
{
139
        struct udf_sparing_data *sdata;
140
        struct sparingTable *st = NULL;
141
        struct sparingEntry mapEntry;
142
        uint32_t packet;
143
        int i, j, k, l;
144
 
145
        for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
146
        {
147
                if (old_block > UDF_SB_PARTROOT(sb,i) &&
148
                    old_block < UDF_SB_PARTROOT(sb,i) + UDF_SB_PARTLEN(sb,i))
149
                {
150
                        sdata = &UDF_SB_TYPESPAR(sb,i);
151
                        packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1);
152
 
153
                        for (j=0; j<4; j++)
154
                        {
155
                                if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
156
                                {
157
                                        st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
158
                                        break;
159
                                }
160
                        }
161
 
162
                        if (!st)
163
                                return 1;
164
 
165
                        for (k=0; k<st->reallocationTableLen; k++)
166
                        {
167
                                if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF)
168
                                {
169
                                        for (; j<4; j++)
170
                                        {
171
                                                if (sdata->s_spar_map[j])
172
                                                {
173
                                                        st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
174
                                                        st->mapEntry[k].origLocation = cpu_to_le32(packet);
175
                                                        udf_update_tag((char *)st, sizeof(struct sparingTable) + st->reallocationTableLen * sizeof(struct sparingEntry));
176
                                                        mark_buffer_dirty(sdata->s_spar_map[j]);
177
                                                }
178
                                        }
179
                                        *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
180
                                                ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
181
                                        return 0;
182
                                }
183
                                else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet)
184
                                {
185
                                        *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
186
                                                ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
187
                                        return 0;
188
                                }
189
                                else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet)
190
                                        break;
191
                        }
192
                        for (l=k; l<st->reallocationTableLen; l++)
193
                        {
194
                                if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF)
195
                                {
196
                                        for (; j<4; j++)
197
                                        {
198
                                                if (sdata->s_spar_map[j])
199
                                                {
200
                                                        st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
201
                                                        mapEntry = st->mapEntry[l];
202
                                                        mapEntry.origLocation = cpu_to_le32(packet);
203
                                                        memmove(&st->mapEntry[k+1], &st->mapEntry[k], (l-k)*sizeof(struct sparingEntry));
204
                                                        st->mapEntry[k] = mapEntry;
205
                                                        udf_update_tag((char *)st, sizeof(struct sparingTable) + st->reallocationTableLen * sizeof(struct sparingEntry));
206
                                                        mark_buffer_dirty(sdata->s_spar_map[j]);
207
                                                }
208
                                        }
209
                                        *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
210
                                                ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
211
                                        return 0;
212
                                }
213
                        }
214
                        return 1;
215
                }
216
        }
217
        if (i == UDF_SB_NUMPARTS(sb))
218
        {
219
                /* outside of partitions */
220
                /* for now, fail =) */
221
                return 1;
222
        }
223
 
224
        return 0;
225
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.