Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2000-2001 Christoph Hellwig.
0004  * Copyright (c) 2016 Krzysztof Blaszkowski
0005  */
0006 
0007 /*
0008  * Veritas filesystem driver - fileset header routines.
0009  */
0010 #include <linux/fs.h>
0011 #include <linux/buffer_head.h>
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 #include <linux/string.h>
0015 
0016 #include "vxfs.h"
0017 #include "vxfs_inode.h"
0018 #include "vxfs_extern.h"
0019 #include "vxfs_fshead.h"
0020 
0021 
0022 #ifdef DIAGNOSTIC
0023 static void
0024 vxfs_dumpfsh(struct vxfs_fsh *fhp)
0025 {
0026     printk("\n\ndumping fileset header:\n");
0027     printk("----------------------------\n");
0028     printk("version: %u\n", fhp->fsh_version);
0029     printk("fsindex: %u\n", fhp->fsh_fsindex);
0030     printk("iauino: %u\tninodes:%u\n",
0031             fhp->fsh_iauino, fhp->fsh_ninodes);
0032     printk("maxinode: %u\tlctino: %u\n",
0033             fhp->fsh_maxinode, fhp->fsh_lctino);
0034     printk("nau: %u\n", fhp->fsh_nau);
0035     printk("ilistino[0]: %u\tilistino[1]: %u\n",
0036             fhp->fsh_ilistino[0], fhp->fsh_ilistino[1]);
0037 }
0038 #endif
0039 
0040 /**
0041  * vxfs_getfsh - read fileset header into memory
0042  * @ip:     the (fake) fileset header inode
0043  * @which:  0 for the structural, 1 for the primary fsh.
0044  *
0045  * Description:
0046  *   vxfs_getfsh reads either the structural or primary fileset header
0047  *   described by @ip into memory.
0048  *
0049  * Returns:
0050  *   The fileset header structure on success, else Zero.
0051  */
0052 static struct vxfs_fsh *
0053 vxfs_getfsh(struct inode *ip, int which)
0054 {
0055     struct buffer_head      *bp;
0056 
0057     bp = vxfs_bread(ip, which);
0058     if (bp) {
0059         struct vxfs_fsh     *fhp;
0060 
0061         if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
0062             goto out;
0063         memcpy(fhp, bp->b_data, sizeof(*fhp));
0064 
0065         put_bh(bp);
0066         return (fhp);
0067     }
0068 out:
0069     brelse(bp);
0070     return NULL;
0071 }
0072 
0073 /**
0074  * vxfs_read_fshead - read the fileset headers
0075  * @sbp:    superblock to which the fileset belongs
0076  *
0077  * Description:
0078  *   vxfs_read_fshead will fill the inode and structural inode list in @sb.
0079  *
0080  * Returns:
0081  *   Zero on success, else a negative error code (-EINVAL).
0082  */
0083 int
0084 vxfs_read_fshead(struct super_block *sbp)
0085 {
0086     struct vxfs_sb_info     *infp = VXFS_SBI(sbp);
0087     struct vxfs_fsh         *pfp, *sfp;
0088     struct vxfs_inode_info      *vip;
0089 
0090     infp->vsi_fship = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
0091     if (!infp->vsi_fship) {
0092         printk(KERN_ERR "vxfs: unable to read fsh inode\n");
0093         return -EINVAL;
0094     }
0095 
0096     vip = VXFS_INO(infp->vsi_fship);
0097     if (!VXFS_ISFSH(vip)) {
0098         printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
0099                 vip->vii_mode & VXFS_TYPE_MASK); 
0100         goto out_iput_fship;
0101     }
0102 
0103 #ifdef DIAGNOSTIC
0104     printk("vxfs: fsh inode dump:\n");
0105     vxfs_dumpi(vip, infp->vsi_fshino);
0106 #endif
0107 
0108     sfp = vxfs_getfsh(infp->vsi_fship, 0);
0109     if (!sfp) {
0110         printk(KERN_ERR "vxfs: unable to get structural fsh\n");
0111         goto out_iput_fship;
0112     } 
0113 
0114 #ifdef DIAGNOSTIC
0115     vxfs_dumpfsh(sfp);
0116 #endif
0117 
0118     pfp = vxfs_getfsh(infp->vsi_fship, 1);
0119     if (!pfp) {
0120         printk(KERN_ERR "vxfs: unable to get primary fsh\n");
0121         goto out_free_sfp;
0122     }
0123 
0124 #ifdef DIAGNOSTIC
0125     vxfs_dumpfsh(pfp);
0126 #endif
0127 
0128     infp->vsi_stilist = vxfs_blkiget(sbp, infp->vsi_iext,
0129             fs32_to_cpu(infp, sfp->fsh_ilistino[0]));
0130     if (!infp->vsi_stilist) {
0131         printk(KERN_ERR "vxfs: unable to get structural list inode\n");
0132         goto out_free_pfp;
0133     }
0134     if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
0135         printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n",
0136                 VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
0137         goto out_iput_stilist;
0138     }
0139 
0140     infp->vsi_ilist = vxfs_stiget(sbp, fs32_to_cpu(infp, pfp->fsh_ilistino[0]));
0141     if (!infp->vsi_ilist) {
0142         printk(KERN_ERR "vxfs: unable to get inode list inode\n");
0143         goto out_iput_stilist;
0144     }
0145     if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
0146         printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
0147                 VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
0148         goto out_iput_ilist;
0149     }
0150 
0151     kfree(pfp);
0152     kfree(sfp);
0153     return 0;
0154 
0155  out_iput_ilist:
0156     iput(infp->vsi_ilist);
0157  out_iput_stilist:
0158     iput(infp->vsi_stilist);
0159  out_free_pfp:
0160     kfree(pfp);
0161  out_free_sfp:
0162     kfree(sfp);
0163  out_iput_fship:
0164     iput(infp->vsi_fship);
0165     return -EINVAL;
0166 }