vxfs_fshead.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2000-2001 Christoph Hellwig.
  4. * Copyright (c) 2016 Krzysztof Blaszkowski
  5. */
  6. /*
  7. * Veritas filesystem driver - fileset header routines.
  8. */
  9. #include <linux/fs.h>
  10. #include <linux/buffer_head.h>
  11. #include <linux/kernel.h>
  12. #include <linux/slab.h>
  13. #include <linux/string.h>
  14. #include "vxfs.h"
  15. #include "vxfs_inode.h"
  16. #include "vxfs_extern.h"
  17. #include "vxfs_fshead.h"
  18. #ifdef DIAGNOSTIC
  19. static void
  20. vxfs_dumpfsh(struct vxfs_fsh *fhp)
  21. {
  22. printk("\n\ndumping fileset header:\n");
  23. printk("----------------------------\n");
  24. printk("version: %u\n", fhp->fsh_version);
  25. printk("fsindex: %u\n", fhp->fsh_fsindex);
  26. printk("iauino: %u\tninodes:%u\n",
  27. fhp->fsh_iauino, fhp->fsh_ninodes);
  28. printk("maxinode: %u\tlctino: %u\n",
  29. fhp->fsh_maxinode, fhp->fsh_lctino);
  30. printk("nau: %u\n", fhp->fsh_nau);
  31. printk("ilistino[0]: %u\tilistino[1]: %u\n",
  32. fhp->fsh_ilistino[0], fhp->fsh_ilistino[1]);
  33. }
  34. #endif
  35. /**
  36. * vxfs_getfsh - read fileset header into memory
  37. * @ip: the (fake) fileset header inode
  38. * @which: 0 for the structural, 1 for the primary fsh.
  39. *
  40. * Description:
  41. * vxfs_getfsh reads either the structural or primary fileset header
  42. * described by @ip into memory.
  43. *
  44. * Returns:
  45. * The fileset header structure on success, else Zero.
  46. */
  47. static struct vxfs_fsh *
  48. vxfs_getfsh(struct inode *ip, int which)
  49. {
  50. struct buffer_head *bp;
  51. bp = vxfs_bread(ip, which);
  52. if (bp) {
  53. struct vxfs_fsh *fhp;
  54. if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
  55. goto out;
  56. memcpy(fhp, bp->b_data, sizeof(*fhp));
  57. put_bh(bp);
  58. return (fhp);
  59. }
  60. out:
  61. brelse(bp);
  62. return NULL;
  63. }
  64. /**
  65. * vxfs_read_fshead - read the fileset headers
  66. * @sbp: superblock to which the fileset belongs
  67. *
  68. * Description:
  69. * vxfs_read_fshead will fill the inode and structural inode list in @sb.
  70. *
  71. * Returns:
  72. * Zero on success, else a negative error code (-EINVAL).
  73. */
  74. int
  75. vxfs_read_fshead(struct super_block *sbp)
  76. {
  77. struct vxfs_sb_info *infp = VXFS_SBI(sbp);
  78. struct vxfs_fsh *pfp, *sfp;
  79. struct vxfs_inode_info *vip;
  80. infp->vsi_fship = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
  81. if (!infp->vsi_fship) {
  82. printk(KERN_ERR "vxfs: unable to read fsh inode\n");
  83. return -EINVAL;
  84. }
  85. vip = VXFS_INO(infp->vsi_fship);
  86. if (!VXFS_ISFSH(vip)) {
  87. printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
  88. vip->vii_mode & VXFS_TYPE_MASK);
  89. goto out_iput_fship;
  90. }
  91. #ifdef DIAGNOSTIC
  92. printk("vxfs: fsh inode dump:\n");
  93. vxfs_dumpi(vip, infp->vsi_fshino);
  94. #endif
  95. sfp = vxfs_getfsh(infp->vsi_fship, 0);
  96. if (!sfp) {
  97. printk(KERN_ERR "vxfs: unable to get structural fsh\n");
  98. goto out_iput_fship;
  99. }
  100. #ifdef DIAGNOSTIC
  101. vxfs_dumpfsh(sfp);
  102. #endif
  103. pfp = vxfs_getfsh(infp->vsi_fship, 1);
  104. if (!pfp) {
  105. printk(KERN_ERR "vxfs: unable to get primary fsh\n");
  106. goto out_free_sfp;
  107. }
  108. #ifdef DIAGNOSTIC
  109. vxfs_dumpfsh(pfp);
  110. #endif
  111. infp->vsi_stilist = vxfs_blkiget(sbp, infp->vsi_iext,
  112. fs32_to_cpu(infp, sfp->fsh_ilistino[0]));
  113. if (!infp->vsi_stilist) {
  114. printk(KERN_ERR "vxfs: unable to get structural list inode\n");
  115. goto out_free_pfp;
  116. }
  117. if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
  118. printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n",
  119. VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK);
  120. goto out_iput_stilist;
  121. }
  122. infp->vsi_ilist = vxfs_stiget(sbp, fs32_to_cpu(infp, pfp->fsh_ilistino[0]));
  123. if (!infp->vsi_ilist) {
  124. printk(KERN_ERR "vxfs: unable to get inode list inode\n");
  125. goto out_iput_stilist;
  126. }
  127. if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
  128. printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
  129. VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
  130. goto out_iput_ilist;
  131. }
  132. kfree(pfp);
  133. kfree(sfp);
  134. return 0;
  135. out_iput_ilist:
  136. iput(infp->vsi_ilist);
  137. out_iput_stilist:
  138. iput(infp->vsi_stilist);
  139. out_free_pfp:
  140. kfree(pfp);
  141. out_free_sfp:
  142. kfree(sfp);
  143. out_iput_fship:
  144. iput(infp->vsi_fship);
  145. return -EINVAL;
  146. }