xref: /linux/fs/freevxfs/vxfs_olt.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*0b1e987cSChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Copyright (c) 2000-2001 Christoph Hellwig.
41da177e4SLinus Torvalds  */
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds /*
71da177e4SLinus Torvalds  * Veritas filesystem driver - object location table support.
81da177e4SLinus Torvalds  */
91da177e4SLinus Torvalds #include <linux/fs.h>
101da177e4SLinus Torvalds #include <linux/buffer_head.h>
111da177e4SLinus Torvalds #include <linux/kernel.h>
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds #include "vxfs.h"
141da177e4SLinus Torvalds #include "vxfs_olt.h"
156e1e8e11SAdrian Bunk #include "vxfs_extern.h"
161da177e4SLinus Torvalds 
171da177e4SLinus Torvalds 
188cb681b9SPekka Enberg static inline void
vxfs_get_fshead(struct vxfs_oltfshead * fshp,struct vxfs_sb_info * infp)191da177e4SLinus Torvalds vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
201da177e4SLinus Torvalds {
217ec70738SEric Sesterhenn 	BUG_ON(infp->vsi_fshino);
220d83f7fcSKrzysztof Błaszkowski 	infp->vsi_fshino = fs32_to_cpu(infp, fshp->olt_fsino[0]);
231da177e4SLinus Torvalds }
241da177e4SLinus Torvalds 
258cb681b9SPekka Enberg static inline void
vxfs_get_ilist(struct vxfs_oltilist * ilistp,struct vxfs_sb_info * infp)261da177e4SLinus Torvalds vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
271da177e4SLinus Torvalds {
287ec70738SEric Sesterhenn 	BUG_ON(infp->vsi_iext);
290d83f7fcSKrzysztof Błaszkowski 	infp->vsi_iext = fs32_to_cpu(infp, ilistp->olt_iext[0]);
301da177e4SLinus Torvalds }
311da177e4SLinus Torvalds 
328cb681b9SPekka Enberg static inline u_long
vxfs_oblock(struct super_block * sbp,daddr_t block,u_long bsize)331da177e4SLinus Torvalds vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
341da177e4SLinus Torvalds {
357ec70738SEric Sesterhenn 	BUG_ON(sbp->s_blocksize % bsize);
361da177e4SLinus Torvalds 	return (block * (sbp->s_blocksize / bsize));
371da177e4SLinus Torvalds }
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds 
401da177e4SLinus Torvalds /**
411da177e4SLinus Torvalds  * vxfs_read_olt - read olt
421da177e4SLinus Torvalds  * @sbp:	superblock of the filesystem
431da177e4SLinus Torvalds  * @bsize:	blocksize of the filesystem
441da177e4SLinus Torvalds  *
451da177e4SLinus Torvalds  * Description:
461da177e4SLinus Torvalds  *   vxfs_read_olt reads the olt of the filesystem described by @sbp
471da177e4SLinus Torvalds  *   into main memory and does some basic setup.
481da177e4SLinus Torvalds  *
491da177e4SLinus Torvalds  * Returns:
501da177e4SLinus Torvalds  *   Zero on success, else a negative error code.
511da177e4SLinus Torvalds  */
521da177e4SLinus Torvalds int
vxfs_read_olt(struct super_block * sbp,u_long bsize)531da177e4SLinus Torvalds vxfs_read_olt(struct super_block *sbp, u_long bsize)
541da177e4SLinus Torvalds {
551da177e4SLinus Torvalds 	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);
561da177e4SLinus Torvalds 	struct buffer_head	*bp;
571da177e4SLinus Torvalds 	struct vxfs_olt		*op;
581da177e4SLinus Torvalds 	char			*oaddr, *eaddr;
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds 	bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
611da177e4SLinus Torvalds 	if (!bp || !bp->b_data)
621da177e4SLinus Torvalds 		goto fail;
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds 	op = (struct vxfs_olt *)bp->b_data;
650d83f7fcSKrzysztof Błaszkowski 	if (fs32_to_cpu(infp, op->olt_magic) != VXFS_OLT_MAGIC) {
661da177e4SLinus Torvalds 		printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
671da177e4SLinus Torvalds 		goto fail;
681da177e4SLinus Torvalds 	}
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds 	/*
711da177e4SLinus Torvalds 	 * It is in theory possible that vsi_oltsize is > 1.
721da177e4SLinus Torvalds 	 * I've not seen any such filesystem yet and I'm lazy..  --hch
731da177e4SLinus Torvalds 	 */
741da177e4SLinus Torvalds 	if (infp->vsi_oltsize > 1) {
751da177e4SLinus Torvalds 		printk(KERN_NOTICE "vxfs: oltsize > 1 detected.\n");
761da177e4SLinus Torvalds 		printk(KERN_NOTICE "vxfs: please notify hch@infradead.org\n");
771da177e4SLinus Torvalds 		goto fail;
781da177e4SLinus Torvalds 	}
791da177e4SLinus Torvalds 
800d83f7fcSKrzysztof Błaszkowski 	oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
818cb681b9SPekka Enberg 	eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	while (oaddr < eaddr) {
841da177e4SLinus Torvalds 		struct vxfs_oltcommon	*ocp =
851da177e4SLinus Torvalds 			(struct vxfs_oltcommon *)oaddr;
861da177e4SLinus Torvalds 
870d83f7fcSKrzysztof Błaszkowski 		switch (fs32_to_cpu(infp, ocp->olt_type)) {
881da177e4SLinus Torvalds 		case VXFS_OLT_FSHEAD:
891da177e4SLinus Torvalds 			vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
901da177e4SLinus Torvalds 			break;
911da177e4SLinus Torvalds 		case VXFS_OLT_ILIST:
921da177e4SLinus Torvalds 			vxfs_get_ilist((struct vxfs_oltilist *)oaddr, infp);
931da177e4SLinus Torvalds 			break;
941da177e4SLinus Torvalds 		}
951da177e4SLinus Torvalds 
960d83f7fcSKrzysztof Błaszkowski 		oaddr += fs32_to_cpu(infp, ocp->olt_size);
971da177e4SLinus Torvalds 	}
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds 	brelse(bp);
1000d83f7fcSKrzysztof Błaszkowski 	return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds fail:
1031da177e4SLinus Torvalds 	brelse(bp);
1041da177e4SLinus Torvalds 	return -EINVAL;
1051da177e4SLinus Torvalds }
106