~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to fs/freevxfs/vxfs_super.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 - superblock related routines.
 
32
 */
 
33
#include <linux/init.h>
 
34
#include <linux/module.h>
 
35
 
 
36
#include <linux/blkdev.h>
 
37
#include <linux/fs.h>
 
38
#include <linux/buffer_head.h>
 
39
#include <linux/kernel.h>
 
40
#include <linux/slab.h>
 
41
#include <linux/stat.h>
 
42
#include <linux/vfs.h>
 
43
#include <linux/mount.h>
 
44
 
 
45
#include "vxfs.h"
 
46
#include "vxfs_extern.h"
 
47
#include "vxfs_dir.h"
 
48
#include "vxfs_inode.h"
 
49
 
 
50
 
 
51
MODULE_AUTHOR("Christoph Hellwig");
 
52
MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
 
53
MODULE_LICENSE("Dual BSD/GPL");
 
54
 
 
55
MODULE_ALIAS("vxfs"); /* makes mount -t vxfs autoload the module */
 
56
 
 
57
 
 
58
static void             vxfs_put_super(struct super_block *);
 
59
static int              vxfs_statfs(struct dentry *, struct kstatfs *);
 
60
static int              vxfs_remount(struct super_block *, int *, char *);
 
61
 
 
62
static const struct super_operations vxfs_super_ops = {
 
63
        .evict_inode =          vxfs_evict_inode,
 
64
        .put_super =            vxfs_put_super,
 
65
        .statfs =               vxfs_statfs,
 
66
        .remount_fs =           vxfs_remount,
 
67
};
 
68
 
 
69
/**
 
70
 * vxfs_put_super - free superblock resources
 
71
 * @sbp:        VFS superblock.
 
72
 *
 
73
 * Description:
 
74
 *   vxfs_put_super frees all resources allocated for @sbp
 
75
 *   after the last instance of the filesystem is unmounted.
 
76
 */
 
77
 
 
78
static void
 
79
vxfs_put_super(struct super_block *sbp)
 
80
{
 
81
        struct vxfs_sb_info     *infp = VXFS_SBI(sbp);
 
82
 
 
83
        vxfs_put_fake_inode(infp->vsi_fship);
 
84
        vxfs_put_fake_inode(infp->vsi_ilist);
 
85
        vxfs_put_fake_inode(infp->vsi_stilist);
 
86
 
 
87
        brelse(infp->vsi_bp);
 
88
        kfree(infp);
 
89
}
 
90
 
 
91
/**
 
92
 * vxfs_statfs - get filesystem information
 
93
 * @dentry:     VFS dentry to locate superblock
 
94
 * @bufp:       output buffer
 
95
 *
 
96
 * Description:
 
97
 *   vxfs_statfs fills the statfs buffer @bufp with information
 
98
 *   about the filesystem described by @dentry.
 
99
 *
 
100
 * Returns:
 
101
 *   Zero.
 
102
 *
 
103
 * Locking:
 
104
 *   No locks held.
 
105
 *
 
106
 * Notes:
 
107
 *   This is everything but complete...
 
108
 */
 
109
static int
 
110
vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
 
111
{
 
112
        struct vxfs_sb_info             *infp = VXFS_SBI(dentry->d_sb);
 
113
 
 
114
        bufp->f_type = VXFS_SUPER_MAGIC;
 
115
        bufp->f_bsize = dentry->d_sb->s_blocksize;
 
116
        bufp->f_blocks = infp->vsi_raw->vs_dsize;
 
117
        bufp->f_bfree = infp->vsi_raw->vs_free;
 
118
        bufp->f_bavail = 0;
 
119
        bufp->f_files = 0;
 
120
        bufp->f_ffree = infp->vsi_raw->vs_ifree;
 
121
        bufp->f_namelen = VXFS_NAMELEN;
 
122
 
 
123
        return 0;
 
124
}
 
125
 
 
126
static int vxfs_remount(struct super_block *sb, int *flags, char *data)
 
127
{
 
128
        *flags |= MS_RDONLY;
 
129
        return 0;
 
130
}
 
131
 
 
132
/**
 
133
 * vxfs_read_super - read superblock into memory and initialize filesystem
 
134
 * @sbp:                VFS superblock (to fill)
 
135
 * @dp:                 fs private mount data
 
136
 * @silent:             do not complain loudly when sth is wrong
 
137
 *
 
138
 * Description:
 
139
 *   We are called on the first mount of a filesystem to read the
 
140
 *   superblock into memory and do some basic setup.
 
141
 *
 
142
 * Returns:
 
143
 *   The superblock on success, else %NULL.
 
144
 *
 
145
 * Locking:
 
146
 *   We are under @sbp->s_lock.
 
147
 */
 
