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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Copyright (c) 2000-2001 Christoph Hellwig.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions, and the following disclaimer,
10
 *    without modification.
11
 * 2. The name of the author may not be used to endorse or promote products
12
 *    derived from this software without specific prior written permission.
13
 *
14
 * Alternatively, this software may be distributed under the terms of the
15
 * GNU General Public License ("GPL").
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
 
30
#ident "$Id: vxfs_bmap.c,v 1.1.1.1 2004-04-15 01:11:45 phoenix Exp $"
31
 
32
/*
33
 * Veritas filesystem driver - filesystem to disk block mapping.
34
 */
35
#include <linux/fs.h>
36
#include <linux/kernel.h>
37
 
38
#include "vxfs.h"
39
#include "vxfs_inode.h"
40
 
41
 
42
#ifdef DIAGNOSTIC
43
static void
44
vxfs_typdump(struct vxfs_typed *typ)
45
{
46
        printk(KERN_DEBUG "type=%Lu ", typ->vt_hdr >> VXFS_TYPED_TYPESHIFT);
47
        printk("offset=%Lx ", typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
48
        printk("block=%x ", typ->vt_block);
49
        printk("size=%x\n", typ->vt_size);
50
}
51
#endif
52
 
53
/**
54
 * vxfs_bmap_ext4 - do bmap for ext4 extents
55
 * @ip:         pointer to the inode we do bmap for
56
 * @iblock:     logical block.
57
 *
58
 * Description:
59
 *   vxfs_bmap_ext4 performs the bmap operation for inodes with
60
 *   ext4-style extents (which are much like the traditional UNIX
61
 *   inode organisation).
62
 *
63
 * Returns:
64
 *   The physical block number on success, else Zero.
65
 */
66
static daddr_t
67
vxfs_bmap_ext4(struct inode *ip, long bn)
68
{
69
        struct super_block *sb = ip->i_sb;
70
        struct vxfs_inode_info *vip = VXFS_INO(ip);
71
        unsigned long bsize = sb->s_blocksize;
72
        u32 indsize = vip->vii_ext4.ve4_indsize;
73
        int i;
74
 
75
        if (indsize > sb->s_blocksize)
76
                goto fail_size;
77
 
78
        for (i = 0; i < VXFS_NDADDR; i++) {
79
                struct direct *d = vip->vii_ext4.ve4_direct + i;
80
                if (bn >= 0 && bn < d->size)
81
                        return (bn + d->extent);
82
                bn -= d->size;
83
        }
84
 
85
        if ((bn / (indsize * indsize * bsize / 4)) == 0) {
86
                struct buffer_head *buf;
87
                daddr_t bno;
88
                u32 *indir;
89
 
90
                buf = sb_bread(sb, vip->vii_ext4.ve4_indir[0]);
91
                if (!buf || !buffer_mapped(buf))
92
                        goto fail_buf;
93
 
94
                indir = (u32 *)buf->b_data;
95
                bno = indir[(bn/indsize) % (indsize*bn)] + (bn%indsize);
96
 
97
                brelse(buf);
98
                return bno;
99
        } else
100
                printk(KERN_WARNING "no matching indir?");
101
 
102
        return 0;
103
 
104
fail_size:
105
        printk("vxfs: indirect extent to big!\n");
106
fail_buf:
107
        return 0;
108
}
109
 
110
/**
111
 * vxfs_bmap_indir - recursion for vxfs_bmap_typed
112
 * @ip:         pointer to the inode we do bmap for
113
 * @indir:      indirect block we start reading at
114
 * @size:       size of the typed area to search
115
 * @block:      partially result from further searches
116
 *
117
 * Description:
118
 *   vxfs_bmap_indir reads a &struct vxfs_typed at @indir
119
 *   and performs the type-defined action.
120
 *
121
 * Return Value:
122
 *   The physical block number on success, else Zero.
123
 *
124
 * Note:
125
 *   Kernelstack is rare.  Unrecurse?
126
 */
127
static daddr_t
128
vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
129
{
130
        struct buffer_head              *bp = NULL;
131
        daddr_t                         pblock = 0;
132
        int                             i;
133
 
134
        for (i = 0; i < size * VXFS_TYPED_PER_BLOCK(ip->i_sb); i++) {
135
                struct vxfs_typed       *typ;
136
                int64_t                 off;
137
 
138
                bp = sb_bread(ip->i_sb,
139
                                indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)));
140
                if (!buffer_mapped(bp))
141
                        return 0;
142
 
143
                typ = ((struct vxfs_typed *)bp->b_data) +
144
                        (i % VXFS_TYPED_PER_BLOCK(ip->i_sb));
145
                off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
146
 
147
                if (block < off) {
148
                        brelse(bp);
149
                        continue;
150
                }
151
 
152
                switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
153
                case VXFS_TYPED_INDIRECT:
154
                        pblock = vxfs_bmap_indir(ip, typ->vt_block,
155
                                        typ->vt_size, block - off);
156
                        if (pblock == -2)
157
                                break;
158
                        goto out;
159
                case VXFS_TYPED_DATA:
160
                        if ((block - off) >= typ->vt_size)
161
                                break;
162
                        pblock = (typ->vt_block + block - off);
163
                        goto out;
164
                case VXFS_TYPED_INDIRECT_DEV4:
165
                case VXFS_TYPED_DATA_DEV4: {
166
                        struct vxfs_typed_dev4  *typ4 =
167
                                (struct vxfs_typed_dev4 *)typ;
168
 
169
                        printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
170
                        printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
171
                                typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
172
                        goto fail;
173
                }
174
                default:
175
                        BUG();
176
                }
