vxfs_olt.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2000-2001 Christoph Hellwig.
  4. */
  5. /*
  6. * Veritas filesystem driver - object location table support.
  7. */
  8. #include <linux/fs.h>
  9. #include <linux/buffer_head.h>
  10. #include <linux/kernel.h>
  11. #include "vxfs.h"
  12. #include "vxfs_olt.h"
  13. #include "vxfs_extern.h"
  14. static inline void
  15. vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
  16. {
  17. BUG_ON(infp->vsi_fshino);
  18. infp->vsi_fshino = fs32_to_cpu(infp, fshp->olt_fsino[0]);
  19. }
  20. static inline void
  21. vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
  22. {
  23. BUG_ON(infp->vsi_iext);
  24. infp->vsi_iext = fs32_to_cpu(infp, ilistp->olt_iext[0]);
  25. }
  26. static inline u_long
  27. vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
  28. {
  29. BUG_ON(sbp->s_blocksize % bsize);
  30. return (block * (sbp->s_blocksize / bsize));
  31. }
  32. /**
  33. * vxfs_read_olt - read olt
  34. * @sbp: superblock of the filesystem
  35. * @bsize: blocksize of the filesystem
  36. *
  37. * Description:
  38. * vxfs_read_olt reads the olt of the filesystem described by @sbp
  39. * into main memory and does some basic setup.
  40. *
  41. * Returns:
  42. * Zero on success, else a negative error code.
  43. */
  44. int
  45. vxfs_read_olt(struct super_block *sbp, u_long bsize)
  46. {
  47. struct vxfs_sb_info *infp = VXFS_SBI(sbp);
  48. struct buffer_head *bp;
  49. struct vxfs_olt *op;
  50. char *oaddr, *eaddr;
  51. bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
  52. if (!bp || !bp->b_data)
  53. goto fail;
  54. op = (struct vxfs_olt *)bp->b_data;
  55. if (fs32_to_cpu(infp, op->olt_magic) != VXFS_OLT_MAGIC) {
  56. printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
  57. goto fail;
  58. }
  59. /*
  60. * It is in theory possible that vsi_oltsize is > 1.
  61. * I've not seen any such filesystem yet and I'm lazy.. --hch
  62. */
  63. if (infp->vsi_oltsize > 1) {
  64. printk(KERN_NOTICE "vxfs: oltsize > 1 detected.\n");
  65. printk(KERN_NOTICE "vxfs: please notify [email protected]\n");
  66. goto fail;
  67. }
  68. oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
  69. eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
  70. while (oaddr < eaddr) {
  71. struct vxfs_oltcommon *ocp =
  72. (struct vxfs_oltcommon *)oaddr;
  73. switch (fs32_to_cpu(infp, ocp->olt_type)) {
  74. case VXFS_OLT_FSHEAD:
  75. vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
  76. break;
  77. case VXFS_OLT_ILIST:
  78. vxfs_get_ilist((struct vxfs_oltilist *)oaddr, infp);
  79. break;
  80. }
  81. oaddr += fs32_to_cpu(infp, ocp->olt_size);
  82. }
  83. brelse(bp);
  84. return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
  85. fail:
  86. brelse(bp);
  87. return -EINVAL;
  88. }