Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vxfs_fshead.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2001 Christoph Hellwig.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions, and the following disclaimer,
10  * without modification.
11  * 2. The name of the author may not be used to endorse or promote products
12  * derived from this software without specific prior written permission.
13  *
14  * Alternatively, this software may be distributed under the terms of the
15  * GNU General Public License ("GPL").
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * Veritas filesystem driver - fileset header routines.
32  */
33 #include <linux/fs.h>
34 #include <linux/buffer_head.h>
35 #include <linux/kernel.h>
36 #include <linux/slab.h>
37 #include <linux/string.h>
38 
39 #include "vxfs.h"
40 #include "vxfs_inode.h"
41 #include "vxfs_extern.h"
42 #include "vxfs_fshead.h"
43 
44 
45 #ifdef DIAGNOSTIC
46 static void
47 vxfs_dumpfsh(struct vxfs_fsh *fhp)
48 {
49  printk("\n\ndumping fileset header:\n");
50  printk("----------------------------\n");
51  printk("version: %u\n", fhp->fsh_version);
52  printk("fsindex: %u\n", fhp->fsh_fsindex);
53  printk("iauino: %u\tninodes:%u\n",
54  fhp->fsh_iauino, fhp->fsh_ninodes);
55  printk("maxinode: %u\tlctino: %u\n",
56  fhp->fsh_maxinode, fhp->fsh_lctino);
57  printk("nau: %u\n", fhp->fsh_nau);
58  printk("ilistino[0]: %u\tilistino[1]: %u\n",
59  fhp->fsh_ilistino[0], fhp->fsh_ilistino[1]);
60 }
61 #endif
62 
75 static struct vxfs_fsh *
76 vxfs_getfsh(struct inode *ip, int which)
77 {
78  struct buffer_head *bp;
79 
80  bp = vxfs_bread(ip, which);
81  if (bp) {
82  struct vxfs_fsh *fhp;
83 
84  if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
85  goto out;
86  memcpy(fhp, bp->b_data, sizeof(*fhp));
87 
88  put_bh(bp);
89  return (fhp);
90  }
91 out:
92  brelse(bp);
93  return NULL;
94 }
95 
106 int
108 {
109  struct vxfs_sb_info *infp = VXFS_SBI(sbp);
110  struct vxfs_fsh *pfp, *sfp;
111  struct vxfs_inode_info *vip, *tip;
112 
113  vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
114  if (!vip) {
115  printk(KERN_ERR "vxfs: unable to read fsh inode\n");
116  return -EINVAL;
117  }
118  if (!VXFS_ISFSH(vip)) {
119  printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
120  vip->vii_mode & VXFS_TYPE_MASK);
121  goto out_free_fship;
122  }
123 
124 
125 #ifdef DIAGNOSTIC
126  printk("vxfs: fsh inode dump:\n");
127  vxfs_dumpi(vip, infp->vsi_fshino);
128 #endif
129 
130  infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
131  if (!infp->vsi_fship) {
132  printk(KERN_ERR "vxfs: unable to get fsh inode\n");
133  goto out_free_fship;
134  }
135 
136  sfp = vxfs_getfsh(infp->vsi_fship, 0);
137  if (!sfp) {
138  printk(KERN_ERR "vxfs: unable to get structural fsh\n");
139  goto out_iput_fship;
140  }
141 
142 #ifdef DIAGNOSTIC
143  vxfs_dumpfsh(sfp);
144 #endif
145 
146  pfp = vxfs_getfsh(infp->vsi_fship, 1);
147  if (!pfp) {
148  printk(KERN_ERR "vxfs: unable to get primary fsh\n");
149  goto out_free_sfp;
150  }
151 
152 #ifdef DIAGNOSTIC
153  vxfs_dumpfsh(pfp);
154 #endif
155 
156  tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
157  if (!tip)
158  goto out_free_pfp;
159 
160  infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
161  if (!infp->vsi_stilist) {
162  printk(KERN_ERR "vxfs: unable to get structural list inode\n");
163  kfree(tip);
164  goto out_free_pfp;
165  }
166  if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
167  printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n",
168  VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK);
169  goto out_iput_stilist;
170  }
171 
172  tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
173  if (!tip)
174  goto out_iput_stilist;
175  infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
176  if (!infp->vsi_ilist) {
177  printk(KERN_ERR "vxfs: unable to get inode list inode\n");
178  kfree(tip);
179  goto out_iput_stilist;
180  }
181  if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
182  printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
183  VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
184  goto out_iput_ilist;
185  }
186 
187  return 0;
188 
189  out_iput_ilist:
190  iput(infp->vsi_ilist);
191  out_iput_stilist:
192  iput(infp->vsi_stilist);
193  out_free_pfp:
194  kfree(pfp);
195  out_free_sfp:
196  kfree(sfp);
197  out_iput_fship:
198  iput(infp->vsi_fship);
199  return -EINVAL;
200  out_free_fship:
201  kfree(vip);
202  return -EINVAL;
203 }