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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [freevxfs/] [vxfs_bmap.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
/*
31
 * Veritas filesystem driver - filesystem to disk block mapping.
32
 */
33
#include <linux/fs.h>
34
#include <linux/buffer_head.h>
35
#include <linux/kernel.h>
36
 
37
#include "vxfs.h"
38
#include "vxfs_inode.h"
39
#include "vxfs_extern.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 too 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 (!bp || !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
                               (unsigned long long) typ4->vd4_block,
172
                               (unsigned long long) typ4->vd4_size,
173
                               typ4->vd4_dev);
174
                        goto fail;
175
                }
176
                default:
177
                        BUG();
178
                }
179
                brelse(bp);
180
        }
181
 
182
fail:
183
        pblock = 0;
184
out:
185
        brelse(bp);
186
        return (pblock);
187
}
188
 
189
/**
190
 * vxfs_bmap_typed - bmap for typed extents
191
 * @ip:         pointer to the inode we do bmap for
192
 * @iblock:     logical block
193
 *
194
 * Description:
195
 *   Performs the bmap operation for typed extents.
196
 *
197
 * Return Value:
198
 *   The physical block number on success, else Zero.
199
 */
200
static daddr_t
201
vxfs_bmap_typed(struct inode *ip, long iblock)
202
{
203
        struct vxfs_inode_info          *vip = VXFS_INO(ip);
204
        daddr_t                         pblock = 0;
205
        int                             i;
206
 
207
        for (i = 0; i < VXFS_NTYPED; i++) {
208
                struct vxfs_typed       *typ = vip->vii_org.typed + i;
209
                int64_t                 off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
210
 
211
#ifdef DIAGNOSTIC
212
                vxfs_typdump(typ);
213
#endif
214
                if (iblock < off)
215
                        continue;
216
                switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
217
                case VXFS_TYPED_INDIRECT:
218
                        pblock = vxfs_bmap_indir(ip, typ->vt_block,
219
                                        typ->vt_size, iblock - off);
220
                        if (pblock == -2)
221
                                break;
222
                        return (pblock);
223
                case VXFS_TYPED_DATA:
224
                        if ((iblock - off) < typ->vt_size)
225
                                return (typ->vt_block + iblock - off);
226
                        break;
227
                case VXFS_TYPED_INDIRECT_DEV4:
228
                case VXFS_TYPED_DATA_DEV4: {
229
                        struct vxfs_typed_dev4  *typ4 =
230
                                (struct vxfs_typed_dev4 *)typ;
231
 
232
                        printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
233
                        printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
234
                               (unsigned long long) typ4->vd4_block,
235
                               (unsigned long long) typ4->vd4_size,
236
                               typ4->vd4_dev);
237
                        return 0;
238
                }
239
                default:
240
                        BUG();
241
                }
242
        }
243
 
244
        return 0;
245
}
246
 
247
/**
248
 * vxfs_bmap1 - vxfs-internal bmap operation
249
 * @ip:                 pointer to the inode we do bmap for
250
 * @iblock:             logical block
251
 *
252
 * Description:
253
 *   vxfs_bmap1 perfoms a logical to physical block mapping
254
 *   for vxfs-internal purposes.
255
 *
256
 * Return Value:
257
 *   The physical block number on success, else Zero.
258
 */
259
daddr_t
260
vxfs_bmap1(struct inode *ip, long iblock)
261
{
262
        struct vxfs_inode_info          *vip = VXFS_INO(ip);
263
 
264
        if (VXFS_ISEXT4(vip))
265
                return vxfs_bmap_ext4(ip, iblock);
266
        if (VXFS_ISTYPED(vip))
267
                return vxfs_bmap_typed(ip, iblock);
268
        if (VXFS_ISNONE(vip))
269
                goto unsupp;
270
        if (VXFS_ISIMMED(vip))
271
                goto unsupp;
272
 
273
        printk(KERN_WARNING "vxfs: inode %ld has no valid orgtype (%x)\n",
274
                        ip->i_ino, vip->vii_orgtype);
275
        BUG();
276
 
277
unsupp:
278
        printk(KERN_WARNING "vxfs: inode %ld has an unsupported orgtype (%x)\n",
279
                        ip->i_ino, vip->vii_orgtype);
280
        return 0;
281
}

powered by: WebSVN 2.1.0

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