0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012
0013 #include <linux/blkdev.h>
0014 #include <linux/fs.h>
0015 #include <linux/buffer_head.h>
0016 #include <linux/kernel.h>
0017 #include <linux/slab.h>
0018 #include <linux/stat.h>
0019 #include <linux/vfs.h>
0020 #include <linux/mount.h>
0021
0022 #include "vxfs.h"
0023 #include "vxfs_extern.h"
0024 #include "vxfs_dir.h"
0025 #include "vxfs_inode.h"
0026
0027
0028 MODULE_AUTHOR("Christoph Hellwig, Krzysztof Blaszkowski");
0029 MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
0030 MODULE_LICENSE("Dual BSD/GPL");
0031
0032 static struct kmem_cache *vxfs_inode_cachep;
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 static void
0044 vxfs_put_super(struct super_block *sbp)
0045 {
0046 struct vxfs_sb_info *infp = VXFS_SBI(sbp);
0047
0048 iput(infp->vsi_fship);
0049 iput(infp->vsi_ilist);
0050 iput(infp->vsi_stilist);
0051
0052 brelse(infp->vsi_bp);
0053 kfree(infp);
0054 }
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 static int
0075 vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
0076 {
0077 struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb);
0078 struct vxfs_sb *raw_sb = infp->vsi_raw;
0079
0080 bufp->f_type = VXFS_SUPER_MAGIC;
0081 bufp->f_bsize = dentry->d_sb->s_blocksize;
0082 bufp->f_blocks = fs32_to_cpu(infp, raw_sb->vs_dsize);
0083 bufp->f_bfree = fs32_to_cpu(infp, raw_sb->vs_free);
0084 bufp->f_bavail = 0;
0085 bufp->f_files = 0;
0086 bufp->f_ffree = fs32_to_cpu(infp, raw_sb->vs_ifree);
0087 bufp->f_namelen = VXFS_NAMELEN;
0088
0089 return 0;
0090 }
0091
0092 static int vxfs_remount(struct super_block *sb, int *flags, char *data)
0093 {
0094 sync_filesystem(sb);
0095 *flags |= SB_RDONLY;
0096 return 0;
0097 }
0098
0099 static struct inode *vxfs_alloc_inode(struct super_block *sb)
0100 {
0101 struct vxfs_inode_info *vi;
0102
0103 vi = alloc_inode_sb(sb, vxfs_inode_cachep, GFP_KERNEL);
0104 if (!vi)
0105 return NULL;
0106 inode_init_once(&vi->vfs_inode);
0107 return &vi->vfs_inode;
0108 }
0109
0110 static void vxfs_free_inode(struct inode *inode)
0111 {
0112 kmem_cache_free(vxfs_inode_cachep, VXFS_INO(inode));
0113 }
0114
0115 static const struct super_operations vxfs_super_ops = {
0116 .alloc_inode = vxfs_alloc_inode,
0117 .free_inode = vxfs_free_inode,
0118 .evict_inode = vxfs_evict_inode,
0119 .put_super = vxfs_put_super,
0120 .statfs = vxfs_statfs,
0121 .remount_fs = vxfs_remount,
0122 };
0123
0124 static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
0125 unsigned blk, __fs32 magic)
0126 {
0127 struct buffer_head *bp;
0128 struct vxfs_sb *rsbp;
0129 struct vxfs_sb_info *infp = VXFS_SBI(sbp);
0130 int rc = -ENOMEM;
0131
0132 bp = sb_bread(sbp, blk);
0133 do {
0134 if (!bp || !buffer_mapped(bp)) {
0135 if (!silent) {
0136 printk(KERN_WARNING
0137 "vxfs: unable to read disk superblock at %u\n",
0138 blk);
0139 }
0140 break;
0141 }
0142
0143 rc = -EINVAL;
0144 rsbp = (struct vxfs_sb *)bp->b_data;
0145 if (rsbp->vs_magic != magic) {
0146 if (!silent)
0147 printk(KERN_NOTICE
0148 "vxfs: WRONG superblock magic %08x at %u\n",
0149 rsbp->vs_magic, blk);
0150 break;
0151 }
0152
0153 rc = 0;
0154 infp->vsi_raw = rsbp;
0155 infp->vsi_bp = bp;
0156 } while (0);
0157
0158 if (rc) {
0159 infp->vsi_raw = NULL;
0160 infp->vsi_bp = NULL;
0161 brelse(bp);
0162 }
0163
0164 return rc;
0165 }
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
0184 {
0185 struct vxfs_sb_info *infp;
0186 struct vxfs_sb *rsbp;
0187 u_long bsize;
0188 struct inode *root;
0189 int ret = -EINVAL;
0190 u32 j;
0191
0192 sbp->s_flags |= SB_RDONLY;
0193
0194 infp = kzalloc(sizeof(*infp), GFP_KERNEL);
0195 if (!infp) {
0196 printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
0197 return -ENOMEM;
0198 }
0199
0200 bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
0201 if (!bsize) {
0202 printk(KERN_WARNING "vxfs: unable to set blocksize\n");
0203 goto out;
0204 }
0205
0206 sbp->s_op = &vxfs_super_ops;
0207 sbp->s_fs_info = infp;
0208 sbp->s_time_min = 0;
0209 sbp->s_time_max = U32_MAX;
0210
0211 if (!vxfs_try_sb_magic(sbp, silent, 1,
0212 (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
0213
0214 infp->byte_order = VXFS_BO_LE;
0215 } else if (!vxfs_try_sb_magic(sbp, silent, 8,
0216 (__force __fs32)cpu_to_be32(VXFS_SUPER_MAGIC))) {
0217
0218 infp->byte_order = VXFS_BO_BE;
0219 } else {
0220 if (!silent)
0221 printk(KERN_NOTICE "vxfs: can't find superblock.\n");
0222 goto out;
0223 }
0224
0225 rsbp = infp->vsi_raw;
0226 j = fs32_to_cpu(infp, rsbp->vs_version);
0227 if ((j < 2 || j > 4) && !silent) {
0228 printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", j);
0229 goto out;
0230 }
0231
0232 #ifdef DIAGNOSTIC
0233 printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
0234 printk(KERN_DEBUG "vxfs: blocksize: %d\n",
0235 fs32_to_cpu(infp, rsbp->vs_bsize));
0236 #endif
0237
0238 sbp->s_magic = fs32_to_cpu(infp, rsbp->vs_magic);
0239
0240 infp->vsi_oltext = fs32_to_cpu(infp, rsbp->vs_oltext[0]);
0241 infp->vsi_oltsize = fs32_to_cpu(infp, rsbp->vs_oltsize);
0242
0243 j = fs32_to_cpu(infp, rsbp->vs_bsize);
0244 if (!sb_set_blocksize(sbp, j)) {
0245 printk(KERN_WARNING "vxfs: unable to set final block size\n");
0246 goto out;
0247 }
0248
0249 if (vxfs_read_olt(sbp, bsize)) {
0250 printk(KERN_WARNING "vxfs: unable to read olt\n");
0251 goto out;
0252 }
0253
0254 if (vxfs_read_fshead(sbp)) {
0255 printk(KERN_WARNING "vxfs: unable to read fshead\n");
0256 goto out;
0257 }
0258
0259 root = vxfs_iget(sbp, VXFS_ROOT_INO);
0260 if (IS_ERR(root)) {
0261 ret = PTR_ERR(root);
0262 goto out;
0263 }
0264 sbp->s_root = d_make_root(root);
0265 if (!sbp->s_root) {
0266 printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
0267 goto out_free_ilist;
0268 }
0269
0270 return 0;
0271
0272 out_free_ilist:
0273 iput(infp->vsi_fship);
0274 iput(infp->vsi_ilist);
0275 iput(infp->vsi_stilist);
0276 out:
0277 brelse(infp->vsi_bp);
0278 kfree(infp);
0279 return ret;
0280 }
0281
0282
0283
0284
0285 static struct dentry *vxfs_mount(struct file_system_type *fs_type,
0286 int flags, const char *dev_name, void *data)
0287 {
0288 return mount_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
0289 }
0290
0291 static struct file_system_type vxfs_fs_type = {
0292 .owner = THIS_MODULE,
0293 .name = "vxfs",
0294 .mount = vxfs_mount,
0295 .kill_sb = kill_block_super,
0296 .fs_flags = FS_REQUIRES_DEV,
0297 };
0298 MODULE_ALIAS_FS("vxfs");
0299 MODULE_ALIAS("vxfs");
0300
0301 static int __init
0302 vxfs_init(void)
0303 {
0304 int rv;
0305
0306 vxfs_inode_cachep = kmem_cache_create_usercopy("vxfs_inode",
0307 sizeof(struct vxfs_inode_info), 0,
0308 SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
0309 offsetof(struct vxfs_inode_info, vii_immed.vi_immed),
0310 sizeof_field(struct vxfs_inode_info,
0311 vii_immed.vi_immed),
0312 NULL);
0313 if (!vxfs_inode_cachep)
0314 return -ENOMEM;
0315 rv = register_filesystem(&vxfs_fs_type);
0316 if (rv < 0)
0317 kmem_cache_destroy(vxfs_inode_cachep);
0318 return rv;
0319 }
0320
0321 static void __exit
0322 vxfs_cleanup(void)
0323 {
0324 unregister_filesystem(&vxfs_fs_type);
0325
0326
0327
0328
0329 rcu_barrier();
0330 kmem_cache_destroy(vxfs_inode_cachep);
0331 }
0332
0333 module_init(vxfs_init);
0334 module_exit(vxfs_cleanup);