blob: 9e0e9be1e41ddc4d973ca5515496401c3d97e77a [file] [log] [blame]
David Teiglandb3b94fa2006-01-16 16:50:04 +00001/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
Steven Whitehouse3a8a9a12006-05-18 15:09:15 -04003 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
David Teiglandb3b94fa2006-01-16 16:50:04 +00004 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
Steven Whitehousee9fc2aa2006-09-01 11:05:15 -04007 * of the GNU General Public License version 2.
David Teiglandb3b94fa2006-01-16 16:50:04 +00008 */
9
10#include <linux/sched.h>
11#include <linux/slab.h>
12#include <linux/spinlock.h>
13#include <linux/completion.h>
14#include <linux/buffer_head.h>
David Teiglandb3b94fa2006-01-16 16:50:04 +000015#include <linux/blkdev.h>
16#include <linux/kthread.h>
Abhijith Das86384602006-08-25 11:13:37 -050017#include <linux/namei.h>
18#include <linux/mount.h>
Steven Whitehouse5c676f62006-02-27 17:23:27 -050019#include <linux/gfs2_ondisk.h>
Fabio Massimo Di Nitto7d308592006-09-19 07:56:29 +020020#include <linux/lm_interface.h>
David Teiglandb3b94fa2006-01-16 16:50:04 +000021
22#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050023#include "incore.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000024#include "daemon.h"
25#include "glock.h"
26#include "glops.h"
27#include "inode.h"
28#include "lm.h"
29#include "mount.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000030#include "ops_fstype.h"
Denis Chengca5a9392007-07-31 18:31:12 +080031#include "ops_dentry.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000032#include "ops_super.h"
33#include "recovery.h"
34#include "rgrp.h"
35#include "super.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000036#include "sys.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050037#include "util.h"
Steven Whitehousebb3b0e32007-08-16 16:03:57 +010038#include "log.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000039
40#define DO 0
41#define UNDO 1
42
43static struct gfs2_sbd *init_sbd(struct super_block *sb)
44{
45 struct gfs2_sbd *sdp;
David Teiglandb3b94fa2006-01-16 16:50:04 +000046
Steven Whitehouse85d1da62006-09-07 14:40:21 -040047 sdp = kzalloc(sizeof(struct gfs2_sbd), GFP_KERNEL);
David Teiglandb3b94fa2006-01-16 16:50:04 +000048 if (!sdp)
49 return NULL;
50
Steven Whitehouse5c676f62006-02-27 17:23:27 -050051 sb->s_fs_info = sdp;
David Teiglandb3b94fa2006-01-16 16:50:04 +000052 sdp->sd_vfs = sb;
53
54 gfs2_tune_init(&sdp->sd_tune);
55
David Teiglandb3b94fa2006-01-16 16:50:04 +000056 INIT_LIST_HEAD(&sdp->sd_reclaim_list);
57 spin_lock_init(&sdp->sd_reclaim_lock);
58 init_waitqueue_head(&sdp->sd_reclaim_wq);
David Teiglandb3b94fa2006-01-16 16:50:04 +000059
Steven Whitehousef55ab262006-02-21 12:51:39 +000060 mutex_init(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +000061 spin_lock_init(&sdp->sd_statfs_spin);
Steven Whitehousef55ab262006-02-21 12:51:39 +000062 mutex_init(&sdp->sd_statfs_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +000063
64 spin_lock_init(&sdp->sd_rindex_spin);
Steven Whitehousef55ab262006-02-21 12:51:39 +000065 mutex_init(&sdp->sd_rindex_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +000066 INIT_LIST_HEAD(&sdp->sd_rindex_list);
67 INIT_LIST_HEAD(&sdp->sd_rindex_mru_list);
68 INIT_LIST_HEAD(&sdp->sd_rindex_recent_list);
69
70 INIT_LIST_HEAD(&sdp->sd_jindex_list);
71 spin_lock_init(&sdp->sd_jindex_spin);
Steven Whitehousef55ab262006-02-21 12:51:39 +000072 mutex_init(&sdp->sd_jindex_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +000073
David Teiglandb3b94fa2006-01-16 16:50:04 +000074 INIT_LIST_HEAD(&sdp->sd_quota_list);
75 spin_lock_init(&sdp->sd_quota_spin);
Steven Whitehousef55ab262006-02-21 12:51:39 +000076 mutex_init(&sdp->sd_quota_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +000077
78 spin_lock_init(&sdp->sd_log_lock);
David Teiglandb3b94fa2006-01-16 16:50:04 +000079
80 INIT_LIST_HEAD(&sdp->sd_log_le_gl);
81 INIT_LIST_HEAD(&sdp->sd_log_le_buf);
82 INIT_LIST_HEAD(&sdp->sd_log_le_revoke);
83 INIT_LIST_HEAD(&sdp->sd_log_le_rg);
84 INIT_LIST_HEAD(&sdp->sd_log_le_databuf);
85
Steven Whitehouse71b86f52006-03-28 14:14:04 -050086 mutex_init(&sdp->sd_log_reserve_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +000087 INIT_LIST_HEAD(&sdp->sd_ail1_list);
88 INIT_LIST_HEAD(&sdp->sd_ail2_list);
89
Steven Whitehouse484adff2006-03-29 09:12:12 -050090 init_rwsem(&sdp->sd_log_flush_lock);
David Teiglandb3b94fa2006-01-16 16:50:04 +000091 INIT_LIST_HEAD(&sdp->sd_log_flush_list);
92
93 INIT_LIST_HEAD(&sdp->sd_revoke_list);
94
Steven Whitehousef55ab262006-02-21 12:51:39 +000095 mutex_init(&sdp->sd_freeze_lock);
David Teiglandb3b94fa2006-01-16 16:50:04 +000096
97 return sdp;
98}
99
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500100static void init_vfs(struct super_block *sb, unsigned noatime)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000101{
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500102 struct gfs2_sbd *sdp = sb->s_fs_info;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000103
104 sb->s_magic = GFS2_MAGIC;
105 sb->s_op = &gfs2_super_ops;
106 sb->s_export_op = &gfs2_export_ops;
Steven Whitehouse4bd91ba2007-06-05 09:39:18 +0100107 sb->s_time_gran = 1;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000108 sb->s_maxbytes = MAX_LFS_FILESIZE;
109
110 if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500111 set_bit(noatime, &sdp->sd_flags);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000112
113 /* Don't let the VFS update atimes. GFS2 handles this itself. */
114 sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000115}
116
117static int init_names(struct gfs2_sbd *sdp, int silent)
118{
David Teiglandb3b94fa2006-01-16 16:50:04 +0000119 char *proto, *table;
120 int error = 0;
121
122 proto = sdp->sd_args.ar_lockproto;
123 table = sdp->sd_args.ar_locktable;
124
125 /* Try to autodetect */
126
127 if (!proto[0] || !table[0]) {
Steven Whitehousebb8d8a62007-06-01 14:11:58 +0100128 error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
129 if (error)
130 return error;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000131
Steven Whitehouse3cf1e7b2006-10-02 11:49:41 -0400132 error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000133 if (error)
134 goto out;
135
136 if (!proto[0])
Steven Whitehouse3cf1e7b2006-10-02 11:49:41 -0400137 proto = sdp->sd_sb.sb_lockproto;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000138 if (!table[0])
Steven Whitehouse3cf1e7b2006-10-02 11:49:41 -0400139 table = sdp->sd_sb.sb_locktable;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000140 }
141
142 if (!table[0])
143 table = sdp->sd_vfs->s_id;
144
145 snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto);
146 snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table);
147
Denis Cheng5d35e312007-08-13 11:01:58 +0800148 table = sdp->sd_table_name;
149 while ((table = strchr(table, '/')))
Robert Petersonb35997d2007-06-07 09:10:01 -0500150 *table = '_';
151
Steven Whitehousea91ea692006-09-04 12:04:26 -0400152out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000153 return error;
154}
155
156static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
157 int undo)
158{
159 struct task_struct *p;
160 int error = 0;
161
162 if (undo)
163 goto fail_trans;
164
David Teiglandb3b94fa2006-01-16 16:50:04 +0000165 for (sdp->sd_glockd_num = 0;
166 sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd;
167 sdp->sd_glockd_num++) {
168 p = kthread_run(gfs2_glockd, sdp, "gfs2_glockd");
169 error = IS_ERR(p);
170 if (error) {
171 fs_err(sdp, "can't start glockd thread: %d\n", error);
172 goto fail;
173 }
174 sdp->sd_glockd_process[sdp->sd_glockd_num] = p;
175 }
176
177 error = gfs2_glock_nq_num(sdp,
178 GFS2_MOUNT_LOCK, &gfs2_nondisk_glops,
179 LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE,
180 mount_gh);
181 if (error) {
182 fs_err(sdp, "can't acquire mount glock: %d\n", error);
183 goto fail;
184 }
185
186 error = gfs2_glock_nq_num(sdp,
187 GFS2_LIVE_LOCK, &gfs2_nondisk_glops,
188 LM_ST_SHARED,
Steven Whitehouse579b78a2006-04-26 14:58:26 -0400189 LM_FLAG_NOEXP | GL_EXACT,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000190 &sdp->sd_live_gh);
191 if (error) {
192 fs_err(sdp, "can't acquire live glock: %d\n", error);
193 goto fail_mount;
194 }
195
196 error = gfs2_glock_get(sdp, GFS2_RENAME_LOCK, &gfs2_nondisk_glops,
197 CREATE, &sdp->sd_rename_gl);
198 if (error) {
199 fs_err(sdp, "can't create rename glock: %d\n", error);
200 goto fail_live;
201 }
202
203 error = gfs2_glock_get(sdp, GFS2_TRANS_LOCK, &gfs2_trans_glops,
204 CREATE, &sdp->sd_trans_gl);
205 if (error) {
206 fs_err(sdp, "can't create transaction glock: %d\n", error);
207 goto fail_rename;
208 }
209 set_bit(GLF_STICKY, &sdp->sd_trans_gl->gl_flags);
210
211 return 0;
212
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400213fail_trans:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000214 gfs2_glock_put(sdp->sd_trans_gl);
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400215fail_rename:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000216 gfs2_glock_put(sdp->sd_rename_gl);
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400217fail_live:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000218 gfs2_glock_dq_uninit(&sdp->sd_live_gh);
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400219fail_mount:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000220 gfs2_glock_dq_uninit(mount_gh);
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400221fail:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000222 while (sdp->sd_glockd_num--)
223 kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
224
David Teiglandb3b94fa2006-01-16 16:50:04 +0000225 return error;
226}
227
Steven Whitehousedbb7cae2007-05-15 15:37:50 +0100228static inline struct inode *gfs2_lookup_root(struct super_block *sb,
229 u64 no_addr)
Steven Whitehousef42faf42006-01-30 18:34:10 +0000230{
Wendy Chengbb9bcf02007-06-27 17:07:08 -0400231 return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000232}
233
David Teiglandb3b94fa2006-01-16 16:50:04 +0000234static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
235{
236 struct super_block *sb = sdp->sd_vfs;
237 struct gfs2_holder sb_gh;
Steven Whitehousedbb7cae2007-05-15 15:37:50 +0100238 u64 no_addr;
Steven Whitehousef42faf42006-01-30 18:34:10 +0000239 struct inode *inode;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000240 int error = 0;
241
242 if (undo) {
Russell Cattelan88721872006-08-10 11:08:40 -0500243 if (sb->s_root) {
244 dput(sb->s_root);
245 sb->s_root = NULL;
246 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000247 return 0;
248 }
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400249
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400250 error = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000251 LM_ST_SHARED, 0, &sb_gh);
252 if (error) {
253 fs_err(sdp, "can't acquire superblock glock: %d\n", error);
254 return error;
255 }
256
257 error = gfs2_read_sb(sdp, sb_gh.gh_gl, silent);
258 if (error) {
259 fs_err(sdp, "can't read superblock: %d\n", error);
260 goto out;
261 }
262
263 /* Set up the buffer cache and SB for real */
David Teiglandb3b94fa2006-01-16 16:50:04 +0000264 if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) {
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500265 error = -EINVAL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000266 fs_err(sdp, "FS block size (%u) is too small for device "
267 "block size (%u)\n",
268 sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev));
269 goto out;
270 }
271 if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500272 error = -EINVAL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000273 fs_err(sdp, "FS block size (%u) is too big for machine "
274 "page size (%u)\n",
275 sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE);
276 goto out;
277 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000278 sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
279
Steven Whitehousef42faf42006-01-30 18:34:10 +0000280 /* Get the root inode */
Steven Whitehousedbb7cae2007-05-15 15:37:50 +0100281 no_addr = sdp->sd_sb.sb_root_dir.no_addr;
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500282 if (sb->s_type == &gfs2meta_fs_type)
Steven Whitehousedbb7cae2007-05-15 15:37:50 +0100283 no_addr = sdp->sd_sb.sb_master_dir.no_addr;
284 inode = gfs2_lookup_root(sb, no_addr);
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500285 if (IS_ERR(inode)) {
286 error = PTR_ERR(inode);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000287 fs_err(sdp, "can't read in root inode: %d\n", error);
288 goto out;
289 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000290
Steven Whitehousef42faf42006-01-30 18:34:10 +0000291 sb->s_root = d_alloc_root(inode);
292 if (!sb->s_root) {
293 fs_err(sdp, "can't get root dentry\n");
294 error = -ENOMEM;
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500295 iput(inode);
Denis Cheng34eaae32007-08-15 23:54:44 +0800296 } else
297 sb->s_root->d_op = &gfs2_dops;
298
Steven Whitehousef42faf42006-01-30 18:34:10 +0000299out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000300 gfs2_glock_dq_uninit(&sb_gh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000301 return error;
302}
303
304static int init_journal(struct gfs2_sbd *sdp, int undo)
305{
306 struct gfs2_holder ji_gh;
307 struct task_struct *p;
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500308 struct gfs2_inode *ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000309 int jindex = 1;
310 int error = 0;
311
312 if (undo) {
313 jindex = 0;
314 goto fail_recoverd;
315 }
316
Steven Whitehousec7526662006-03-20 12:30:04 -0500317 sdp->sd_jindex = gfs2_lookup_simple(sdp->sd_master_dir, "jindex");
318 if (IS_ERR(sdp->sd_jindex)) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000319 fs_err(sdp, "can't lookup journal index: %d\n", error);
Steven Whitehousec7526662006-03-20 12:30:04 -0500320 return PTR_ERR(sdp->sd_jindex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000321 }
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400322 ip = GFS2_I(sdp->sd_jindex);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500323 set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000324
325 /* Load in the journal index special file */
326
327 error = gfs2_jindex_hold(sdp, &ji_gh);
328 if (error) {
329 fs_err(sdp, "can't read journal index: %d\n", error);
330 goto fail;
331 }
332
333 error = -EINVAL;
334 if (!gfs2_jindex_size(sdp)) {
335 fs_err(sdp, "no journals!\n");
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400336 goto fail_jindex;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000337 }
338
339 if (sdp->sd_args.ar_spectator) {
340 sdp->sd_jdesc = gfs2_jdesc_find(sdp, 0);
341 sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks;
342 } else {
343 if (sdp->sd_lockstruct.ls_jid >= gfs2_jindex_size(sdp)) {
344 fs_err(sdp, "can't mount journal #%u\n",
345 sdp->sd_lockstruct.ls_jid);
346 fs_err(sdp, "there are only %u journals (0 - %u)\n",
347 gfs2_jindex_size(sdp),
348 gfs2_jindex_size(sdp) - 1);
349 goto fail_jindex;
350 }
351 sdp->sd_jdesc = gfs2_jdesc_find(sdp, sdp->sd_lockstruct.ls_jid);
352
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400353 error = gfs2_glock_nq_num(sdp, sdp->sd_lockstruct.ls_jid,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000354 &gfs2_journal_glops,
355 LM_ST_EXCLUSIVE, LM_FLAG_NOEXP,
356 &sdp->sd_journal_gh);
357 if (error) {
358 fs_err(sdp, "can't acquire journal glock: %d\n", error);
359 goto fail_jindex;
360 }
361
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400362 ip = GFS2_I(sdp->sd_jdesc->jd_inode);
363 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
Bob Peterson75be73a2007-08-08 17:08:14 -0500364 LM_FLAG_NOEXP | GL_EXACT | GL_NOCACHE,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000365 &sdp->sd_jinode_gh);
366 if (error) {
367 fs_err(sdp, "can't acquire journal inode glock: %d\n",
368 error);
369 goto fail_journal_gh;
370 }
371
372 error = gfs2_jdesc_check(sdp->sd_jdesc);
373 if (error) {
374 fs_err(sdp, "my journal (%u) is bad: %d\n",
375 sdp->sd_jdesc->jd_jid, error);
376 goto fail_jinode_gh;
377 }
378 sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks;
379 }
380
381 if (sdp->sd_lockstruct.ls_first) {
382 unsigned int x;
383 for (x = 0; x < sdp->sd_journals; x++) {
David Teiglandc63e31c2006-04-20 17:03:48 -0400384 error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x));
David Teiglandb3b94fa2006-01-16 16:50:04 +0000385 if (error) {
386 fs_err(sdp, "error recovering journal %u: %d\n",
387 x, error);
388 goto fail_jinode_gh;
389 }
390 }
391
392 gfs2_lm_others_may_mount(sdp);
393 } else if (!sdp->sd_args.ar_spectator) {
David Teiglandc63e31c2006-04-20 17:03:48 -0400394 error = gfs2_recover_journal(sdp->sd_jdesc);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000395 if (error) {
396 fs_err(sdp, "error recovering my journal: %d\n", error);
397 goto fail_jinode_gh;
398 }
399 }
400
401 set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags);
402 gfs2_glock_dq_uninit(&ji_gh);
403 jindex = 0;
404
David Teiglandb3b94fa2006-01-16 16:50:04 +0000405 p = kthread_run(gfs2_recoverd, sdp, "gfs2_recoverd");
406 error = IS_ERR(p);
407 if (error) {
408 fs_err(sdp, "can't start recoverd thread: %d\n", error);
409 goto fail_jinode_gh;
410 }
411 sdp->sd_recoverd_process = p;
412
413 return 0;
414
Steven Whitehousea91ea692006-09-04 12:04:26 -0400415fail_recoverd:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000416 kthread_stop(sdp->sd_recoverd_process);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400417fail_jinode_gh:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000418 if (!sdp->sd_args.ar_spectator)
419 gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400420fail_journal_gh:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000421 if (!sdp->sd_args.ar_spectator)
422 gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400423fail_jindex:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000424 gfs2_jindex_free(sdp);
425 if (jindex)
426 gfs2_glock_dq_uninit(&ji_gh);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400427fail:
Steven Whitehousef42faf42006-01-30 18:34:10 +0000428 iput(sdp->sd_jindex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000429 return error;
430}
431
David Teiglandb3b94fa2006-01-16 16:50:04 +0000432
433static int init_inodes(struct gfs2_sbd *sdp, int undo)
434{
David Teiglandb3b94fa2006-01-16 16:50:04 +0000435 int error = 0;
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500436 struct gfs2_inode *ip;
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500437 struct inode *inode;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000438
439 if (undo)
Steven Whitehousef42faf42006-01-30 18:34:10 +0000440 goto fail_qinode;
441
Steven Whitehousedbb7cae2007-05-15 15:37:50 +0100442 inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr);
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500443 if (IS_ERR(inode)) {
444 error = PTR_ERR(inode);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000445 fs_err(sdp, "can't read in master directory: %d\n", error);
446 goto fail;
447 }
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500448 sdp->sd_master_dir = inode;
Steven Whitehousef42faf42006-01-30 18:34:10 +0000449
450 error = init_journal(sdp, undo);
451 if (error)
452 goto fail_master;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000453
454 /* Read in the master inode number inode */
Steven Whitehousec7526662006-03-20 12:30:04 -0500455 sdp->sd_inum_inode = gfs2_lookup_simple(sdp->sd_master_dir, "inum");
456 if (IS_ERR(sdp->sd_inum_inode)) {
457 error = PTR_ERR(sdp->sd_inum_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000458 fs_err(sdp, "can't read in inum inode: %d\n", error);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000459 goto fail_journal;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000460 }
461
Steven Whitehousef42faf42006-01-30 18:34:10 +0000462
David Teiglandb3b94fa2006-01-16 16:50:04 +0000463 /* Read in the master statfs inode */
Steven Whitehousec7526662006-03-20 12:30:04 -0500464 sdp->sd_statfs_inode = gfs2_lookup_simple(sdp->sd_master_dir, "statfs");
465 if (IS_ERR(sdp->sd_statfs_inode)) {
466 error = PTR_ERR(sdp->sd_statfs_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000467 fs_err(sdp, "can't read in statfs inode: %d\n", error);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000468 goto fail_inum;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000469 }
470
471 /* Read in the resource index inode */
Steven Whitehousec7526662006-03-20 12:30:04 -0500472 sdp->sd_rindex = gfs2_lookup_simple(sdp->sd_master_dir, "rindex");
473 if (IS_ERR(sdp->sd_rindex)) {
474 error = PTR_ERR(sdp->sd_rindex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000475 fs_err(sdp, "can't get resource index inode: %d\n", error);
476 goto fail_statfs;
477 }
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400478 ip = GFS2_I(sdp->sd_rindex);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500479 set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
480 sdp->sd_rindex_vn = ip->i_gl->gl_vn - 1;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000481
482 /* Read in the quota inode */
Steven Whitehousec7526662006-03-20 12:30:04 -0500483 sdp->sd_quota_inode = gfs2_lookup_simple(sdp->sd_master_dir, "quota");
484 if (IS_ERR(sdp->sd_quota_inode)) {
485 error = PTR_ERR(sdp->sd_quota_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000486 fs_err(sdp, "can't get quota file inode: %d\n", error);
487 goto fail_rindex;
488 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000489 return 0;
490
Steven Whitehousef42faf42006-01-30 18:34:10 +0000491fail_qinode:
492 iput(sdp->sd_quota_inode);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000493fail_rindex:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000494 gfs2_clear_rgrpd(sdp);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000495 iput(sdp->sd_rindex);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000496fail_statfs:
497 iput(sdp->sd_statfs_inode);
Steven Whitehousef42faf42006-01-30 18:34:10 +0000498fail_inum:
499 iput(sdp->sd_inum_inode);
500fail_journal:
501 init_journal(sdp, UNDO);
502fail_master:
503 iput(sdp->sd_master_dir);
504fail:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000505 return error;
506}
507
508static int init_per_node(struct gfs2_sbd *sdp, int undo)
509{
Steven Whitehousef42faf42006-01-30 18:34:10 +0000510 struct inode *pn = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000511 char buf[30];
512 int error = 0;
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500513 struct gfs2_inode *ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000514
515 if (sdp->sd_args.ar_spectator)
516 return 0;
517
518 if (undo)
519 goto fail_qc_gh;
520
Steven Whitehousec7526662006-03-20 12:30:04 -0500521 pn = gfs2_lookup_simple(sdp->sd_master_dir, "per_node");
522 if (IS_ERR(pn)) {
523 error = PTR_ERR(pn);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000524 fs_err(sdp, "can't find per_node directory: %d\n", error);
525 return error;
526 }
527
528 sprintf(buf, "inum_range%u", sdp->sd_jdesc->jd_jid);
Steven Whitehousec7526662006-03-20 12:30:04 -0500529 sdp->sd_ir_inode = gfs2_lookup_simple(pn, buf);
530 if (IS_ERR(sdp->sd_ir_inode)) {
531 error = PTR_ERR(sdp->sd_ir_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000532 fs_err(sdp, "can't find local \"ir\" file: %d\n", error);
533 goto fail;
534 }
535
536 sprintf(buf, "statfs_change%u", sdp->sd_jdesc->jd_jid);
Steven Whitehousec7526662006-03-20 12:30:04 -0500537 sdp->sd_sc_inode = gfs2_lookup_simple(pn, buf);
538 if (IS_ERR(sdp->sd_sc_inode)) {
539 error = PTR_ERR(sdp->sd_sc_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000540 fs_err(sdp, "can't find local \"sc\" file: %d\n", error);
541 goto fail_ir_i;
542 }
543
David Teiglandb3b94fa2006-01-16 16:50:04 +0000544 sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid);
Steven Whitehousec7526662006-03-20 12:30:04 -0500545 sdp->sd_qc_inode = gfs2_lookup_simple(pn, buf);
546 if (IS_ERR(sdp->sd_qc_inode)) {
547 error = PTR_ERR(sdp->sd_qc_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000548 fs_err(sdp, "can't find local \"qc\" file: %d\n", error);
549 goto fail_ut_i;
550 }
551
Steven Whitehousef42faf42006-01-30 18:34:10 +0000552 iput(pn);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000553 pn = NULL;
554
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400555 ip = GFS2_I(sdp->sd_ir_inode);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500556 error = gfs2_glock_nq_init(ip->i_gl,
Steven Whitehouse579b78a2006-04-26 14:58:26 -0400557 LM_ST_EXCLUSIVE, 0,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000558 &sdp->sd_ir_gh);
559 if (error) {
560 fs_err(sdp, "can't lock local \"ir\" file: %d\n", error);
561 goto fail_qc_i;
562 }
563
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400564 ip = GFS2_I(sdp->sd_sc_inode);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500565 error = gfs2_glock_nq_init(ip->i_gl,
Steven Whitehouse579b78a2006-04-26 14:58:26 -0400566 LM_ST_EXCLUSIVE, 0,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000567 &sdp->sd_sc_gh);
568 if (error) {
569 fs_err(sdp, "can't lock local \"sc\" file: %d\n", error);
570 goto fail_ir_gh;
571 }
572
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400573 ip = GFS2_I(sdp->sd_qc_inode);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500574 error = gfs2_glock_nq_init(ip->i_gl,
Steven Whitehouse579b78a2006-04-26 14:58:26 -0400575 LM_ST_EXCLUSIVE, 0,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000576 &sdp->sd_qc_gh);
577 if (error) {
578 fs_err(sdp, "can't lock local \"qc\" file: %d\n", error);
579 goto fail_ut_gh;
580 }
581
582 return 0;
583
Steven Whitehousea91ea692006-09-04 12:04:26 -0400584fail_qc_gh:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000585 gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400586fail_ut_gh:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000587 gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400588fail_ir_gh:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000589 gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400590fail_qc_i:
Steven Whitehousef42faf42006-01-30 18:34:10 +0000591 iput(sdp->sd_qc_inode);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400592fail_ut_i:
Steven Whitehousef42faf42006-01-30 18:34:10 +0000593 iput(sdp->sd_sc_inode);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400594fail_ir_i:
Steven Whitehousef42faf42006-01-30 18:34:10 +0000595 iput(sdp->sd_ir_inode);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400596fail:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000597 if (pn)
Steven Whitehousef42faf42006-01-30 18:34:10 +0000598 iput(pn);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000599 return error;
600}
601
602static int init_threads(struct gfs2_sbd *sdp, int undo)
603{
604 struct task_struct *p;
605 int error = 0;
606
607 if (undo)
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400608 goto fail_quotad;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000609
610 sdp->sd_log_flush_time = jiffies;
611 sdp->sd_jindex_refresh_time = jiffies;
612
613 p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
614 error = IS_ERR(p);
615 if (error) {
616 fs_err(sdp, "can't start logd thread: %d\n", error);
617 return error;
618 }
619 sdp->sd_logd_process = p;
620
621 sdp->sd_statfs_sync_time = jiffies;
622 sdp->sd_quota_sync_time = jiffies;
623
624 p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
625 error = IS_ERR(p);
626 if (error) {
627 fs_err(sdp, "can't start quotad thread: %d\n", error);
628 goto fail;
629 }
630 sdp->sd_quotad_process = p;
631
David Teiglandb3b94fa2006-01-16 16:50:04 +0000632 return 0;
633
David Teiglandb3b94fa2006-01-16 16:50:04 +0000634
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400635fail_quotad:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000636 kthread_stop(sdp->sd_quotad_process);
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400637fail:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000638 kthread_stop(sdp->sd_logd_process);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000639 return error;
640}
641
642/**
643 * fill_super - Read in superblock
644 * @sb: The VFS superblock
645 * @data: Mount options
646 * @silent: Don't complain if it's not a GFS2 filesystem
647 *
648 * Returns: errno
649 */
650
651static int fill_super(struct super_block *sb, void *data, int silent)
652{
653 struct gfs2_sbd *sdp;
654 struct gfs2_holder mount_gh;
655 int error;
656
657 sdp = init_sbd(sb);
658 if (!sdp) {
Steven Whitehoused92a8d42006-02-27 10:57:14 -0500659 printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n");
David Teiglandb3b94fa2006-01-16 16:50:04 +0000660 return -ENOMEM;
661 }
662
663 error = gfs2_mount_args(sdp, (char *)data, 0);
664 if (error) {
Steven Whitehoused92a8d42006-02-27 10:57:14 -0500665 printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
David Teiglandb3b94fa2006-01-16 16:50:04 +0000666 goto fail;
667 }
668
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500669 init_vfs(sb, SDF_NOATIME);
670
671 /* Set up the buffer cache and fill in some fake block size values
672 to allow us to read-in the on-disk superblock. */
673 sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS2_BASIC_BLOCK);
674 sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits;
675 sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
676 GFS2_BASIC_BLOCK_SHIFT;
677 sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000678
679 error = init_names(sdp, silent);
680 if (error)
681 goto fail;
682
Robert Peterson7c52b162007-03-16 10:26:37 +0000683 gfs2_create_debugfs_file(sdp);
684
David Teiglandb3b94fa2006-01-16 16:50:04 +0000685 error = gfs2_sys_fs_add(sdp);
686 if (error)
687 goto fail;
688
689 error = gfs2_lm_mount(sdp, silent);
690 if (error)
691 goto fail_sys;
692
693 error = init_locking(sdp, &mount_gh, DO);
694 if (error)
695 goto fail_lm;
696
697 error = init_sb(sdp, silent, DO);
698 if (error)
699 goto fail_locking;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000700
701 error = init_inodes(sdp, DO);
702 if (error)
Steven Whitehousef42faf42006-01-30 18:34:10 +0000703 goto fail_sb;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000704
705 error = init_per_node(sdp, DO);
706 if (error)
707 goto fail_inodes;
708
709 error = gfs2_statfs_init(sdp);
710 if (error) {
711 fs_err(sdp, "can't initialize statfs subsystem: %d\n", error);
712 goto fail_per_node;
713 }
714
715 error = init_threads(sdp, DO);
716 if (error)
717 goto fail_per_node;
718
719 if (!(sb->s_flags & MS_RDONLY)) {
720 error = gfs2_make_fs_rw(sdp);
721 if (error) {
722 fs_err(sdp, "can't make FS RW: %d\n", error);
723 goto fail_threads;
724 }
725 }
726
727 gfs2_glock_dq_uninit(&mount_gh);
728
729 return 0;
730
Steven Whitehousea91ea692006-09-04 12:04:26 -0400731fail_threads:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000732 init_threads(sdp, UNDO);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400733fail_per_node:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000734 init_per_node(sdp, UNDO);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400735fail_inodes:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000736 init_inodes(sdp, UNDO);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400737fail_sb:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000738 init_sb(sdp, 0, UNDO);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400739fail_locking:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000740 init_locking(sdp, &mount_gh, UNDO);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400741fail_lm:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000742 gfs2_gl_hash_clear(sdp, WAIT);
743 gfs2_lm_unmount(sdp);
744 while (invalidate_inodes(sb))
745 yield();
Steven Whitehousea91ea692006-09-04 12:04:26 -0400746fail_sys:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000747 gfs2_sys_fs_del(sdp);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400748fail:
Robert Peterson5f882092007-04-18 11:41:11 -0500749 gfs2_delete_debugfs_file(sdp);
Steven Whitehousea2c45802006-09-08 10:13:03 -0400750 kfree(sdp);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500751 sb->s_fs_info = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000752 return error;
753}
754
Andrew Mortonccd6efd2006-06-30 02:16:34 -0700755static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
756 const char *dev_name, void *data, struct vfsmount *mnt)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000757{
Abhijith Das86384602006-08-25 11:13:37 -0500758 struct super_block *sb;
759 struct gfs2_sbd *sdp;
760 int error = get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt);
761 if (error)
762 goto out;
763 sb = mnt->mnt_sb;
Steven Whitehouse26c1a572006-09-04 15:32:10 -0400764 sdp = sb->s_fs_info;
Abhijith Das86384602006-08-25 11:13:37 -0500765 sdp->sd_gfs2mnt = mnt;
766out:
767 return error;
768}
769
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400770static int fill_super_meta(struct super_block *sb, struct super_block *new,
Abhijith Das86384602006-08-25 11:13:37 -0500771 void *data, int silent)
772{
773 struct gfs2_sbd *sdp = sb->s_fs_info;
774 struct inode *inode;
775 int error = 0;
776
777 new->s_fs_info = sdp;
778 sdp->sd_vfs_meta = sb;
779
780 init_vfs(new, SDF_NOATIME);
781
782 /* Get the master inode */
783 inode = igrab(sdp->sd_master_dir);
784
785 new->s_root = d_alloc_root(inode);
786 if (!new->s_root) {
787 fs_err(sdp, "can't get root dentry\n");
788 error = -ENOMEM;
789 iput(inode);
Adrian Bunkbbbe4512006-10-19 15:27:00 +0200790 } else
791 new->s_root->d_op = &gfs2_dops;
Abhijith Das86384602006-08-25 11:13:37 -0500792
793 return error;
794}
Steven Whitehousea91ea692006-09-04 12:04:26 -0400795
Abhijith Das86384602006-08-25 11:13:37 -0500796static int set_bdev_super(struct super_block *s, void *data)
797{
798 s->s_bdev = data;
799 s->s_dev = s->s_bdev->bd_dev;
800 return 0;
801}
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400802
Abhijith Das86384602006-08-25 11:13:37 -0500803static int test_bdev_super(struct super_block *s, void *data)
804{
Steven Whitehouse26c1a572006-09-04 15:32:10 -0400805 return s->s_bdev == data;
Abhijith Das86384602006-08-25 11:13:37 -0500806}
807
808static struct super_block* get_gfs2_sb(const char *dev_name)
809{
810 struct kstat stat;
811 struct nameidata nd;
812 struct file_system_type *fstype;
813 struct super_block *sb = NULL, *s;
Abhijith Das86384602006-08-25 11:13:37 -0500814 int error;
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400815
Abhijith Das86384602006-08-25 11:13:37 -0500816 error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
817 if (error) {
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400818 printk(KERN_WARNING "GFS2: path_lookup on %s returned error\n",
Abhijith Das86384602006-08-25 11:13:37 -0500819 dev_name);
820 goto out;
821 }
822 error = vfs_getattr(nd.mnt, nd.dentry, &stat);
823
824 fstype = get_fs_type("gfs2");
Denis Chengadb4ec12007-08-11 10:27:07 +0800825 list_for_each_entry(s, &fstype->fs_supers, s_instances) {
Abhijith Das86384602006-08-25 11:13:37 -0500826 if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) ||
827 (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) {
828 sb = s;
829 goto free_nd;
830 }
831 }
832
833 printk(KERN_WARNING "GFS2: Unrecognized block device or "
Richard Fearnd5a67512007-02-17 17:29:15 +0000834 "mount point %s\n", dev_name);
Abhijith Das86384602006-08-25 11:13:37 -0500835
836free_nd:
837 path_release(&nd);
838out:
839 return sb;
840}
841
842static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
843 const char *dev_name, void *data, struct vfsmount *mnt)
844{
845 int error = 0;
846 struct super_block *sb = NULL, *new;
847 struct gfs2_sbd *sdp;
Abhijith Das86384602006-08-25 11:13:37 -0500848
849 sb = get_gfs2_sb(dev_name);
850 if (!sb) {
851 printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
852 error = -ENOENT;
853 goto error;
854 }
Denis Cheng2d3ba1e2007-08-11 10:27:08 +0800855 sdp = sb->s_fs_info;
Abhijith Das86384602006-08-25 11:13:37 -0500856 if (sdp->sd_vfs_meta) {
857 printk(KERN_WARNING "GFS2: gfs2meta mount already exists\n");
858 error = -EBUSY;
859 goto error;
860 }
David Chinnerf73ca1b2007-01-10 23:15:41 -0800861 down(&sb->s_bdev->bd_mount_sem);
Abhijith Das86384602006-08-25 11:13:37 -0500862 new = sget(fs_type, test_bdev_super, set_bdev_super, sb->s_bdev);
David Chinnerf73ca1b2007-01-10 23:15:41 -0800863 up(&sb->s_bdev->bd_mount_sem);
Abhijith Das86384602006-08-25 11:13:37 -0500864 if (IS_ERR(new)) {
865 error = PTR_ERR(new);
866 goto error;
867 }
868 module_put(fs_type->owner);
869 new->s_flags = flags;
870 strlcpy(new->s_id, sb->s_id, sizeof(new->s_id));
871 sb_set_blocksize(new, sb->s_blocksize);
872 error = fill_super_meta(sb, new, data, flags & MS_SILENT ? 1 : 0);
873 if (error) {
874 up_write(&new->s_umount);
875 deactivate_super(new);
876 goto error;
877 }
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400878
Abhijith Das86384602006-08-25 11:13:37 -0500879 new->s_flags |= MS_ACTIVE;
Steven Whitehouse907b9bc2006-09-25 09:26:04 -0400880
Abhijith Das86384602006-08-25 11:13:37 -0500881 /* Grab a reference to the gfs2 mount point */
882 atomic_inc(&sdp->sd_gfs2mnt->mnt_count);
883 return simple_set_mnt(mnt, new);
884error:
Abhijith Das86384602006-08-25 11:13:37 -0500885 return error;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000886}
887
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500888static void gfs2_kill_sb(struct super_block *sb)
889{
Robert Peterson7c52b162007-03-16 10:26:37 +0000890 gfs2_delete_debugfs_file(sb->s_fs_info);
Steven Whitehousebb3b0e32007-08-16 16:03:57 +0100891 gfs2_meta_syncfs(sb->s_fs_info);
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500892 kill_block_super(sb);
893}
894
Abhijith Das86384602006-08-25 11:13:37 -0500895static void gfs2_kill_sb_meta(struct super_block *sb)
896{
897 struct gfs2_sbd *sdp = sb->s_fs_info;
898 generic_shutdown_super(sb);
899 sdp->sd_vfs_meta = NULL;
900 atomic_dec(&sdp->sd_gfs2mnt->mnt_count);
901}
902
David Teiglandb3b94fa2006-01-16 16:50:04 +0000903struct file_system_type gfs2_fs_type = {
904 .name = "gfs2",
905 .fs_flags = FS_REQUIRES_DEV,
906 .get_sb = gfs2_get_sb,
Steven Whitehouse419c93e2006-03-02 16:33:41 -0500907 .kill_sb = gfs2_kill_sb,
908 .owner = THIS_MODULE,
909};
910
911struct file_system_type gfs2meta_fs_type = {
912 .name = "gfs2meta",
913 .fs_flags = FS_REQUIRES_DEV,
Abhijith Das86384602006-08-25 11:13:37 -0500914 .get_sb = gfs2_get_sb_meta,
915 .kill_sb = gfs2_kill_sb_meta,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000916 .owner = THIS_MODULE,
917};
918