linux/fs/freevxfs/vxfs_fshead.c
<<
>>
Prefs
   1/*
   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 - fileset header routines.
  32 */
  33#include <linux/fs.h>
  34#include <linux/buffer_head.h>
  35#include <linux/kernel.h>
  36#include <linux/slab.h>
  37#include <linux/string.h>
  38
  39#include "vxfs.h"
  40#include "vxfs_inode.h"
  41#include "vxfs_extern.h"
  42#include "vxfs_fshead.h"
  43
  44
  45#ifdef DIAGNOSTIC
  46static void
  47vxfs_dumpfsh(struct vxfs_fsh *fhp)
  48{
  49        printk("\n\ndumping fileset header:\n");
  50        printk("----------------------------\n");
  51        printk("version: %u\n", fhp->fsh_version);
  52        printk("fsindex: %u\n", fhp->fsh_fsindex);
  53        printk("iauino: %u\tninodes:%u\n",
  54                        fhp->fsh_iauino, fhp->fsh_ninodes);
  55        printk("maxinode: %u\tlctino: %u\n",
  56                        fhp->fsh_maxinode, fhp->fsh_lctino);
  57        printk("nau: %u\n", fhp->fsh_nau);
  58        printk("ilistino[0]: %u\tilistino[1]: %u\n",
  59                        fhp->fsh_ilistino[0], fhp->fsh_ilistino[1]);
  60}
  61#endif
  62
  63/**
  64 * vxfs_getfsh - read fileset header into memory
  65 * @ip:         the (fake) fileset header inode
  66 * @which:      0 for the structural, 1 for the primary fsh.
  67 *
  68 * Description:
  69 *   vxfs_getfsh reads either the structural or primary fileset header
  70 *   described by @ip into memory.
  71 *
  72 * Returns:
  73 *   The fileset header structure on success, else Zero.
  74 */
  75static struct vxfs_fsh *
  76vxfs_getfsh(struct inode *ip, int which)
  77{
  78        struct buffer_head              *bp;
  79
  80        bp = vxfs_bread(ip, which);
  81        if (bp) {
  82                struct vxfs_fsh         *fhp;
  83
  84                if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
  85                        goto out;
  86                memcpy(fhp, bp->b_data, sizeof(*fhp));
  87
  88                put_bh(bp);
  89                return (fhp);
  90        }
  91out:
  92        brelse(bp);
  93        return NULL;
  94}
  95
  96/**
  97 * vxfs_read_fshead - read the fileset headers
  98 * @sbp:        superblock to which the fileset belongs
  99 *
 100 * Description:
 101 *   vxfs_read_fshead will fill the inode and structural inode list in @sb.
 102 *
 103 * Returns:
 104 *   Zero on success, else a negative error code (-EINVAL).
 105 */
 106int
 107vxfs_read_fshead(struct super_block *sbp)
 108{
 109        struct vxfs_sb_info             *infp = VXFS_SBI(sbp);
 110        struct vxfs_fsh                 *pfp, *sfp;
 111        struct vxfs_inode_info          *vip, *tip;
 112
 113        vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
 114        if (!vip) {
 115                printk(KERN_ERR "vxfs: unable to read fsh inode\n");
 116                return -EINVAL;
 117        }
 118        if (!VXFS_ISFSH(vip)) {
 119                printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
 120                                vip->vii_mode & VXFS_TYPE_MASK); 
 121                goto out_free_fship;
 122        }
 123
 124
 125#ifdef DIAGNOSTIC
 126        printk("vxfs: fsh inode dump:\n");
 127        vxfs_dumpi(vip, infp->vsi_fshino);
 128#endif
 129
 130        infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
 131        if (!infp->vsi_fship) {
 132                printk(KERN_ERR "vxfs: unable to get fsh inode\n");
 133                goto out_free_fship;
 134        }
 135
 136        sfp = vxfs_getfsh(infp->vsi_fship, 0);
 137        if (!sfp) {
 138                printk(KERN_ERR "vxfs: unable to get structural fsh\n");
 139                goto out_iput_fship;
 140        } 
 141
 142#ifdef DIAGNOSTIC
 143        vxfs_dumpfsh(sfp);
 144#endif
 145
 146        pfp = vxfs_getfsh(infp->vsi_fship, 1);
 147        if (!pfp) {
 148                printk(KERN_ERR "vxfs: unable to get primary fsh\n");
 149                goto out_free_sfp;
 150        }
 151
 152#ifdef DIAGNOSTIC
 153        vxfs_dumpfsh(pfp);
 154#endif
 155
 156        tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
 157        if (!tip)
 158                goto out_free_pfp;
 159
 160        infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
 161        if (!infp->vsi_stilist) {
 162                printk(KERN_ERR "vxfs: unable to get structural list inode\n");
 163                kfree(tip);
 164                goto out_free_pfp;
 165        }
 166        if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
 167                printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n",
 168                                VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
 169                goto out_iput_stilist;
 170        }
 171
 172        tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
 173        if (!tip)
 174                goto out_iput_stilist;
 175        infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
 176        if (!infp->vsi_ilist) {
 177                printk(KERN_ERR "vxfs: unable to get inode list inode\n");
 178                kfree(tip);
 179                goto out_iput_stilist;
 180        }
 181        if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
 182                printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
 183                                VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
 184                goto out_iput_ilist;
 185        }
 186
 187        return 0;
 188
 189 out_iput_ilist:
 190        iput(infp->vsi_ilist);
 191 out_iput_stilist:
 192        iput(infp->vsi_stilist);
 193 out_free_pfp:
 194        kfree(pfp);
 195 out_free_sfp:
 196        kfree(sfp);
 197 out_iput_fship:
 198        iput(infp->vsi_fship);
 199        return -EINVAL;
 200 out_free_fship:
 201        kfree(vip);
 202        return -EINVAL;
 203}
 204