2022-05-16 16:38:25 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-17 02:20:36 +04:00
/*
* Copyright ( c ) 2000 - 2001 Christoph Hellwig .
2016-06-01 10:25:12 +03:00
* Copyright ( c ) 2016 Krzysztof Blaszkowski
2005-04-17 02:20:36 +04:00
*/
/*
* Veritas filesystem driver - fileset header routines .
*/
# include <linux/fs.h>
# include <linux/buffer_head.h>
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/string.h>
# include "vxfs.h"
# include "vxfs_inode.h"
# include "vxfs_extern.h"
# include "vxfs_fshead.h"
# ifdef DIAGNOSTIC
static void
vxfs_dumpfsh ( struct vxfs_fsh * fhp )
{
printk ( " \n \n dumping fileset header: \n " ) ;
printk ( " ---------------------------- \n " ) ;
printk ( " version: %u \n " , fhp - > fsh_version ) ;
printk ( " fsindex: %u \n " , fhp - > fsh_fsindex ) ;
printk ( " iauino: %u \t ninodes:%u \n " ,
fhp - > fsh_iauino , fhp - > fsh_ninodes ) ;
printk ( " maxinode: %u \t lctino: %u \n " ,
fhp - > fsh_maxinode , fhp - > fsh_lctino ) ;
printk ( " nau: %u \n " , fhp - > fsh_nau ) ;
printk ( " ilistino[0]: %u \t ilistino[1]: %u \n " ,
fhp - > fsh_ilistino [ 0 ] , fhp - > fsh_ilistino [ 1 ] ) ;
}
# endif
/**
* vxfs_getfsh - read fileset header into memory
* @ ip : the ( fake ) fileset header inode
* @ which : 0 for the structural , 1 for the primary fsh .
*
* Description :
* vxfs_getfsh reads either the structural or primary fileset header
* described by @ ip into memory .
*
* Returns :
* The fileset header structure on success , else Zero .
*/
static struct vxfs_fsh *
vxfs_getfsh ( struct inode * ip , int which )
{
struct buffer_head * bp ;
bp = vxfs_bread ( ip , which ) ;
2005-06-30 13:59:04 +04:00
if ( bp ) {
2005-04-17 02:20:36 +04:00
struct vxfs_fsh * fhp ;
2005-06-30 13:59:04 +04:00
if ( ! ( fhp = kmalloc ( sizeof ( * fhp ) , GFP_KERNEL ) ) )
goto out ;
2005-04-17 02:20:36 +04:00
memcpy ( fhp , bp - > b_data , sizeof ( * fhp ) ) ;
2005-06-30 13:59:04 +04:00
put_bh ( bp ) ;
2005-04-17 02:20:36 +04:00
return ( fhp ) ;
}
2005-06-30 13:59:04 +04:00
out :
brelse ( bp ) ;
2005-04-17 02:20:36 +04:00
return NULL ;
}
/**
* vxfs_read_fshead - read the fileset headers
* @ sbp : superblock to which the fileset belongs
*
* Description :
* vxfs_read_fshead will fill the inode and structural inode list in @ sb .
*
* Returns :
* Zero on success , else a negative error code ( - EINVAL ) .
*/
int
vxfs_read_fshead ( struct super_block * sbp )
{
struct vxfs_sb_info * infp = VXFS_SBI ( sbp ) ;
struct vxfs_fsh * pfp , * sfp ;
2016-06-01 09:56:04 +03:00
struct vxfs_inode_info * vip ;
2005-04-17 02:20:36 +04:00
2016-06-01 09:56:04 +03:00
infp - > vsi_fship = vxfs_blkiget ( sbp , infp - > vsi_iext , infp - > vsi_fshino ) ;
if ( ! infp - > vsi_fship ) {
2006-06-25 16:47:16 +04:00
printk ( KERN_ERR " vxfs: unable to read fsh inode \n " ) ;
2005-04-17 02:20:36 +04:00
return - EINVAL ;
}
2016-06-01 09:56:04 +03:00
vip = VXFS_INO ( infp - > vsi_fship ) ;
2005-04-17 02:20:36 +04:00
if ( ! VXFS_ISFSH ( vip ) ) {
printk ( KERN_ERR " vxfs: fsh list inode is of wrong type (%x) \n " ,
vip - > vii_mode & VXFS_TYPE_MASK ) ;
2016-06-01 09:56:04 +03:00
goto out_iput_fship ;
2005-04-17 02:20:36 +04:00
}
# ifdef DIAGNOSTIC
printk ( " vxfs: fsh inode dump: \n " ) ;
vxfs_dumpi ( vip , infp - > vsi_fshino ) ;
# endif
sfp = vxfs_getfsh ( infp - > vsi_fship , 0 ) ;
if ( ! sfp ) {
2006-06-25 16:47:16 +04:00
printk ( KERN_ERR " vxfs: unable to get structural fsh \n " ) ;
2005-04-17 02:20:36 +04:00
goto out_iput_fship ;
}
# ifdef DIAGNOSTIC
vxfs_dumpfsh ( sfp ) ;
# endif
pfp = vxfs_getfsh ( infp - > vsi_fship , 1 ) ;
if ( ! pfp ) {
2006-06-25 16:47:16 +04:00
printk ( KERN_ERR " vxfs: unable to get primary fsh \n " ) ;
2005-04-17 02:20:36 +04:00
goto out_free_sfp ;
}
# ifdef DIAGNOSTIC
vxfs_dumpfsh ( pfp ) ;
# endif
2016-06-01 09:56:04 +03:00
infp - > vsi_stilist = vxfs_blkiget ( sbp , infp - > vsi_iext ,
2016-05-31 09:45:13 +03:00
fs32_to_cpu ( infp , sfp - > fsh_ilistino [ 0 ] ) ) ;
2005-04-17 02:20:36 +04:00
if ( ! infp - > vsi_stilist ) {
2006-06-25 16:47:16 +04:00
printk ( KERN_ERR " vxfs: unable to get structural list inode \n " ) ;
2005-04-17 02:20:36 +04:00
goto out_free_pfp ;
}
if ( ! VXFS_ISILT ( VXFS_INO ( infp - > vsi_stilist ) ) ) {
2011-03-31 05:57:33 +04:00
printk ( KERN_ERR " vxfs: structural list inode is of wrong type (%x) \n " ,
2005-04-17 02:20:36 +04:00
VXFS_INO ( infp - > vsi_stilist ) - > vii_mode & VXFS_TYPE_MASK ) ;
goto out_iput_stilist ;
}
2016-06-01 09:56:04 +03:00
infp - > vsi_ilist = vxfs_stiget ( sbp , fs32_to_cpu ( infp , pfp - > fsh_ilistino [ 0 ] ) ) ;
2005-04-17 02:20:36 +04:00
if ( ! infp - > vsi_ilist ) {
2006-06-25 16:47:16 +04:00
printk ( KERN_ERR " vxfs: unable to get inode list inode \n " ) ;
2005-04-17 02:20:36 +04:00
goto out_iput_stilist ;
}
if ( ! VXFS_ISILT ( VXFS_INO ( infp - > vsi_ilist ) ) ) {
printk ( KERN_ERR " vxfs: inode list inode is of wrong type (%x) \n " ,
VXFS_INO ( infp - > vsi_ilist ) - > vii_mode & VXFS_TYPE_MASK ) ;
goto out_iput_ilist ;
}
2016-06-12 20:25:23 +03:00
kfree ( pfp ) ;
kfree ( sfp ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
out_iput_ilist :
iput ( infp - > vsi_ilist ) ;
out_iput_stilist :
iput ( infp - > vsi_stilist ) ;
out_free_pfp :
kfree ( pfp ) ;
out_free_sfp :
kfree ( sfp ) ;
out_iput_fship :
iput ( infp - > vsi_fship ) ;
return - EINVAL ;
}