vxfs_super.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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. #ident "$Id: vxfs_super.c,v 1.29 2002/01/02 22:02:12 hch Exp hch $"
  30. /*
  31.  * Veritas filesystem driver - superblock related routines.
  32.  */
  33. #include <linux/init.h>
  34. #include <linux/module.h>
  35. #include <linux/blkdev.h>
  36. #include <linux/fs.h>
  37. #include <linux/kernel.h>
  38. #include <linux/slab.h>
  39. #include <linux/stat.h>
  40. #include "vxfs.h"
  41. #include "vxfs_extern.h"
  42. #include "vxfs_dir.h"
  43. #include "vxfs_inode.h"
  44. MODULE_AUTHOR("Christoph Hellwig");
  45. MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
  46. MODULE_LICENSE("Dual BSD/GPL");
  47. static void vxfs_put_super(struct super_block *);
  48. static int vxfs_statfs(struct super_block *, struct statfs *);
  49. static struct super_operations vxfs_super_ops = {
  50. .read_inode = vxfs_read_inode,
  51. .put_inode = vxfs_put_inode,
  52. .put_super = vxfs_put_super,
  53. .statfs = vxfs_statfs,
  54. };
  55. /**
  56.  * vxfs_put_super - free superblock resources
  57.  * @sbp: VFS superblock.
  58.  *
  59.  * Description:
  60.  *   vxfs_put_super frees all resources allocated for @sbp
  61.  *   after the last instance of the filesystem is unmounted.
  62.  */
  63. static void
  64. vxfs_put_super(struct super_block *sbp)
  65. {
  66. struct vxfs_sb_info *infp = VXFS_SBI(sbp);
  67. vxfs_put_fake_inode(infp->vsi_fship);
  68. vxfs_put_fake_inode(infp->vsi_ilist);
  69. vxfs_put_fake_inode(infp->vsi_stilist);
  70. brelse(infp->vsi_bp);
  71. kfree(infp);
  72. }
  73. /**
  74.  * vxfs_statfs - get filesystem information
  75.  * @sbp: VFS superblock
  76.  * @bufp: output buffer
  77.  *
  78.  * Description:
  79.  *   vxfs_statfs fills the statfs buffer @bufp with information
  80.  *   about the filesystem described by @sbp.
  81.  *
  82.  * Returns:
  83.  *   Zero.
  84.  *
  85.  * Locking:
  86.  *   We are under bkl and @sbp->s_lock.
  87.  *
  88.  * Notes:
  89.  *   This is everything but complete...
  90.  */
  91. static int
  92. vxfs_statfs(struct super_block *sbp, struct statfs *bufp)
  93. {
  94. struct vxfs_sb_info *infp = VXFS_SBI(sbp);
  95. bufp->f_type = VXFS_SUPER_MAGIC;
  96. bufp->f_bsize = sbp->s_blocksize;
  97. bufp->f_blocks = infp->vsi_raw->vs_dsize;
  98. bufp->f_bfree = infp->vsi_raw->vs_free;
  99. bufp->f_bavail = 0;
  100. bufp->f_files = 0;
  101. bufp->f_ffree = infp->vsi_raw->vs_ifree;
  102. bufp->f_namelen = VXFS_NAMELEN;
  103. return 0;
  104. }
  105. /**
  106.  * vxfs_read_super - read superblock into memory and initalize filesystem
  107.  * @sbp: VFS superblock (to fill)
  108.  * @dp: fs private mount data
  109.  * @silent: do not complain loudly when sth is wrong
  110.  *
  111.  * Description:
  112.  *   We are called on the first mount of a filesystem to read the
  113.  *   superblock into memory and do some basic setup.
  114.  *
  115.  * Returns:
  116.  *   The superblock on success, else %NULL.
  117.  *
  118.  * Locking:
  119.  *   We are under the bkl and @sbp->s_lock.
  120.  */
  121. static struct super_block *
  122. vxfs_read_super(struct super_block *sbp, void *dp, int silent)
  123. {
  124. struct vxfs_sb_info *infp;
  125. struct vxfs_sb *rsbp;
  126. struct buffer_head *bp = NULL;
  127. u_long bsize;
  128. infp = kmalloc(sizeof(*infp), GFP_KERNEL);
  129. if (!infp) {
  130. printk(KERN_WARNING "vxfs: unable to allocate incore superblockn");
  131. return NULL;
  132. }
  133. memset(infp, 0, sizeof(*infp));
  134. bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
  135. if (!bsize) {
  136. printk(KERN_WARNING "vxfs: unable to set blocksizen");
  137. goto out;
  138. }
  139. bp = sb_bread(sbp, 1);
  140. if (!bp || !buffer_mapped(bp)) {
  141. if (!silent) {
  142. printk(KERN_WARNING
  143. "vxfs: unable to read disk superblockn");
  144. }
  145. goto out;
  146. }
  147. rsbp = (struct vxfs_sb *)bp->b_data;
  148. if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
  149. if (!silent)
  150. printk(KERN_NOTICE "vxfs: WRONG superblock magicn");
  151. goto out;
  152. }
  153. if ((rsbp->vs_version < 2 || rsbp->vs_version > 4) && !silent) {
  154. printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)n",
  155.        rsbp->vs_version);
  156. goto out;
  157. }
  158. #ifdef DIAGNOSTIC
  159. printk(KERN_DEBUG "vxfs: supported VxFS version (%d)n", rsbp->vs_version);
  160. printk(KERN_DEBUG "vxfs: blocksize: %dn", rsbp->vs_bsize);
  161. #endif
  162. sbp->s_magic = rsbp->vs_magic;
  163. sbp->u.generic_sbp = (void *)infp;
  164. infp->vsi_raw = rsbp;
  165. infp->vsi_bp = bp;
  166. infp->vsi_oltext = rsbp->vs_oltext[0];
  167. infp->vsi_oltsize = rsbp->vs_oltsize;
  168. if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) {
  169. printk(KERN_WARNING "vxfs: unable to set final block sizen");
  170. goto out;
  171. }
  172. if (vxfs_read_olt(sbp, bsize)) {
  173. printk(KERN_WARNING "vxfs: unable to read oltn");
  174. goto out;
  175. }
  176. if (vxfs_read_fshead(sbp)) {
  177. printk(KERN_WARNING "vxfs: unable to read fsheadn");
  178. goto out;
  179. }
  180. sbp->s_op = &vxfs_super_ops;
  181. sbp->s_root = d_alloc_root(iget(sbp, VXFS_ROOT_INO));
  182. if (!sbp->s_root) {
  183. printk(KERN_WARNING "vxfs: unable to get root dentry.n");
  184. goto out_free_ilist;
  185. }
  186. return (sbp);
  187. out_free_ilist:
  188. vxfs_put_fake_inode(infp->vsi_fship);
  189. vxfs_put_fake_inode(infp->vsi_ilist);
  190. vxfs_put_fake_inode(infp->vsi_stilist);
  191. out:
  192. brelse(bp);
  193. kfree(infp);
  194. return NULL;
  195. }
  196. /*
  197.  * The usual module blurb.
  198.  */
  199. static DECLARE_FSTYPE_DEV(vxfs_fs_type, "vxfs", vxfs_read_super);
  200. static int __init
  201. vxfs_init(void)
  202. {
  203. vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
  204. sizeof(struct vxfs_inode_info), 0, 0, NULL, NULL);
  205. if (vxfs_inode_cachep)
  206. return (register_filesystem(&vxfs_fs_type));
  207. return -ENOMEM;
  208. }
  209. static void __exit
  210. vxfs_cleanup(void)
  211. {
  212. unregister_filesystem(&vxfs_fs_type);
  213. kmem_cache_destroy(vxfs_inode_cachep);
  214. }
  215. module_init(vxfs_init);
  216. module_exit(vxfs_cleanup);