18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2000-2001 Christoph Hellwig. 38c2ecf20Sopenharmony_ci * Copyright (c) 2016 Krzysztof Blaszkowski 48c2ecf20Sopenharmony_ci * All rights reserved. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 78c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 88c2ecf20Sopenharmony_ci * are met: 98c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 108c2ecf20Sopenharmony_ci * notice, this list of conditions, and the following disclaimer, 118c2ecf20Sopenharmony_ci * without modification. 128c2ecf20Sopenharmony_ci * 2. The name of the author may not be used to endorse or promote products 138c2ecf20Sopenharmony_ci * derived from this software without specific prior written permission. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 168c2ecf20Sopenharmony_ci * GNU General Public License ("GPL"). 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 198c2ecf20Sopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 208c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 218c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 228c2ecf20Sopenharmony_ci * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 238c2ecf20Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 248c2ecf20Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 258c2ecf20Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 268c2ecf20Sopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 278c2ecf20Sopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 288c2ecf20Sopenharmony_ci * SUCH DAMAGE. 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* 328c2ecf20Sopenharmony_ci * Veritas filesystem driver - fileset header routines. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci#include <linux/fs.h> 358c2ecf20Sopenharmony_ci#include <linux/buffer_head.h> 368c2ecf20Sopenharmony_ci#include <linux/kernel.h> 378c2ecf20Sopenharmony_ci#include <linux/slab.h> 388c2ecf20Sopenharmony_ci#include <linux/string.h> 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#include "vxfs.h" 418c2ecf20Sopenharmony_ci#include "vxfs_inode.h" 428c2ecf20Sopenharmony_ci#include "vxfs_extern.h" 438c2ecf20Sopenharmony_ci#include "vxfs_fshead.h" 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC 478c2ecf20Sopenharmony_cistatic void 488c2ecf20Sopenharmony_civxfs_dumpfsh(struct vxfs_fsh *fhp) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci printk("\n\ndumping fileset header:\n"); 518c2ecf20Sopenharmony_ci printk("----------------------------\n"); 528c2ecf20Sopenharmony_ci printk("version: %u\n", fhp->fsh_version); 538c2ecf20Sopenharmony_ci printk("fsindex: %u\n", fhp->fsh_fsindex); 548c2ecf20Sopenharmony_ci printk("iauino: %u\tninodes:%u\n", 558c2ecf20Sopenharmony_ci fhp->fsh_iauino, fhp->fsh_ninodes); 568c2ecf20Sopenharmony_ci printk("maxinode: %u\tlctino: %u\n", 578c2ecf20Sopenharmony_ci fhp->fsh_maxinode, fhp->fsh_lctino); 588c2ecf20Sopenharmony_ci printk("nau: %u\n", fhp->fsh_nau); 598c2ecf20Sopenharmony_ci printk("ilistino[0]: %u\tilistino[1]: %u\n", 608c2ecf20Sopenharmony_ci fhp->fsh_ilistino[0], fhp->fsh_ilistino[1]); 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci#endif 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/** 658c2ecf20Sopenharmony_ci * vxfs_getfsh - read fileset header into memory 668c2ecf20Sopenharmony_ci * @ip: the (fake) fileset header inode 678c2ecf20Sopenharmony_ci * @which: 0 for the structural, 1 for the primary fsh. 688c2ecf20Sopenharmony_ci * 698c2ecf20Sopenharmony_ci * Description: 708c2ecf20Sopenharmony_ci * vxfs_getfsh reads either the structural or primary fileset header 718c2ecf20Sopenharmony_ci * described by @ip into memory. 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * Returns: 748c2ecf20Sopenharmony_ci * The fileset header structure on success, else Zero. 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_cistatic struct vxfs_fsh * 778c2ecf20Sopenharmony_civxfs_getfsh(struct inode *ip, int which) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci struct buffer_head *bp; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci bp = vxfs_bread(ip, which); 828c2ecf20Sopenharmony_ci if (bp) { 838c2ecf20Sopenharmony_ci struct vxfs_fsh *fhp; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL))) 868c2ecf20Sopenharmony_ci goto out; 878c2ecf20Sopenharmony_ci memcpy(fhp, bp->b_data, sizeof(*fhp)); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci put_bh(bp); 908c2ecf20Sopenharmony_ci return (fhp); 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ciout: 938c2ecf20Sopenharmony_ci brelse(bp); 948c2ecf20Sopenharmony_ci return NULL; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci/** 988c2ecf20Sopenharmony_ci * vxfs_read_fshead - read the fileset headers 998c2ecf20Sopenharmony_ci * @sbp: superblock to which the fileset belongs 1008c2ecf20Sopenharmony_ci * 1018c2ecf20Sopenharmony_ci * Description: 1028c2ecf20Sopenharmony_ci * vxfs_read_fshead will fill the inode and structural inode list in @sb. 1038c2ecf20Sopenharmony_ci * 1048c2ecf20Sopenharmony_ci * Returns: 1058c2ecf20Sopenharmony_ci * Zero on success, else a negative error code (-EINVAL). 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_ciint 1088c2ecf20Sopenharmony_civxfs_read_fshead(struct super_block *sbp) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci struct vxfs_sb_info *infp = VXFS_SBI(sbp); 1118c2ecf20Sopenharmony_ci struct vxfs_fsh *pfp, *sfp; 1128c2ecf20Sopenharmony_ci struct vxfs_inode_info *vip; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci infp->vsi_fship = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino); 1158c2ecf20Sopenharmony_ci if (!infp->vsi_fship) { 1168c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: unable to read fsh inode\n"); 1178c2ecf20Sopenharmony_ci return -EINVAL; 1188c2ecf20Sopenharmony_ci } 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci vip = VXFS_INO(infp->vsi_fship); 1218c2ecf20Sopenharmony_ci if (!VXFS_ISFSH(vip)) { 1228c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n", 1238c2ecf20Sopenharmony_ci vip->vii_mode & VXFS_TYPE_MASK); 1248c2ecf20Sopenharmony_ci goto out_iput_fship; 1258c2ecf20Sopenharmony_ci } 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC 1288c2ecf20Sopenharmony_ci printk("vxfs: fsh inode dump:\n"); 1298c2ecf20Sopenharmony_ci vxfs_dumpi(vip, infp->vsi_fshino); 1308c2ecf20Sopenharmony_ci#endif 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci sfp = vxfs_getfsh(infp->vsi_fship, 0); 1338c2ecf20Sopenharmony_ci if (!sfp) { 1348c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: unable to get structural fsh\n"); 1358c2ecf20Sopenharmony_ci goto out_iput_fship; 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC 1398c2ecf20Sopenharmony_ci vxfs_dumpfsh(sfp); 1408c2ecf20Sopenharmony_ci#endif 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci pfp = vxfs_getfsh(infp->vsi_fship, 1); 1438c2ecf20Sopenharmony_ci if (!pfp) { 1448c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: unable to get primary fsh\n"); 1458c2ecf20Sopenharmony_ci goto out_free_sfp; 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC 1498c2ecf20Sopenharmony_ci vxfs_dumpfsh(pfp); 1508c2ecf20Sopenharmony_ci#endif 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci infp->vsi_stilist = vxfs_blkiget(sbp, infp->vsi_iext, 1538c2ecf20Sopenharmony_ci fs32_to_cpu(infp, sfp->fsh_ilistino[0])); 1548c2ecf20Sopenharmony_ci if (!infp->vsi_stilist) { 1558c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: unable to get structural list inode\n"); 1568c2ecf20Sopenharmony_ci goto out_free_pfp; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) { 1598c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n", 1608c2ecf20Sopenharmony_ci VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 1618c2ecf20Sopenharmony_ci goto out_iput_stilist; 1628c2ecf20Sopenharmony_ci } 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci infp->vsi_ilist = vxfs_stiget(sbp, fs32_to_cpu(infp, pfp->fsh_ilistino[0])); 1658c2ecf20Sopenharmony_ci if (!infp->vsi_ilist) { 1668c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: unable to get inode list inode\n"); 1678c2ecf20Sopenharmony_ci goto out_iput_stilist; 1688c2ecf20Sopenharmony_ci } 1698c2ecf20Sopenharmony_ci if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) { 1708c2ecf20Sopenharmony_ci printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n", 1718c2ecf20Sopenharmony_ci VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK); 1728c2ecf20Sopenharmony_ci goto out_iput_ilist; 1738c2ecf20Sopenharmony_ci } 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci kfree(pfp); 1768c2ecf20Sopenharmony_ci kfree(sfp); 1778c2ecf20Sopenharmony_ci return 0; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci out_iput_ilist: 1808c2ecf20Sopenharmony_ci iput(infp->vsi_ilist); 1818c2ecf20Sopenharmony_ci out_iput_stilist: 1828c2ecf20Sopenharmony_ci iput(infp->vsi_stilist); 1838c2ecf20Sopenharmony_ci out_free_pfp: 1848c2ecf20Sopenharmony_ci kfree(pfp); 1858c2ecf20Sopenharmony_ci out_free_sfp: 1868c2ecf20Sopenharmony_ci kfree(sfp); 1878c2ecf20Sopenharmony_ci out_iput_fship: 1888c2ecf20Sopenharmony_ci iput(infp->vsi_fship); 1898c2ecf20Sopenharmony_ci return -EINVAL; 1908c2ecf20Sopenharmony_ci} 191