148
static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 
149
{
 
150
        struct vxfs_sb_info     *infp;
 
151
        struct vxfs_sb          *rsbp;
 
152
        struct buffer_head      *bp = NULL;
 
153
        u_long                  bsize;
 
154
        struct inode *root;
 
155
        int ret = -EINVAL;
 
156
 
 
157
        sbp->s_flags |= MS_RDONLY;
 
158
 
 
159
        infp = kzalloc(sizeof(*infp), GFP_KERNEL);
 
160
        if (!infp) {
 
161
                printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
 
162
                return -ENOMEM;
 
163
        }
 
164
 
 
165
        bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
 
166
        if (!bsize) {
 
167
                printk(KERN_WARNING "vxfs: unable to set blocksize\n");
 
168
                goto out;
 
169
        }
 
170
 
 
171
        bp = sb_bread(sbp, 1);
 
172
        if (!bp || !buffer_mapped(bp)) {
 
173
                if (!silent) {
 
174
                        printk(KERN_WARNING
 
175
                                "vxfs: unable to read disk superblock\n");
 
176
                }
 
177
                goto out;
 
178
        }
 
179
 
 
180
        rsbp = (struct vxfs_sb *)bp->b_data;
 
181
        if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
 
182
                if (!silent)
 
183
                        printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
 
184
                goto out;
 
185
        }
 
186
 
 
187
        if ((rsbp->vs_version < 2 || rsbp->vs_version > 4) && !silent) {
 
188
                printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n",
 
189
                       rsbp->vs_version);
 
190
                goto out;
 
191
        }
 
192
 
 
193
#ifdef DIAGNOSTIC
 
194
        printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", rsbp->vs_version);
 
195
        printk(KERN_DEBUG "vxfs: blocksize: %d\n", rsbp->vs_bsize);
 
196
#endif
 
197
 
 
198
        sbp->s_magic = rsbp->vs_magic;
 
199
        sbp->s_fs_info = infp;
 
200
 
 
201
        infp->vsi_raw = rsbp;
 
202
        infp->vsi_bp = bp;
 
203
        infp->vsi_oltext = rsbp->vs_oltext[0];
 
204
        infp->vsi_oltsize = rsbp->vs_oltsize;
 
205
 
 
206
        if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) {
 
207
                printk(KERN_WARNING "vxfs: unable to set final block size\n");
 
208
                goto out;
 
209
        }
 
210
 
 
211
        if (vxfs_read_olt(sbp, bsize)) {
 
212
                printk(KERN_WARNING "vxfs: unable to read olt\n");
 
213
                goto out;
 
214
        }
 
215
 
 
216
        if (vxfs_read_fshead(sbp)) {
 
217
                printk(KERN_WARNING "vxfs: unable to read fshead\n");
 
218
                goto out;
 
219
        }
 
220
 
 
221
        sbp->s_op = &vxfs_super_ops;
 
222
        root = vxfs_iget(sbp, VXFS_ROOT_INO);
 
223
        if (IS_ERR(root)) {
 
224
                ret = PTR_ERR(root);
 
225
                goto out;
 
226
        }
 
227
        sbp->s_root = d_alloc_root(root);
 
228
        if (!sbp->s_root) {
 
229
                iput(root);
 
230
                printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
 
231
                goto out_free_ilist;
 
232
        }
 
233
 
 
234
        return 0;
 
235
        
 
236
out_free_ilist:
 
237
        vxfs_put_fake_inode(infp->vsi_fship);
 
238
        vxfs_put_fake_inode(infp->vsi_ilist);
 
239
        vxfs_put_fake_inode(infp->vsi_stilist);
 
240
out:
 
241
        brelse(bp);
 
242
        kfree(infp);
 
243
        return ret;
 
244
}
 
245
 
 
246
/*
 
247
 * The usual module blurb.
 
248
 */
 
249
static struct dentry *vxfs_mount(struct file_system_type *fs_type,
 
250
        int flags, const char *dev_name, void *data)
 
251
{
 
252
        return mount_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
 
253
}
 
254
 
 
255
static struct file_system_type vxfs_fs_type = {
 
256
        .owner          = THIS_MODULE,
 
257
        .name           = "vxfs",
 
258
        .mount          = vxfs_mount,
 
259
        .kill_sb        = kill_block_super,
 
260
        .fs_flags       = FS_REQUIRES_DEV,
 
261
};
 
262
 
 
263
static int __init
 
264
vxfs_init(void)
 
265
{
 
266
        int rv;
 
267
 
 
268
        vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
 
269
                        sizeof(struct vxfs_inode_info), 0,
 
270
                        SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
 
271
        if (!vxfs_inode_cachep)
 
272
                return -ENOMEM;
 
273
        rv = register_filesystem(&vxfs_fs_type);
 
274
        if (rv < 0)
 
275
                kmem_cache_destroy(vxfs_inode_cachep);
 
276
        return rv;
 
277
}
 
278
 
 
279
static void __exit
 
280
vxfs_cleanup(void)
 
281
{
 
282
        unregister_filesystem(&vxfs_fs_type);
 
283
        kmem_cache_destroy(vxfs_inode_cachep);
 
284
}
 
285
 
 
286
module_init(vxfs_init);
 
287
module_exit(vxfs_cleanup);