177
                brelse(bp);
178
        }
179
 
180
fail:
181
        pblock = 0;
182
out:
183
        brelse(bp);
184
        return (pblock);
185
}
186
 
187
/**
188
 * vxfs_bmap_typed - bmap for typed extents
189
 * @ip:         pointer to the inode we do bmap for
190
 * @iblock:     logical block
191
 *
192
 * Description:
193
 *   Performs the bmap operation for typed extents.
194
 *
195
 * Return Value:
196
 *   The physical block number on success, else Zero.
197
 */
198
static daddr_t
199
vxfs_bmap_typed(struct inode *ip, long iblock)
200
{
201
        struct vxfs_inode_info          *vip = VXFS_INO(ip);
202
        daddr_t                         pblock = 0;
203
        int                             i;
204
 
205
        for (i = 0; i < VXFS_NTYPED; i++) {
206
                struct vxfs_typed       *typ = vip->vii_org.typed + i;
207
                int64_t                 off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
208
 
209
#ifdef DIAGNOSTIC
210
                vxfs_typdump(typ);
211
#endif
212
                if (iblock < off)
213
                        continue;
214
                switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
215
                case VXFS_TYPED_INDIRECT:
216
                        pblock = vxfs_bmap_indir(ip, typ->vt_block,
217
                                        typ->vt_size, iblock - off);
218
                        if (pblock == -2)
219
                                break;
220
                        return (pblock);
221
                case VXFS_TYPED_DATA:
222
                        if ((iblock - off) < typ->vt_size)
223
                                return (typ->vt_block + iblock - off);
224
                        break;
225
                case VXFS_TYPED_INDIRECT_DEV4:
226
                case VXFS_TYPED_DATA_DEV4: {
227
                        struct vxfs_typed_dev4  *typ4 =
228
                                (struct vxfs_typed_dev4 *)typ;
229
 
230
                        printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
231
                        printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
232
                                typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
233
                        return 0;
234
                }
235
                default:
236
                        BUG();
237
                }
238
        }
239
 
240
        return 0;
241
}
242
 
243
/**
244
 * vxfs_bmap1 - vxfs-internal bmap operation
245
 * @ip:                 pointer to the inode we do bmap for
246
 * @iblock:             logical block
247
 *
248
 * Description:
249
 *   vxfs_bmap1 perfoms a logical to physical block mapping
250
 *   for vxfs-internal purposes.
251
 *
252
 * Return Value:
253
 *   The physical block number on success, else Zero.
254
 */
255
daddr_t
256
vxfs_bmap1(struct inode *ip, long iblock)
257
{
258
        struct vxfs_inode_info          *vip = VXFS_INO(ip);
259
 
260
        if (VXFS_ISEXT4(vip))
261
                return vxfs_bmap_ext4(ip, iblock);
262
        if (VXFS_ISTYPED(vip))
263
                return vxfs_bmap_typed(ip, iblock);
264
        if (VXFS_ISNONE(vip))
265
                goto unsupp;
266
        if (VXFS_ISIMMED(vip))
267
                goto unsupp;
268
 
269
        printk(KERN_WARNING "vxfs: inode %ld has no valid orgtype (%x)\n",
270
                        ip->i_ino, vip->vii_orgtype);
271
        BUG();
272
 
273
unsupp:
274
        printk(KERN_WARNING "vxfs: inode %ld has an unsupported orgtype (%x)\n",
275
                        ip->i_ino, vip->vii_orgtype);
276
        return 0;
277
}

powered by: WebSVN 2.1.0

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