2022-05-16 15:38:25 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-16 15:20:36 -07:00
/*
* Copyright ( c ) 2000 - 2001 Christoph Hellwig .
*/
/*
* Veritas filesystem driver - object location table support .
*/
# include <linux/fs.h>
# include <linux/buffer_head.h>
# include <linux/kernel.h>
# include "vxfs.h"
# include "vxfs_olt.h"
2005-11-08 16:47:45 +01:00
# include "vxfs_extern.h"
2005-04-16 15:20:36 -07:00
2005-06-30 02:59:05 -07:00
static inline void
2005-04-16 15:20:36 -07:00
vxfs_get_fshead ( struct vxfs_oltfshead * fshp , struct vxfs_sb_info * infp )
{
2006-04-02 13:41:02 +02:00
BUG_ON ( infp - > vsi_fshino ) ;
2016-05-31 08:45:13 +02:00
infp - > vsi_fshino = fs32_to_cpu ( infp , fshp - > olt_fsino [ 0 ] ) ;
2005-04-16 15:20:36 -07:00
}
2005-06-30 02:59:05 -07:00
static inline void
2005-04-16 15:20:36 -07:00
vxfs_get_ilist ( struct vxfs_oltilist * ilistp , struct vxfs_sb_info * infp )
{
2006-04-02 13:41:02 +02:00
BUG_ON ( infp - > vsi_iext ) ;
2016-05-31 08:45:13 +02:00
infp - > vsi_iext = fs32_to_cpu ( infp , ilistp - > olt_iext [ 0 ] ) ;
2005-04-16 15:20:36 -07:00
}
2005-06-30 02:59:05 -07:00
static inline u_long
2005-04-16 15:20:36 -07:00
vxfs_oblock ( struct super_block * sbp , daddr_t block , u_long bsize )
{
2006-04-02 13:41:02 +02:00
BUG_ON ( sbp - > s_blocksize % bsize ) ;
2005-04-16 15:20:36 -07:00
return ( block * ( sbp - > s_blocksize / bsize ) ) ;
}
/**
* vxfs_read_olt - read olt
* @ sbp : superblock of the filesystem
* @ bsize : blocksize of the filesystem
*
* Description :
* vxfs_read_olt reads the olt of the filesystem described by @ sbp
* into main memory and does some basic setup .
*
* Returns :
* Zero on success , else a negative error code .
*/
int
vxfs_read_olt ( struct super_block * sbp , u_long bsize )
{
struct vxfs_sb_info * infp = VXFS_SBI ( sbp ) ;
struct buffer_head * bp ;
struct vxfs_olt * op ;
char * oaddr , * eaddr ;
bp = sb_bread ( sbp , vxfs_oblock ( sbp , infp - > vsi_oltext , bsize ) ) ;
if ( ! bp | | ! bp - > b_data )
goto fail ;
op = ( struct vxfs_olt * ) bp - > b_data ;
2016-05-31 08:45:13 +02:00
if ( fs32_to_cpu ( infp , op - > olt_magic ) ! = VXFS_OLT_MAGIC ) {
2005-04-16 15:20:36 -07:00
printk ( KERN_NOTICE " vxfs: ivalid olt magic number \n " ) ;
goto fail ;
}
/*
* It is in theory possible that vsi_oltsize is > 1.
* I ' ve not seen any such filesystem yet and I ' m lazy . . - - hch
*/
if ( infp - > vsi_oltsize > 1 ) {
printk ( KERN_NOTICE " vxfs: oltsize > 1 detected. \n " ) ;
printk ( KERN_NOTICE " vxfs: please notify hch@infradead.org \n " ) ;
goto fail ;
}
2016-05-31 08:45:13 +02:00
oaddr = bp - > b_data + fs32_to_cpu ( infp , op - > olt_size ) ;
2005-06-30 02:59:05 -07:00
eaddr = bp - > b_data + ( infp - > vsi_oltsize * sbp - > s_blocksize ) ;
2005-04-16 15:20:36 -07:00
while ( oaddr < eaddr ) {
struct vxfs_oltcommon * ocp =
( struct vxfs_oltcommon * ) oaddr ;
2016-05-31 08:45:13 +02:00
switch ( fs32_to_cpu ( infp , ocp - > olt_type ) ) {
2005-04-16 15:20:36 -07:00
case VXFS_OLT_FSHEAD :
vxfs_get_fshead ( ( struct vxfs_oltfshead * ) oaddr , infp ) ;
break ;
case VXFS_OLT_ILIST :
vxfs_get_ilist ( ( struct vxfs_oltilist * ) oaddr , infp ) ;
break ;
}
2016-05-31 08:45:13 +02:00
oaddr + = fs32_to_cpu ( infp , ocp - > olt_size ) ;
2005-04-16 15:20:36 -07:00
}
brelse ( bp ) ;
2016-05-31 08:45:13 +02:00
return ( infp - > vsi_fshino & & infp - > vsi_iext ) ? 0 : - EINVAL ;
2005-04-16 15:20:36 -07:00
fail :
brelse ( bp ) ;
return - EINVAL ;
}