linux/fs/freevxfs/vxfs_olt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2000-2001 Christoph Hellwig.
   4 */
   5
   6/* 
   7 * Veritas filesystem driver - object location table support.
   8 */
   9#include <linux/fs.h>
  10#include <linux/buffer_head.h>
  11#include <linux/kernel.h>
  12
  13#include "vxfs.h"
  14#include "vxfs_olt.h"
  15#include "vxfs_extern.h"
  16
  17
  18static inline void
  19vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
  20{
  21        BUG_ON(infp->vsi_fshino);
  22        infp->vsi_fshino = fs32_to_cpu(infp, fshp->olt_fsino[0]);
  23}
  24
  25static inline void
  26vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
  27{
  28        BUG_ON(infp->vsi_iext);
  29        infp->vsi_iext = fs32_to_cpu(infp, ilistp->olt_iext[0]);
  30}
  31
  32static inline u_long
  33vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
  34{
  35        BUG_ON(sbp->s_blocksize % bsize);
  36        return (block * (sbp->s_blocksize / bsize));
  37}
  38
  39
  40/**
  41 * vxfs_read_olt - read olt
  42 * @sbp:        superblock of the filesystem
  43 * @bsize:      blocksize of the filesystem
  44 *
  45 * Description:
  46 *   vxfs_read_olt reads the olt of the filesystem described by @sbp
  47 *   into main memory and does some basic setup.
  48 *
  49 * Returns:
  50 *   Zero on success, else a negative error code.
  51 */
  52int
  53vxfs_read_olt(struct super_block *sbp, u_long bsize)
  54{
  55        struct vxfs_sb_info     *infp = VXFS_SBI(sbp);
  56        struct buffer_head      *bp;
  57        struct vxfs_olt         *op;
  58        char                    *oaddr, *eaddr;
  59
  60        bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
  61        if (!bp || !bp->b_data)
  62                goto fail;
  63
  64        op = (struct vxfs_olt *)bp->b_data;
  65        if (fs32_to_cpu(infp, op->olt_magic) != VXFS_OLT_MAGIC) {
  66                printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
  67                goto fail;
  68        }
  69
  70        /*
  71         * It is in theory possible that vsi_oltsize is > 1.
  72         * I've not seen any such filesystem yet and I'm lazy..  --hch
  73         */
  74        if (infp->vsi_oltsize > 1) {
  75                printk(KERN_NOTICE "vxfs: oltsize > 1 detected.\n");
  76                printk(KERN_NOTICE "vxfs: please notify hch@infradead.org\n");
  77                goto fail;
  78        }
  79
  80        oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
  81        eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
  82
  83        while (oaddr < eaddr) {
  84                struct vxfs_oltcommon   *ocp =
  85                        (struct vxfs_oltcommon *)oaddr;
  86                
  87                switch (fs32_to_cpu(infp, ocp->olt_type)) {
  88                case VXFS_OLT_FSHEAD:
  89                        vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
  90                        break;
  91                case VXFS_OLT_ILIST:
  92                        vxfs_get_ilist((struct vxfs_oltilist *)oaddr, infp);
  93                        break;
  94                }
  95
  96                oaddr += fs32_to_cpu(infp, ocp->olt_size);
  97        }
  98
  99        brelse(bp);
 100        return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
 101
 102fail:
 103        brelse(bp);
 104        return -EINVAL;
 105}
 106