blob: 7950ff6ec4e81ac64b761c085780b1eef1bcd30c [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/fs/ext3/super.c
3 *
4 * Copyright (C) 1992, 1993, 1994, 1995
5 * Remy Card (card@masi.ibp.fr)
6 * Laboratoire MASI - Institut Blaise Pascal
7 * Universite Pierre et Marie Curie (Paris VI)
8 *
9 * from
10 *
11 * linux/fs/minix/inode.c
12 *
13 * Copyright (C) 1991, 1992 Linus Torvalds
14 *
15 * Big-endian to little-endian byte-swapping/bitmaps by
16 * David S. Miller (davem@caip.rutgers.edu), 1995
17 */
18
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/module.h>
20#include <linux/string.h>
21#include <linux/fs.h>
22#include <linux/time.h>
23#include <linux/jbd.h>
24#include <linux/ext3_fs.h>
25#include <linux/ext3_jbd.h>
26#include <linux/slab.h>
27#include <linux/init.h>
28#include <linux/blkdev.h>
29#include <linux/parser.h>
30#include <linux/smp_lock.h>
31#include <linux/buffer_head.h>
Christoph Hellwiga5694252007-07-17 04:04:28 -070032#include <linux/exportfs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/vfs.h>
34#include <linux/random.h>
35#include <linux/mount.h>
36#include <linux/namei.h>
37#include <linux/quotaops.h>
Mark Bellon8fc27512005-09-06 15:16:54 -070038#include <linux/seq_file.h>
vignesh babu3fc74262007-07-15 23:41:17 -070039#include <linux/log2.h>
Ben Dooks381be252005-10-30 15:02:56 -080040
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <asm/uaccess.h>
Ben Dooks381be252005-10-30 15:02:56 -080042
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include "xattr.h"
44#include "acl.h"
Ben Dooks381be252005-10-30 15:02:56 -080045#include "namei.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Linus Torvaldsbbae8bc2009-04-06 17:16:47 -070047#ifdef CONFIG_EXT3_DEFAULTS_TO_ORDERED
48 #define EXT3_MOUNT_DEFAULT_DATA_MODE EXT3_MOUNT_ORDERED_DATA
49#else
50 #define EXT3_MOUNT_DEFAULT_DATA_MODE EXT3_MOUNT_WRITEBACK_DATA
51#endif
52
Johann Lombardi71b96252006-01-08 01:03:20 -080053static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
54 unsigned long journal_devnum);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
Eric Sandeeneee194e2006-09-27 01:49:30 -070056 unsigned int);
Takashi Satoc4be0c12009-01-09 16:40:58 -080057static int ext3_commit_super(struct super_block *sb,
58 struct ext3_super_block *es,
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 int sync);
60static void ext3_mark_recovery_complete(struct super_block * sb,
61 struct ext3_super_block * es);
62static void ext3_clear_journal_err(struct super_block * sb,
63 struct ext3_super_block * es);
64static int ext3_sync_fs(struct super_block *sb, int wait);
65static const char *ext3_decode_error(struct super_block * sb, int errno,
66 char nbuf[16]);
67static int ext3_remount (struct super_block * sb, int * flags, char * data);
David Howells726c3342006-06-23 02:02:58 -070068static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf);
Takashi Satoc4be0c12009-01-09 16:40:58 -080069static int ext3_unfreeze(struct super_block *sb);
Takashi Satoc4be0c12009-01-09 16:40:58 -080070static int ext3_freeze(struct super_block *sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071
Mingming Caoae6ddcc2006-09-27 01:49:27 -070072/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 * Wrappers for journal_start/end.
74 *
75 * The only special thing we need to do here is to make sure that all
76 * journal_end calls result in the superblock being marked dirty, so
77 * that sync() will call the filesystem's write_super callback if
Mingming Caoae6ddcc2006-09-27 01:49:27 -070078 * appropriate.
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 */
80handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks)
81{
82 journal_t *journal;
83
84 if (sb->s_flags & MS_RDONLY)
85 return ERR_PTR(-EROFS);
86
87 /* Special case here: if the journal has aborted behind our
88 * backs (eg. EIO in the commit thread), then we still need to
89 * take the FS itself readonly cleanly. */
90 journal = EXT3_SB(sb)->s_journal;
91 if (is_journal_aborted(journal)) {
Harvey Harrisone05b6b52008-04-28 02:16:15 -070092 ext3_abort(sb, __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 "Detected aborted journal");
94 return ERR_PTR(-EROFS);
95 }
96
97 return journal_start(journal, nblocks);
98}
99
Mingming Caoae6ddcc2006-09-27 01:49:27 -0700100/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 * The only special thing we need to do here is to make sure that all
102 * journal_stop calls result in the superblock being marked dirty, so
103 * that sync() will call the filesystem's write_super callback if
Mingming Caoae6ddcc2006-09-27 01:49:27 -0700104 * appropriate.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 */
106int __ext3_journal_stop(const char *where, handle_t *handle)
107{
108 struct super_block *sb;
109 int err;
110 int rc;
111
112 sb = handle->h_transaction->t_journal->j_private;
113 err = handle->h_err;
114 rc = journal_stop(handle);
115
116 if (!err)
117 err = rc;
118 if (err)
119 __ext3_std_error(sb, where, err);
120 return err;
121}
122
123void ext3_journal_abort_handle(const char *caller, const char *err_fn,
124 struct buffer_head *bh, handle_t *handle, int err)
125{
126 char nbuf[16];
127 const char *errstr = ext3_decode_error(NULL, err, nbuf);
128
129 if (bh)
130 BUFFER_TRACE(bh, "abort");
131
132 if (!handle->h_err)
133 handle->h_err = err;
134
135 if (is_handle_aborted(handle))
136 return;
137
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100138 printk(KERN_ERR "EXT3-fs: %s: aborting transaction: %s in %s\n",
139 caller, errstr, err_fn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141 journal_abort_handle(handle);
142}
143
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100144void ext3_msg(struct super_block *sb, const char *prefix,
145 const char *fmt, ...)
146{
147 va_list args;
148
149 va_start(args, fmt);
150 printk("%sEXT3-fs (%s): ", prefix, sb->s_id);
151 vprintk(fmt, args);
152 printk("\n");
153 va_end(args);
154}
155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156/* Deal with the reporting of failure conditions on a filesystem such as
157 * inconsistencies detected or read IO failures.
158 *
159 * On ext2, we can store the error state of the filesystem in the
160 * superblock. That is not possible on ext3, because we may have other
161 * write ordering constraints on the superblock which prevent us from
162 * writing it out straight away; and given that the journal is about to
163 * be aborted, we can't rely on the current, or future, transactions to
164 * write out the superblock safely.
165 *
166 * We'll just use the journal_abort() error code to record an error in
167 * the journal instead. On recovery, the journal will compain about
168 * that error until we've noted it down and cleared it.
169 */
170
171static void ext3_handle_error(struct super_block *sb)
172{
173 struct ext3_super_block *es = EXT3_SB(sb)->s_es;
174
175 EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
176 es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
177
178 if (sb->s_flags & MS_RDONLY)
179 return;
180
Vasily Averin7543fc72006-09-27 01:49:33 -0700181 if (!test_opt (sb, ERRORS_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 journal_t *journal = EXT3_SB(sb)->s_journal;
183
Dmitry Monakhove3c96432010-02-02 16:05:51 +0300184 set_opt(EXT3_SB(sb)->s_mount_opt, ABORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 if (journal)
186 journal_abort(journal, -EIO);
187 }
Vasily Averin7543fc72006-09-27 01:49:33 -0700188 if (test_opt (sb, ERRORS_RO)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100189 ext3_msg(sb, KERN_CRIT,
190 "error: remounting filesystem read-only");
Vasily Averin7543fc72006-09-27 01:49:33 -0700191 sb->s_flags |= MS_RDONLY;
192 }
193 ext3_commit_super(sb, es, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 if (test_opt(sb, ERRORS_PANIC))
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100195 panic("EXT3-fs (%s): panic forced after error\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 sb->s_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197}
198
199void ext3_error (struct super_block * sb, const char * function,
200 const char * fmt, ...)
201{
202 va_list args;
203
204 va_start(args, fmt);
205 printk(KERN_CRIT "EXT3-fs error (device %s): %s: ",sb->s_id, function);
206 vprintk(fmt, args);
207 printk("\n");
208 va_end(args);
209
210 ext3_handle_error(sb);
211}
212
213static const char *ext3_decode_error(struct super_block * sb, int errno,
214 char nbuf[16])
215{
216 char *errstr = NULL;
217
218 switch (errno) {
219 case -EIO:
220 errstr = "IO failure";
221 break;
222 case -ENOMEM:
223 errstr = "Out of memory";
224 break;
225 case -EROFS:
226 if (!sb || EXT3_SB(sb)->s_journal->j_flags & JFS_ABORT)
227 errstr = "Journal has aborted";
228 else
229 errstr = "Readonly filesystem";
230 break;
231 default:
232 /* If the caller passed in an extra buffer for unknown
233 * errors, textualise them now. Else we just return
234 * NULL. */
235 if (nbuf) {
236 /* Check for truncated error codes... */
237 if (snprintf(nbuf, 16, "error %d", -errno) >= 0)
238 errstr = nbuf;
239 }
240 break;
241 }
242
243 return errstr;
244}
245
246/* __ext3_std_error decodes expected errors from journaling functions
247 * automatically and invokes the appropriate error response. */
248
249void __ext3_std_error (struct super_block * sb, const char * function,
250 int errno)
251{
252 char nbuf[16];
Stephen Tweedie30121622005-05-18 11:47:17 -0400253 const char *errstr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254
Stephen Tweedie30121622005-05-18 11:47:17 -0400255 /* Special case: if the error is EROFS, and we're not already
256 * inside a transaction, then there's really no point in logging
257 * an error. */
258 if (errno == -EROFS && journal_current_handle() == NULL &&
259 (sb->s_flags & MS_RDONLY))
260 return;
261
262 errstr = ext3_decode_error(sb, errno, nbuf);
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100263 ext3_msg(sb, KERN_CRIT, "error in %s: %s", function, errstr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264
265 ext3_handle_error(sb);
266}
267
268/*
269 * ext3_abort is a much stronger failure handler than ext3_error. The
270 * abort function may be used to deal with unrecoverable failures such
271 * as journal IO errors or ENOMEM at a critical moment in log management.
272 *
273 * We unconditionally force the filesystem into an ABORT|READONLY state,
274 * unless the error response on the fs has been set to panic in which
275 * case we take the easy way out and panic immediately.
276 */
277
278void ext3_abort (struct super_block * sb, const char * function,
279 const char * fmt, ...)
280{
281 va_list args;
282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 va_start(args, fmt);
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100284 printk(KERN_CRIT "EXT3-fs (%s): error: %s: ", sb->s_id, function);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 vprintk(fmt, args);
286 printk("\n");
287 va_end(args);
288
289 if (test_opt(sb, ERRORS_PANIC))
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100290 panic("EXT3-fs: panic from previous error\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291
292 if (sb->s_flags & MS_RDONLY)
293 return;
294
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100295 ext3_msg(sb, KERN_CRIT,
296 "error: remounting filesystem read-only");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
298 sb->s_flags |= MS_RDONLY;
Dmitry Monakhove3c96432010-02-02 16:05:51 +0300299 set_opt(EXT3_SB(sb)->s_mount_opt, ABORT);
Hidehiro Kawai44d6f782008-10-27 22:51:46 -0400300 if (EXT3_SB(sb)->s_journal)
301 journal_abort(EXT3_SB(sb)->s_journal, -EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302}
303
304void ext3_warning (struct super_block * sb, const char * function,
305 const char * fmt, ...)
306{
307 va_list args;
308
309 va_start(args, fmt);
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100310 printk(KERN_WARNING "EXT3-fs (%s): warning: %s: ",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 sb->s_id, function);
312 vprintk(fmt, args);
313 printk("\n");
314 va_end(args);
315}
316
317void ext3_update_dynamic_rev(struct super_block *sb)
318{
319 struct ext3_super_block *es = EXT3_SB(sb)->s_es;
320
321 if (le32_to_cpu(es->s_rev_level) > EXT3_GOOD_OLD_REV)
322 return;
323
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100324 ext3_msg(sb, KERN_WARNING,
325 "warning: updating to rev %d because of "
326 "new feature flag, running e2fsck is recommended",
327 EXT3_DYNAMIC_REV);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328
329 es->s_first_ino = cpu_to_le32(EXT3_GOOD_OLD_FIRST_INO);
330 es->s_inode_size = cpu_to_le16(EXT3_GOOD_OLD_INODE_SIZE);
331 es->s_rev_level = cpu_to_le32(EXT3_DYNAMIC_REV);
332 /* leave es->s_feature_*compat flags alone */
333 /* es->s_uuid will be set by e2fsck if empty */
334
335 /*
336 * The rest of the superblock fields should be zero, and if not it
337 * means they are likely already in use, so leave them alone. We
338 * can leave it up to e2fsck to clean up any inconsistencies there.
339 */
340}
341
342/*
343 * Open the external journal device
344 */
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100345static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346{
347 struct block_device *bdev;
348 char b[BDEVNAME_SIZE];
349
350 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
351 if (IS_ERR(bdev))
352 goto fail;
353 return bdev;
354
355fail:
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100356 ext3_msg(sb, "error: failed to open journal device %s: %ld",
357 __bdevname(dev, b), PTR_ERR(bdev));
358
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 return NULL;
360}
361
362/*
363 * Release the journal device
364 */
365static int ext3_blkdev_put(struct block_device *bdev)
366{
367 bd_release(bdev);
Al Viro9a1c3542008-02-22 20:40:24 -0500368 return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369}
370
371static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
372{
373 struct block_device *bdev;
374 int ret = -ENODEV;
375
376 bdev = sbi->journal_bdev;
377 if (bdev) {
378 ret = ext3_blkdev_put(bdev);
379 sbi->journal_bdev = NULL;
380 }
381 return ret;
382}
383
384static inline struct inode *orphan_list_entry(struct list_head *l)
385{
386 return &list_entry(l, struct ext3_inode_info, i_orphan)->vfs_inode;
387}
388
389static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
390{
391 struct list_head *l;
392
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100393 ext3_msg(sb, KERN_ERR, "error: sb orphan head is %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 le32_to_cpu(sbi->s_es->s_last_orphan));
395
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100396 ext3_msg(sb, KERN_ERR, "sb_info orphan list:");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 list_for_each(l, &sbi->s_orphan) {
398 struct inode *inode = orphan_list_entry(l);
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100399 ext3_msg(sb, KERN_ERR, " "
Eric Sandeeneee194e2006-09-27 01:49:30 -0700400 "inode %s:%lu at %p: mode %o, nlink %d, next %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 inode->i_sb->s_id, inode->i_ino, inode,
Mingming Caoae6ddcc2006-09-27 01:49:27 -0700402 inode->i_mode, inode->i_nlink,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 NEXT_ORPHAN(inode));
404 }
405}
406
407static void ext3_put_super (struct super_block * sb)
408{
409 struct ext3_sb_info *sbi = EXT3_SB(sb);
410 struct ext3_super_block *es = sbi->s_es;
Hidehiro Kawai44d6f782008-10-27 22:51:46 -0400411 int i, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Christoph Hellwig6cfd0142009-05-05 15:40:36 +0200413 lock_kernel();
414
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 ext3_xattr_put_super(sb);
Hidehiro Kawai44d6f782008-10-27 22:51:46 -0400416 err = journal_destroy(sbi->s_journal);
417 sbi->s_journal = NULL;
418 if (err < 0)
Hidehiro Kawai2d7c8202008-10-22 14:15:01 -0700419 ext3_abort(sb, __func__, "Couldn't clean up the journal");
Hidehiro Kawai44d6f782008-10-27 22:51:46 -0400420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 if (!(sb->s_flags & MS_RDONLY)) {
422 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
423 es->s_state = cpu_to_le16(sbi->s_mount_state);
424 BUFFER_TRACE(sbi->s_sbh, "marking dirty");
425 mark_buffer_dirty(sbi->s_sbh);
426 ext3_commit_super(sb, es, 1);
427 }
428
429 for (i = 0; i < sbi->s_gdb_count; i++)
430 brelse(sbi->s_group_desc[i]);
431 kfree(sbi->s_group_desc);
432 percpu_counter_destroy(&sbi->s_freeblocks_counter);
433 percpu_counter_destroy(&sbi->s_freeinodes_counter);
434 percpu_counter_destroy(&sbi->s_dirs_counter);
435 brelse(sbi->s_sbh);
436#ifdef CONFIG_QUOTA
437 for (i = 0; i < MAXQUOTAS; i++)
438 kfree(sbi->s_qf_names[i]);
439#endif
440
441 /* Debugging code just in case the in-memory inode orphan list
442 * isn't empty. The on-disk one can be non-empty if we've
443 * detected an error and taken the fs readonly, but the
444 * in-memory list had better be clean by this point. */
445 if (!list_empty(&sbi->s_orphan))
446 dump_orphan_list(sb, sbi);
447 J_ASSERT(list_empty(&sbi->s_orphan));
448
Peter Zijlstraf98393a2007-05-06 14:49:54 -0700449 invalidate_bdev(sb->s_bdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) {
451 /*
452 * Invalidate the journal device's buffers. We don't want them
453 * floating about in memory - the physical journal device may
454 * hotswapped, and it breaks the `ro-after' testing code.
455 */
456 sync_blockdev(sbi->journal_bdev);
Peter Zijlstraf98393a2007-05-06 14:49:54 -0700457 invalidate_bdev(sbi->journal_bdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 ext3_blkdev_remove(sbi);
459 }
460 sb->s_fs_info = NULL;
Pekka Enberg5df096d2009-01-07 18:07:25 -0800461 kfree(sbi->s_blockgroup_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 kfree(sbi);
Christoph Hellwig6cfd0142009-05-05 15:40:36 +0200463
464 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465}
466
Christoph Lametere18b8902006-12-06 20:33:20 -0800467static struct kmem_cache *ext3_inode_cachep;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468
469/*
470 * Called inside transaction, so use GFP_NOFS
471 */
472static struct inode *ext3_alloc_inode(struct super_block *sb)
473{
474 struct ext3_inode_info *ei;
475
Christoph Lametere6b4f8d2006-12-06 20:33:14 -0800476 ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 if (!ei)
478 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 ei->i_block_alloc_info = NULL;
480 ei->vfs_inode.i_version = 1;
Jan Karafe8bc912009-10-16 19:26:15 +0200481 atomic_set(&ei->i_datasync_tid, 0);
482 atomic_set(&ei->i_sync_tid, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 return &ei->vfs_inode;
484}
485
486static void ext3_destroy_inode(struct inode *inode)
487{
Vasily Averin9f7dd932007-07-15 23:40:45 -0700488 if (!list_empty(&(EXT3_I(inode)->i_orphan))) {
489 printk("EXT3 Inode %p: orphan list check failed!\n",
490 EXT3_I(inode));
491 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4,
492 EXT3_I(inode), sizeof(struct ext3_inode_info),
493 false);
494 dump_stack();
495 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
497}
498
Alexey Dobriyan51cc5062008-07-25 19:45:34 -0700499static void init_once(void *foo)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500{
501 struct ext3_inode_info *ei = (struct ext3_inode_info *) foo;
502
Christoph Lametera35afb82007-05-16 22:10:57 -0700503 INIT_LIST_HEAD(&ei->i_orphan);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504#ifdef CONFIG_EXT3_FS_XATTR
Christoph Lametera35afb82007-05-16 22:10:57 -0700505 init_rwsem(&ei->xattr_sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506#endif
Christoph Lametera35afb82007-05-16 22:10:57 -0700507 mutex_init(&ei->truncate_mutex);
508 inode_init_once(&ei->vfs_inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509}
Mingming Caoae6ddcc2006-09-27 01:49:27 -0700510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511static int init_inodecache(void)
512{
513 ext3_inode_cachep = kmem_cache_create("ext3_inode_cache",
514 sizeof(struct ext3_inode_info),
Paul Jacksonfffb60f2006-03-24 03:16:06 -0800515 0, (SLAB_RECLAIM_ACCOUNT|
516 SLAB_MEM_SPREAD),
Paul Mundt20c2df82007-07-20 10:11:58 +0900517 init_once);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 if (ext3_inode_cachep == NULL)
519 return -ENOMEM;
520 return 0;
521}
522
523static void destroy_inodecache(void)
524{
Alexey Dobriyan1a1d92c2006-09-27 01:49:40 -0700525 kmem_cache_destroy(ext3_inode_cachep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526}
527
528static void ext3_clear_inode(struct inode *inode)
529{
530 struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 ext3_discard_reservation(inode);
532 EXT3_I(inode)->i_block_alloc_info = NULL;
Andrew Mortone6022602006-06-23 02:05:32 -0700533 if (unlikely(rsv))
534 kfree(rsv);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535}
536
Peter Osterlund6cd37cd2005-10-28 20:23:39 +0200537static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb)
Mark Bellon8fc27512005-09-06 15:16:54 -0700538{
Peter Osterlund6cd37cd2005-10-28 20:23:39 +0200539#if defined(CONFIG_QUOTA)
OGAWA Hirofumi275abf52005-09-22 21:44:03 -0700540 struct ext3_sb_info *sbi = EXT3_SB(sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
Jan Kara1aeec432009-11-30 22:22:41 +0100542 if (sbi->s_jquota_fmt) {
543 char *fmtname = "";
544
545 switch (sbi->s_jquota_fmt) {
546 case QFMT_VFS_OLD:
547 fmtname = "vfsold";
548 break;
549 case QFMT_VFS_V0:
550 fmtname = "vfsv0";
551 break;
552 case QFMT_VFS_V1:
553 fmtname = "vfsv1";
554 break;
555 }
556 seq_printf(seq, ",jqfmt=%s", fmtname);
557 }
Mark Bellon8fc27512005-09-06 15:16:54 -0700558
559 if (sbi->s_qf_names[USRQUOTA])
560 seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
561
562 if (sbi->s_qf_names[GRPQUOTA])
563 seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
564
Dmitry Monakhove3c96432010-02-02 16:05:51 +0300565 if (test_opt(sb, USRQUOTA))
Mark Bellon8fc27512005-09-06 15:16:54 -0700566 seq_puts(seq, ",usrquota");
567
Dmitry Monakhove3c96432010-02-02 16:05:51 +0300568 if (test_opt(sb, GRPQUOTA))
Mark Bellon8fc27512005-09-06 15:16:54 -0700569 seq_puts(seq, ",grpquota");
570#endif
Peter Osterlund6cd37cd2005-10-28 20:23:39 +0200571}
572
Jan Kara3c4cec62009-08-24 16:38:43 +0200573static char *data_mode_string(unsigned long mode)
574{
575 switch (mode) {
576 case EXT3_MOUNT_JOURNAL_DATA:
577 return "journal";
578 case EXT3_MOUNT_ORDERED_DATA:
579 return "ordered";
580 case EXT3_MOUNT_WRITEBACK_DATA:
581 return "writeback";
582 }
583 return "unknown";
584}
585
Miklos Szeredi571beed2007-10-16 23:26:26 -0700586/*
587 * Show an option if
588 * - it's set to a non-default value OR
589 * - if the per-sb default is different from the global default
590 */
Peter Osterlund6cd37cd2005-10-28 20:23:39 +0200591static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
592{
593 struct super_block *sb = vfs->mnt_sb;
Miklos Szeredi571beed2007-10-16 23:26:26 -0700594 struct ext3_sb_info *sbi = EXT3_SB(sb);
595 struct ext3_super_block *es = sbi->s_es;
596 unsigned long def_mount_opts;
597
598 def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
599
600 if (sbi->s_sb_block != 1)
601 seq_printf(seq, ",sb=%lu", sbi->s_sb_block);
602 if (test_opt(sb, MINIX_DF))
603 seq_puts(seq, ",minixdf");
604 if (test_opt(sb, GRPID))
605 seq_puts(seq, ",grpid");
606 if (!test_opt(sb, GRPID) && (def_mount_opts & EXT3_DEFM_BSDGROUPS))
607 seq_puts(seq, ",nogrpid");
608 if (sbi->s_resuid != EXT3_DEF_RESUID ||
609 le16_to_cpu(es->s_def_resuid) != EXT3_DEF_RESUID) {
610 seq_printf(seq, ",resuid=%u", sbi->s_resuid);
611 }
612 if (sbi->s_resgid != EXT3_DEF_RESGID ||
613 le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) {
614 seq_printf(seq, ",resgid=%u", sbi->s_resgid);
615 }
Aneesh Kumar K.V1eca93f2008-02-06 01:40:14 -0800616 if (test_opt(sb, ERRORS_RO)) {
Miklos Szeredi571beed2007-10-16 23:26:26 -0700617 int def_errors = le16_to_cpu(es->s_errors);
618
619 if (def_errors == EXT3_ERRORS_PANIC ||
Aneesh Kumar K.V1eca93f2008-02-06 01:40:14 -0800620 def_errors == EXT3_ERRORS_CONTINUE) {
621 seq_puts(seq, ",errors=remount-ro");
Miklos Szeredi571beed2007-10-16 23:26:26 -0700622 }
623 }
Aneesh Kumar K.V1eca93f2008-02-06 01:40:14 -0800624 if (test_opt(sb, ERRORS_CONT))
625 seq_puts(seq, ",errors=continue");
Miklos Szeredi571beed2007-10-16 23:26:26 -0700626 if (test_opt(sb, ERRORS_PANIC))
627 seq_puts(seq, ",errors=panic");
628 if (test_opt(sb, NO_UID32))
629 seq_puts(seq, ",nouid32");
630 if (test_opt(sb, DEBUG))
631 seq_puts(seq, ",debug");
632 if (test_opt(sb, OLDALLOC))
633 seq_puts(seq, ",oldalloc");
634#ifdef CONFIG_EXT3_FS_XATTR
635 if (test_opt(sb, XATTR_USER))
636 seq_puts(seq, ",user_xattr");
637 if (!test_opt(sb, XATTR_USER) &&
638 (def_mount_opts & EXT3_DEFM_XATTR_USER)) {
639 seq_puts(seq, ",nouser_xattr");
640 }
641#endif
642#ifdef CONFIG_EXT3_FS_POSIX_ACL
643 if (test_opt(sb, POSIX_ACL))
644 seq_puts(seq, ",acl");
645 if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT3_DEFM_ACL))
646 seq_puts(seq, ",noacl");
647#endif
648 if (!test_opt(sb, RESERVATION))
649 seq_puts(seq, ",noreservation");
650 if (sbi->s_commit_interval) {
651 seq_printf(seq, ",commit=%u",
652 (unsigned) (sbi->s_commit_interval / HZ));
653 }
654 if (test_opt(sb, BARRIER))
655 seq_puts(seq, ",barrier=1");
656 if (test_opt(sb, NOBH))
657 seq_puts(seq, ",nobh");
Peter Osterlund6cd37cd2005-10-28 20:23:39 +0200658
Dmitry Monakhove3c96432010-02-02 16:05:51 +0300659 seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS)));
Hidehiro Kawai0e4fb5e2008-10-18 20:27:57 -0700660 if (test_opt(sb, DATA_ERR_ABORT))
661 seq_puts(seq, ",data_err=abort");
662
Eric Sandeendee1d3b2009-11-16 16:50:49 -0600663 if (test_opt(sb, NOLOAD))
664 seq_puts(seq, ",norecovery");
665
Peter Osterlund6cd37cd2005-10-28 20:23:39 +0200666 ext3_show_quota_options(seq, sb);
Mark Bellon8fc27512005-09-06 15:16:54 -0700667
668 return 0;
669}
670
NeilBrownfdb36672006-09-16 12:15:38 -0700671
Christoph Hellwig74af0ba2007-10-21 16:42:07 -0700672static struct inode *ext3_nfs_get_inode(struct super_block *sb,
673 u64 ino, u32 generation)
NeilBrownfdb36672006-09-16 12:15:38 -0700674{
NeilBrownfdb36672006-09-16 12:15:38 -0700675 struct inode *inode;
NeilBrownfdb36672006-09-16 12:15:38 -0700676
677 if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO)
678 return ERR_PTR(-ESTALE);
679 if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count))
680 return ERR_PTR(-ESTALE);
681
682 /* iget isn't really right if the inode is currently unallocated!!
683 *
684 * ext3_read_inode will return a bad_inode if the inode had been
685 * deleted, so we should be safe.
686 *
687 * Currently we don't know the generation for parent directory, so
688 * a generation of 0 means "accept any"
689 */
David Howells473043d2008-02-07 00:15:36 -0800690 inode = ext3_iget(sb, ino);
691 if (IS_ERR(inode))
692 return ERR_CAST(inode);
693 if (generation && inode->i_generation != generation) {
NeilBrownfdb36672006-09-16 12:15:38 -0700694 iput(inode);
695 return ERR_PTR(-ESTALE);
696 }
Christoph Hellwig74af0ba2007-10-21 16:42:07 -0700697
698 return inode;
699}
700
701static struct dentry *ext3_fh_to_dentry(struct super_block *sb, struct fid *fid,
702 int fh_len, int fh_type)
703{
704 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
705 ext3_nfs_get_inode);
706}
707
708static struct dentry *ext3_fh_to_parent(struct super_block *sb, struct fid *fid,
709 int fh_len, int fh_type)
710{
711 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
712 ext3_nfs_get_inode);
NeilBrownfdb36672006-09-16 12:15:38 -0700713}
714
Toshiyuki Okajima6b082b52009-01-05 22:38:14 -0500715/*
716 * Try to release metadata pages (indirect blocks, directories) which are
717 * mapped via the block device. Since these pages could have journal heads
718 * which would prevent try_to_free_buffers() from freeing them, we must use
719 * jbd layer's try_to_free_buffers() function to release them.
720 */
721static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
722 gfp_t wait)
723{
724 journal_t *journal = EXT3_SB(sb)->s_journal;
725
726 WARN_ON(PageChecked(page));
727 if (!page_has_buffers(page))
728 return 0;
729 if (journal)
730 return journal_try_to_free_buffers(journal, page,
731 wait & ~__GFP_WAIT);
732 return try_to_free_buffers(page);
733}
734
Mark Bellon8fc27512005-09-06 15:16:54 -0700735#ifdef CONFIG_QUOTA
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
737#define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
738
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739static int ext3_write_dquot(struct dquot *dquot);
740static int ext3_acquire_dquot(struct dquot *dquot);
741static int ext3_release_dquot(struct dquot *dquot);
742static int ext3_mark_dquot_dirty(struct dquot *dquot);
743static int ext3_write_info(struct super_block *sb, int type);
Jan Kara2fd83a42008-04-28 02:14:34 -0700744static int ext3_quota_on(struct super_block *sb, int type, int format_id,
745 char *path, int remount);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746static int ext3_quota_on_mount(struct super_block *sb, int type);
747static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
748 size_t len, loff_t off);
749static ssize_t ext3_quota_write(struct super_block *sb, int type,
750 const char *data, size_t len, loff_t off);
751
Alexey Dobriyan61e225d2009-09-21 17:01:08 -0700752static const struct dquot_operations ext3_quota_operations = {
Jan Karaa219ce32009-01-12 19:03:19 +0100753 .initialize = dquot_initialize,
754 .drop = dquot_drop,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 .alloc_space = dquot_alloc_space,
756 .alloc_inode = dquot_alloc_inode,
757 .free_space = dquot_free_space,
758 .free_inode = dquot_free_inode,
759 .transfer = dquot_transfer,
760 .write_dquot = ext3_write_dquot,
761 .acquire_dquot = ext3_acquire_dquot,
762 .release_dquot = ext3_release_dquot,
763 .mark_dirty = ext3_mark_dquot_dirty,
Jan Kara157091a2008-11-25 15:31:34 +0100764 .write_info = ext3_write_info,
765 .alloc_dquot = dquot_alloc,
766 .destroy_dquot = dquot_destroy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767};
768
Alexey Dobriyan0d54b212009-09-21 17:01:09 -0700769static const struct quotactl_ops ext3_qctl_operations = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 .quota_on = ext3_quota_on,
771 .quota_off = vfs_quota_off,
772 .quota_sync = vfs_quota_sync,
773 .get_info = vfs_get_dqinfo,
774 .set_info = vfs_set_dqinfo,
775 .get_dqblk = vfs_get_dqblk,
776 .set_dqblk = vfs_set_dqblk
777};
778#endif
779
Josef 'Jeff' Sipekee9b6d62007-02-12 00:55:41 -0800780static const struct super_operations ext3_sops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 .alloc_inode = ext3_alloc_inode,
782 .destroy_inode = ext3_destroy_inode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 .write_inode = ext3_write_inode,
784 .dirty_inode = ext3_dirty_inode,
785 .delete_inode = ext3_delete_inode,
786 .put_super = ext3_put_super,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 .sync_fs = ext3_sync_fs,
Takashi Satoc4be0c12009-01-09 16:40:58 -0800788 .freeze_fs = ext3_freeze,
789 .unfreeze_fs = ext3_unfreeze,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 .statfs = ext3_statfs,
791 .remount_fs = ext3_remount,
792 .clear_inode = ext3_clear_inode,
Mark Bellon8fc27512005-09-06 15:16:54 -0700793 .show_options = ext3_show_options,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794#ifdef CONFIG_QUOTA
795 .quota_read = ext3_quota_read,
796 .quota_write = ext3_quota_write,
797#endif
Toshiyuki Okajima6b082b52009-01-05 22:38:14 -0500798 .bdev_try_to_free_page = bdev_try_to_free_page,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799};
800
Christoph Hellwig39655162007-10-21 16:42:17 -0700801static const struct export_operations ext3_export_ops = {
Christoph Hellwig74af0ba2007-10-21 16:42:07 -0700802 .fh_to_dentry = ext3_fh_to_dentry,
803 .fh_to_parent = ext3_fh_to_parent,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 .get_parent = ext3_get_parent,
805};
806
807enum {
808 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
809 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
Adrian Bunk2860b732005-11-08 21:34:59 -0800810 Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
Badari Pulavartyade1a292006-06-26 00:25:04 -0700812 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
Johann Lombardi71b96252006-01-08 01:03:20 -0800813 Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Hidehiro Kawai0e4fb5e2008-10-18 20:27:57 -0700815 Opt_data_err_abort, Opt_data_err_ignore,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Jan Kara1aeec432009-11-30 22:22:41 +0100817 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
818 Opt_noquota, Opt_ignore, Opt_barrier, Opt_err, Opt_resize,
819 Opt_usrquota, Opt_grpquota
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820};
821
Steven Whitehousea447c092008-10-13 10:46:57 +0100822static const match_table_t tokens = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 {Opt_bsd_df, "bsddf"},
824 {Opt_minix_df, "minixdf"},
825 {Opt_grpid, "grpid"},
826 {Opt_grpid, "bsdgroups"},
827 {Opt_nogrpid, "nogrpid"},
828 {Opt_nogrpid, "sysvgroups"},
829 {Opt_resgid, "resgid=%u"},
830 {Opt_resuid, "resuid=%u"},
831 {Opt_sb, "sb=%u"},
832 {Opt_err_cont, "errors=continue"},
833 {Opt_err_panic, "errors=panic"},
834 {Opt_err_ro, "errors=remount-ro"},
835 {Opt_nouid32, "nouid32"},
836 {Opt_nocheck, "nocheck"},
837 {Opt_nocheck, "check=none"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 {Opt_debug, "debug"},
839 {Opt_oldalloc, "oldalloc"},
840 {Opt_orlov, "orlov"},
841 {Opt_user_xattr, "user_xattr"},
842 {Opt_nouser_xattr, "nouser_xattr"},
843 {Opt_acl, "acl"},
844 {Opt_noacl, "noacl"},
845 {Opt_reservation, "reservation"},
846 {Opt_noreservation, "noreservation"},
847 {Opt_noload, "noload"},
Eric Sandeendee1d3b2009-11-16 16:50:49 -0600848 {Opt_noload, "norecovery"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 {Opt_nobh, "nobh"},
Badari Pulavartyade1a292006-06-26 00:25:04 -0700850 {Opt_bh, "bh"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 {Opt_commit, "commit=%u"},
852 {Opt_journal_update, "journal=update"},
853 {Opt_journal_inum, "journal=%u"},
Johann Lombardi71b96252006-01-08 01:03:20 -0800854 {Opt_journal_dev, "journal_dev=%u"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 {Opt_abort, "abort"},
856 {Opt_data_journal, "data=journal"},
857 {Opt_data_ordered, "data=ordered"},
858 {Opt_data_writeback, "data=writeback"},
Hidehiro Kawai0e4fb5e2008-10-18 20:27:57 -0700859 {Opt_data_err_abort, "data_err=abort"},
860 {Opt_data_err_ignore, "data_err=ignore"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 {Opt_offusrjquota, "usrjquota="},
862 {Opt_usrjquota, "usrjquota=%s"},
863 {Opt_offgrpjquota, "grpjquota="},
864 {Opt_grpjquota, "grpjquota=%s"},
865 {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
866 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
Jan Kara1aeec432009-11-30 22:22:41 +0100867 {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
Mark Bellon8fc27512005-09-06 15:16:54 -0700868 {Opt_grpquota, "grpquota"},
Jan Kara1f545872005-06-23 22:01:04 -0700869 {Opt_noquota, "noquota"},
870 {Opt_quota, "quota"},
Mark Bellon8fc27512005-09-06 15:16:54 -0700871 {Opt_usrquota, "usrquota"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 {Opt_barrier, "barrier=%u"},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 {Opt_resize, "resize"},
Josef Bacik925872162008-03-04 14:29:43 -0800874 {Opt_err, NULL},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875};
876
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100877static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878{
Dave Kleikampe9ad5622006-09-27 01:49:35 -0700879 ext3_fsblk_t sb_block;
880 char *options = (char *) *data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881
882 if (!options || strncmp(options, "sb=", 3) != 0)
883 return 1; /* Default location */
884 options += 3;
Mingming Cao43d23f92006-06-25 05:48:07 -0700885 /*todo: use simple_strtoll with >32bit ext3 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 sb_block = simple_strtoul(options, &options, 0);
887 if (*options && *options != ',') {
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100888 ext3_msg(sb, "error: invalid sb specification: %s",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 (char *) *data);
890 return 1;
891 }
892 if (*options == ',')
893 options++;
894 *data = (void *) options;
895 return sb_block;
896}
897
Johann Lombardi71b96252006-01-08 01:03:20 -0800898static int parse_options (char *options, struct super_block *sb,
Eric Sandeeneee194e2006-09-27 01:49:30 -0700899 unsigned int *inum, unsigned long *journal_devnum,
Mingming Cao43d23f92006-06-25 05:48:07 -0700900 ext3_fsblk_t *n_blocks_count, int is_remount)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901{
902 struct ext3_sb_info *sbi = EXT3_SB(sb);
903 char * p;
904 substring_t args[MAX_OPT_ARGS];
905 int data_opt = 0;
906 int option;
907#ifdef CONFIG_QUOTA
Jan Karad06bf1d2008-07-25 01:46:18 -0700908 int qtype, qfmt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 char *qname;
910#endif
911
912 if (!options)
913 return 1;
914
915 while ((p = strsep (&options, ",")) != NULL) {
916 int token;
917 if (!*p)
918 continue;
919
920 token = match_token(p, tokens, args);
921 switch (token) {
922 case Opt_bsd_df:
923 clear_opt (sbi->s_mount_opt, MINIX_DF);
924 break;
925 case Opt_minix_df:
926 set_opt (sbi->s_mount_opt, MINIX_DF);
927 break;
928 case Opt_grpid:
929 set_opt (sbi->s_mount_opt, GRPID);
930 break;
931 case Opt_nogrpid:
932 clear_opt (sbi->s_mount_opt, GRPID);
933 break;
934 case Opt_resuid:
935 if (match_int(&args[0], &option))
936 return 0;
937 sbi->s_resuid = option;
938 break;
939 case Opt_resgid:
940 if (match_int(&args[0], &option))
941 return 0;
942 sbi->s_resgid = option;
943 break;
944 case Opt_sb:
945 /* handled by get_sb_block() instead of here */
946 /* *sb_block = match_int(&args[0]); */
947 break;
948 case Opt_err_panic:
949 clear_opt (sbi->s_mount_opt, ERRORS_CONT);
950 clear_opt (sbi->s_mount_opt, ERRORS_RO);
951 set_opt (sbi->s_mount_opt, ERRORS_PANIC);
952 break;
953 case Opt_err_ro:
954 clear_opt (sbi->s_mount_opt, ERRORS_CONT);
955 clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
956 set_opt (sbi->s_mount_opt, ERRORS_RO);
957 break;
958 case Opt_err_cont:
959 clear_opt (sbi->s_mount_opt, ERRORS_RO);
960 clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
961 set_opt (sbi->s_mount_opt, ERRORS_CONT);
962 break;
963 case Opt_nouid32:
964 set_opt (sbi->s_mount_opt, NO_UID32);
965 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 case Opt_nocheck:
967 clear_opt (sbi->s_mount_opt, CHECK);
968 break;
969 case Opt_debug:
970 set_opt (sbi->s_mount_opt, DEBUG);
971 break;
972 case Opt_oldalloc:
973 set_opt (sbi->s_mount_opt, OLDALLOC);
974 break;
975 case Opt_orlov:
976 clear_opt (sbi->s_mount_opt, OLDALLOC);
977 break;
978#ifdef CONFIG_EXT3_FS_XATTR
979 case Opt_user_xattr:
980 set_opt (sbi->s_mount_opt, XATTR_USER);
981 break;
982 case Opt_nouser_xattr:
983 clear_opt (sbi->s_mount_opt, XATTR_USER);
984 break;
985#else
986 case Opt_user_xattr:
987 case Opt_nouser_xattr:
Alexey Fisher4cf46b62009-11-22 20:38:55 +0100988 ext3_msg(sb, KERN_INFO,
989 "(no)user_xattr options not supported");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 break;
991#endif
992#ifdef CONFIG_EXT3_FS_POSIX_ACL
993 case Opt_acl:
994 set_opt(sbi->s_mount_opt, POSIX_ACL);
995 break;
996 case Opt_noacl:
997 clear_opt(sbi->s_mount_opt, POSIX_ACL);
998 break;
999#else
1000 case Opt_acl:
1001 case Opt_noacl:
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001002 ext3_msg(sb, KERN_INFO,
1003 "(no)acl options not supported");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 break;
1005#endif
1006 case Opt_reservation:
1007 set_opt(sbi->s_mount_opt, RESERVATION);
1008 break;
1009 case Opt_noreservation:
1010 clear_opt(sbi->s_mount_opt, RESERVATION);
1011 break;
1012 case Opt_journal_update:
1013 /* @@@ FIXME */
1014 /* Eventually we will want to be able to create
1015 a journal file here. For now, only allow the
1016 user to specify an existing inode to be the
1017 journal file. */
1018 if (is_remount) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001019 ext3_msg(sb, KERN_ERR, "error: cannot specify "
1020 "journal on remount");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 return 0;
1022 }
1023 set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
1024 break;
1025 case Opt_journal_inum:
1026 if (is_remount) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001027 ext3_msg(sb, KERN_ERR, "error: cannot specify "
1028 "journal on remount");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 return 0;
1030 }
1031 if (match_int(&args[0], &option))
1032 return 0;
1033 *inum = option;
1034 break;
Johann Lombardi71b96252006-01-08 01:03:20 -08001035 case Opt_journal_dev:
1036 if (is_remount) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001037 ext3_msg(sb, KERN_ERR, "error: cannot specify "
1038 "journal on remount");
Johann Lombardi71b96252006-01-08 01:03:20 -08001039 return 0;
1040 }
1041 if (match_int(&args[0], &option))
1042 return 0;
1043 *journal_devnum = option;
1044 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 case Opt_noload:
1046 set_opt (sbi->s_mount_opt, NOLOAD);
1047 break;
1048 case Opt_commit:
1049 if (match_int(&args[0], &option))
1050 return 0;
1051 if (option < 0)
1052 return 0;
1053 if (option == 0)
1054 option = JBD_DEFAULT_MAX_COMMIT_AGE;
1055 sbi->s_commit_interval = HZ * option;
1056 break;
1057 case Opt_data_journal:
1058 data_opt = EXT3_MOUNT_JOURNAL_DATA;
1059 goto datacheck;
1060 case Opt_data_ordered:
1061 data_opt = EXT3_MOUNT_ORDERED_DATA;
1062 goto datacheck;
1063 case Opt_data_writeback:
1064 data_opt = EXT3_MOUNT_WRITEBACK_DATA;
1065 datacheck:
1066 if (is_remount) {
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001067 if (test_opt(sb, DATA_FLAGS) == data_opt)
Jan Kara3c4cec62009-08-24 16:38:43 +02001068 break;
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001069 ext3_msg(sb, KERN_ERR,
1070 "error: cannot change "
Jan Kara3c4cec62009-08-24 16:38:43 +02001071 "data mode on remount. The filesystem "
1072 "is mounted in data=%s mode and you "
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001073 "try to remount it in data=%s mode.",
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001074 data_mode_string(test_opt(sb,
1075 DATA_FLAGS)),
Jan Kara3c4cec62009-08-24 16:38:43 +02001076 data_mode_string(data_opt));
1077 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 } else {
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001079 clear_opt(sbi->s_mount_opt, DATA_FLAGS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 sbi->s_mount_opt |= data_opt;
1081 }
1082 break;
Hidehiro Kawai0e4fb5e2008-10-18 20:27:57 -07001083 case Opt_data_err_abort:
1084 set_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
1085 break;
1086 case Opt_data_err_ignore:
1087 clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
1088 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089#ifdef CONFIG_QUOTA
1090 case Opt_usrjquota:
1091 qtype = USRQUOTA;
1092 goto set_qf_name;
1093 case Opt_grpjquota:
1094 qtype = GRPQUOTA;
1095set_qf_name:
Jan Karaee0d5ff2008-08-20 18:11:50 +02001096 if (sb_any_quota_loaded(sb) &&
Jan Karad06bf1d2008-07-25 01:46:18 -07001097 !sbi->s_qf_names[qtype]) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001098 ext3_msg(sb, KERN_ERR,
1099 "error: cannot change journaled "
1100 "quota options when quota turned on.");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101 return 0;
1102 }
1103 qname = match_strdup(&args[0]);
1104 if (!qname) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001105 ext3_msg(sb, KERN_ERR,
1106 "error: not enough memory for "
1107 "storing quotafile name.");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 return 0;
1109 }
1110 if (sbi->s_qf_names[qtype] &&
1111 strcmp(sbi->s_qf_names[qtype], qname)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001112 ext3_msg(sb, KERN_ERR,
1113 "error: %s quota file already "
1114 "specified.", QTYPE2NAME(qtype));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 kfree(qname);
1116 return 0;
1117 }
1118 sbi->s_qf_names[qtype] = qname;
1119 if (strchr(sbi->s_qf_names[qtype], '/')) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001120 ext3_msg(sb, KERN_ERR,
1121 "error: quotafile must be on "
1122 "filesystem root.");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 kfree(sbi->s_qf_names[qtype]);
1124 sbi->s_qf_names[qtype] = NULL;
1125 return 0;
1126 }
Jan Kara1f545872005-06-23 22:01:04 -07001127 set_opt(sbi->s_mount_opt, QUOTA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 break;
1129 case Opt_offusrjquota:
1130 qtype = USRQUOTA;
1131 goto clear_qf_name;
1132 case Opt_offgrpjquota:
1133 qtype = GRPQUOTA;
1134clear_qf_name:
Jan Karaee0d5ff2008-08-20 18:11:50 +02001135 if (sb_any_quota_loaded(sb) &&
Jan Karad06bf1d2008-07-25 01:46:18 -07001136 sbi->s_qf_names[qtype]) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001137 ext3_msg(sb, KERN_ERR, "error: cannot change "
Jan Kara99aeaf62008-07-25 01:46:17 -07001138 "journaled quota options when "
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001139 "quota turned on.");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 return 0;
1141 }
Jan Kara08c6a962005-07-12 13:58:28 -07001142 /*
1143 * The space will be released later when all options
1144 * are confirmed to be correct
1145 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 sbi->s_qf_names[qtype] = NULL;
1147 break;
1148 case Opt_jqfmt_vfsold:
Jan Karad06bf1d2008-07-25 01:46:18 -07001149 qfmt = QFMT_VFS_OLD;
1150 goto set_qf_format;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 case Opt_jqfmt_vfsv0:
Jan Karad06bf1d2008-07-25 01:46:18 -07001152 qfmt = QFMT_VFS_V0;
Jan Kara1aeec432009-11-30 22:22:41 +01001153 goto set_qf_format;
1154 case Opt_jqfmt_vfsv1:
1155 qfmt = QFMT_VFS_V1;
Jan Karad06bf1d2008-07-25 01:46:18 -07001156set_qf_format:
Jan Karaee0d5ff2008-08-20 18:11:50 +02001157 if (sb_any_quota_loaded(sb) &&
Jan Karad06bf1d2008-07-25 01:46:18 -07001158 sbi->s_jquota_fmt != qfmt) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001159 ext3_msg(sb, KERN_ERR, "error: cannot change "
Jan Karad06bf1d2008-07-25 01:46:18 -07001160 "journaled quota options when "
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001161 "quota turned on.");
Jan Karad06bf1d2008-07-25 01:46:18 -07001162 return 0;
1163 }
1164 sbi->s_jquota_fmt = qfmt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 break;
Jan Kara1f545872005-06-23 22:01:04 -07001166 case Opt_quota:
Mark Bellon8fc27512005-09-06 15:16:54 -07001167 case Opt_usrquota:
Jan Kara1f545872005-06-23 22:01:04 -07001168 set_opt(sbi->s_mount_opt, QUOTA);
Mark Bellon8fc27512005-09-06 15:16:54 -07001169 set_opt(sbi->s_mount_opt, USRQUOTA);
1170 break;
1171 case Opt_grpquota:
1172 set_opt(sbi->s_mount_opt, QUOTA);
1173 set_opt(sbi->s_mount_opt, GRPQUOTA);
Jan Kara1f545872005-06-23 22:01:04 -07001174 break;
1175 case Opt_noquota:
Jan Karaee0d5ff2008-08-20 18:11:50 +02001176 if (sb_any_quota_loaded(sb)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001177 ext3_msg(sb, KERN_ERR, "error: cannot change "
1178 "quota options when quota turned on.");
Jan Kara1f545872005-06-23 22:01:04 -07001179 return 0;
1180 }
1181 clear_opt(sbi->s_mount_opt, QUOTA);
Mark Bellon8fc27512005-09-06 15:16:54 -07001182 clear_opt(sbi->s_mount_opt, USRQUOTA);
1183 clear_opt(sbi->s_mount_opt, GRPQUOTA);
Jan Kara1f545872005-06-23 22:01:04 -07001184 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185#else
Mark Bellon8fc27512005-09-06 15:16:54 -07001186 case Opt_quota:
1187 case Opt_usrquota:
1188 case Opt_grpquota:
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001189 ext3_msg(sb, KERN_ERR,
1190 "error: quota options not supported.");
Jan Karafa1ff1e2008-04-28 02:16:14 -07001191 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 case Opt_usrjquota:
1193 case Opt_grpjquota:
1194 case Opt_offusrjquota:
1195 case Opt_offgrpjquota:
1196 case Opt_jqfmt_vfsold:
1197 case Opt_jqfmt_vfsv0:
Jan Kara1aeec432009-11-30 22:22:41 +01001198 case Opt_jqfmt_vfsv1:
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001199 ext3_msg(sb, KERN_ERR,
1200 "error: journaled quota options not "
1201 "supported.");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 break;
Jan Kara1f545872005-06-23 22:01:04 -07001203 case Opt_noquota:
1204 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205#endif
1206 case Opt_abort:
1207 set_opt(sbi->s_mount_opt, ABORT);
1208 break;
1209 case Opt_barrier:
1210 if (match_int(&args[0], &option))
1211 return 0;
1212 if (option)
1213 set_opt(sbi->s_mount_opt, BARRIER);
1214 else
1215 clear_opt(sbi->s_mount_opt, BARRIER);
1216 break;
1217 case Opt_ignore:
1218 break;
1219 case Opt_resize:
Jan Kara08c6a962005-07-12 13:58:28 -07001220 if (!is_remount) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001221 ext3_msg(sb, KERN_ERR,
1222 "error: resize option only available "
1223 "for remount");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 return 0;
1225 }
KAMBAROV, ZAURc7f17212005-06-28 20:45:11 -07001226 if (match_int(&args[0], &option) != 0)
1227 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 *n_blocks_count = option;
1229 break;
1230 case Opt_nobh:
1231 set_opt(sbi->s_mount_opt, NOBH);
1232 break;
Badari Pulavartyade1a292006-06-26 00:25:04 -07001233 case Opt_bh:
1234 clear_opt(sbi->s_mount_opt, NOBH);
1235 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 default:
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001237 ext3_msg(sb, KERN_ERR,
1238 "error: unrecognized mount option \"%s\" "
1239 "or missing value", p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 return 0;
1241 }
1242 }
1243#ifdef CONFIG_QUOTA
Mark Bellon8fc27512005-09-06 15:16:54 -07001244 if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001245 if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
Mark Bellon8fc27512005-09-06 15:16:54 -07001246 clear_opt(sbi->s_mount_opt, USRQUOTA);
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001247 if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
Mark Bellon8fc27512005-09-06 15:16:54 -07001248 clear_opt(sbi->s_mount_opt, GRPQUOTA);
1249
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001250 if ((sbi->s_qf_names[USRQUOTA] && test_opt(sb, GRPQUOTA)) ||
1251 (sbi->s_qf_names[GRPQUOTA] && test_opt(sb, USRQUOTA))) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001252 ext3_msg(sb, KERN_ERR, "error: old and new quota "
1253 "format mixing.");
Mark Bellon8fc27512005-09-06 15:16:54 -07001254 return 0;
1255 }
1256
1257 if (!sbi->s_jquota_fmt) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001258 ext3_msg(sb, KERN_ERR, "error: journaled quota format "
1259 "not specified.");
Mark Bellon8fc27512005-09-06 15:16:54 -07001260 return 0;
1261 }
1262 } else {
1263 if (sbi->s_jquota_fmt) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001264 ext3_msg(sb, KERN_ERR, "error: journaled quota format "
Jan Kara99aeaf62008-07-25 01:46:17 -07001265 "specified with no journaling "
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001266 "enabled.");
Mark Bellon8fc27512005-09-06 15:16:54 -07001267 return 0;
1268 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 }
1270#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 return 1;
1272}
1273
1274static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
1275 int read_only)
1276{
1277 struct ext3_sb_info *sbi = EXT3_SB(sb);
1278 int res = 0;
1279
1280 if (le32_to_cpu(es->s_rev_level) > EXT3_MAX_SUPP_REV) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001281 ext3_msg(sb, KERN_ERR,
1282 "error: revision level too high, "
1283 "forcing read-only mode");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 res = MS_RDONLY;
1285 }
1286 if (read_only)
1287 return res;
1288 if (!(sbi->s_mount_state & EXT3_VALID_FS))
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001289 ext3_msg(sb, KERN_WARNING,
1290 "warning: mounting unchecked fs, "
1291 "running e2fsck is recommended");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 else if ((sbi->s_mount_state & EXT3_ERROR_FS))
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001293 ext3_msg(sb, KERN_WARNING,
1294 "warning: mounting fs with errors, "
1295 "running e2fsck is recommended");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
1297 le16_to_cpu(es->s_mnt_count) >=
1298 (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001299 ext3_msg(sb, KERN_WARNING,
1300 "warning: maximal mount count reached, "
1301 "running e2fsck is recommended");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302 else if (le32_to_cpu(es->s_checkinterval) &&
1303 (le32_to_cpu(es->s_lastcheck) +
1304 le32_to_cpu(es->s_checkinterval) <= get_seconds()))
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001305 ext3_msg(sb, KERN_WARNING,
1306 "warning: checktime reached, "
1307 "running e2fsck is recommended");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308#if 0
1309 /* @@@ We _will_ want to clear the valid bit if we find
1310 inconsistencies, to force a fsck at reboot. But for
1311 a plain journaled filesystem we can keep it set as
1312 valid forever! :) */
Marcin Slusarze7f23eb2008-04-28 02:16:06 -07001313 es->s_state &= cpu_to_le16(~EXT3_VALID_FS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314#endif
1315 if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
1316 es->s_max_mnt_count = cpu_to_le16(EXT3_DFL_MAX_MNT_COUNT);
Marcin Slusarz50e8a282008-02-08 04:20:13 -08001317 le16_add_cpu(&es->s_mnt_count, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 es->s_mtime = cpu_to_le32(get_seconds());
1319 ext3_update_dynamic_rev(sb);
1320 EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
1321
1322 ext3_commit_super(sb, es, 1);
1323 if (test_opt(sb, DEBUG))
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001324 ext3_msg(sb, KERN_INFO, "[bs=%lu, gc=%lu, "
1325 "bpg=%lu, ipg=%lu, mo=%04lx]",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 sb->s_blocksize,
1327 sbi->s_groups_count,
1328 EXT3_BLOCKS_PER_GROUP(sb),
1329 EXT3_INODES_PER_GROUP(sb),
1330 sbi->s_mount_opt);
1331
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
1333 char b[BDEVNAME_SIZE];
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001334 ext3_msg(sb, KERN_INFO, "using external journal on %s",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 bdevname(EXT3_SB(sb)->s_journal->j_dev, b));
1336 } else {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001337 ext3_msg(sb, KERN_INFO, "using internal journal");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 return res;
1340}
1341
1342/* Called at mount-time, super-block is locked */
Akinobu Mita197cd65a2008-02-06 01:40:16 -08001343static int ext3_check_descriptors(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344{
1345 struct ext3_sb_info *sbi = EXT3_SB(sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 int i;
1347
1348 ext3_debug ("Checking group descriptors");
1349
Akinobu Mita197cd65a2008-02-06 01:40:16 -08001350 for (i = 0; i < sbi->s_groups_count; i++) {
1351 struct ext3_group_desc *gdp = ext3_get_group_desc(sb, i, NULL);
Akinobu Mita1eaafea2008-04-28 02:16:07 -07001352 ext3_fsblk_t first_block = ext3_group_first_block_no(sb, i);
1353 ext3_fsblk_t last_block;
Akinobu Mita197cd65a2008-02-06 01:40:16 -08001354
Eric Sandeen855565e2006-09-27 01:49:29 -07001355 if (i == sbi->s_groups_count - 1)
1356 last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1;
1357 else
1358 last_block = first_block +
1359 (EXT3_BLOCKS_PER_GROUP(sb) - 1);
1360
Eric Sandeen855565e2006-09-27 01:49:29 -07001361 if (le32_to_cpu(gdp->bg_block_bitmap) < first_block ||
1362 le32_to_cpu(gdp->bg_block_bitmap) > last_block)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 {
1364 ext3_error (sb, "ext3_check_descriptors",
1365 "Block bitmap for group %d"
1366 " not in group (block %lu)!",
1367 i, (unsigned long)
1368 le32_to_cpu(gdp->bg_block_bitmap));
1369 return 0;
1370 }
Eric Sandeen855565e2006-09-27 01:49:29 -07001371 if (le32_to_cpu(gdp->bg_inode_bitmap) < first_block ||
1372 le32_to_cpu(gdp->bg_inode_bitmap) > last_block)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 {
1374 ext3_error (sb, "ext3_check_descriptors",
1375 "Inode bitmap for group %d"
1376 " not in group (block %lu)!",
1377 i, (unsigned long)
1378 le32_to_cpu(gdp->bg_inode_bitmap));
1379 return 0;
1380 }
Eric Sandeen855565e2006-09-27 01:49:29 -07001381 if (le32_to_cpu(gdp->bg_inode_table) < first_block ||
Eric Sandeen780dcdb2007-07-26 10:41:11 -07001382 le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group - 1 >
Eric Sandeen855565e2006-09-27 01:49:29 -07001383 last_block)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 {
1385 ext3_error (sb, "ext3_check_descriptors",
1386 "Inode table for group %d"
1387 " not in group (block %lu)!",
1388 i, (unsigned long)
1389 le32_to_cpu(gdp->bg_inode_table));
1390 return 0;
1391 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 }
1393
1394 sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));
1395 sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb));
1396 return 1;
1397}
1398
1399
1400/* ext3_orphan_cleanup() walks a singly-linked list of inodes (starting at
1401 * the superblock) which were deleted from all directories, but held open by
1402 * a process at the time of a crash. We walk the list and try to delete these
1403 * inodes at recovery time (only with a read-write filesystem).
1404 *
1405 * In order to keep the orphan inode chain consistent during traversal (in
1406 * case of crash during recovery), we link each inode into the superblock
1407 * orphan list_head and handle it the same way as an inode deletion during
1408 * normal operation (which journals the operations for us).
1409 *
1410 * We only do an iget() and an iput() on each inode, which is very safe if we
1411 * accidentally point at an in-use or already deleted inode. The worst that
1412 * can happen in this case is that we get a "bit already cleared" message from
1413 * ext3_free_inode(). The only reason we would point at a wrong inode is if
1414 * e2fsck was run on this filesystem, and it must have already done the orphan
1415 * inode cleanup for us, so we can safely abort without any further action.
1416 */
1417static void ext3_orphan_cleanup (struct super_block * sb,
1418 struct ext3_super_block * es)
1419{
1420 unsigned int s_flags = sb->s_flags;
1421 int nr_orphans = 0, nr_truncates = 0;
1422#ifdef CONFIG_QUOTA
1423 int i;
1424#endif
1425 if (!es->s_last_orphan) {
1426 jbd_debug(4, "no orphan inodes to clean up\n");
1427 return;
1428 }
1429
Eric Sandeena8f48a92006-12-06 20:40:13 -08001430 if (bdev_read_only(sb->s_bdev)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001431 ext3_msg(sb, KERN_ERR, "error: write access "
1432 "unavailable, skipping orphan cleanup.");
Eric Sandeena8f48a92006-12-06 20:40:13 -08001433 return;
1434 }
1435
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) {
1437 if (es->s_last_orphan)
1438 jbd_debug(1, "Errors on filesystem, "
1439 "clearing orphan list.\n");
1440 es->s_last_orphan = 0;
1441 jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
1442 return;
1443 }
1444
1445 if (s_flags & MS_RDONLY) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001446 ext3_msg(sb, KERN_INFO, "orphan cleanup on readonly fs");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 sb->s_flags &= ~MS_RDONLY;
1448 }
1449#ifdef CONFIG_QUOTA
1450 /* Needed for iput() to work correctly and not trash data */
1451 sb->s_flags |= MS_ACTIVE;
1452 /* Turn on quotas so that they are updated correctly */
1453 for (i = 0; i < MAXQUOTAS; i++) {
1454 if (EXT3_SB(sb)->s_qf_names[i]) {
1455 int ret = ext3_quota_on_mount(sb, i);
1456 if (ret < 0)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001457 ext3_msg(sb, KERN_ERR,
1458 "error: cannot turn on journaled "
1459 "quota: %d", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 }
1461 }
1462#endif
1463
1464 while (es->s_last_orphan) {
1465 struct inode *inode;
1466
David Howells473043d2008-02-07 00:15:36 -08001467 inode = ext3_orphan_get(sb, le32_to_cpu(es->s_last_orphan));
1468 if (IS_ERR(inode)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 es->s_last_orphan = 0;
1470 break;
1471 }
1472
1473 list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
Jan Kara81a05222009-01-26 16:58:01 +01001474 vfs_dq_init(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 if (inode->i_nlink) {
1476 printk(KERN_DEBUG
Eric Sandeeneee194e2006-09-27 01:49:30 -07001477 "%s: truncating inode %lu to %Ld bytes\n",
Harvey Harrisone05b6b52008-04-28 02:16:15 -07001478 __func__, inode->i_ino, inode->i_size);
Eric Sandeeneee194e2006-09-27 01:49:30 -07001479 jbd_debug(2, "truncating inode %lu to %Ld bytes\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 inode->i_ino, inode->i_size);
1481 ext3_truncate(inode);
1482 nr_truncates++;
1483 } else {
1484 printk(KERN_DEBUG
Eric Sandeeneee194e2006-09-27 01:49:30 -07001485 "%s: deleting unreferenced inode %lu\n",
Harvey Harrisone05b6b52008-04-28 02:16:15 -07001486 __func__, inode->i_ino);
Eric Sandeeneee194e2006-09-27 01:49:30 -07001487 jbd_debug(2, "deleting unreferenced inode %lu\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 inode->i_ino);
1489 nr_orphans++;
1490 }
1491 iput(inode); /* The delete magic happens here! */
1492 }
1493
1494#define PLURAL(x) (x), ((x)==1) ? "" : "s"
1495
1496 if (nr_orphans)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001497 ext3_msg(sb, KERN_INFO, "%d orphan inode%s deleted",
1498 PLURAL(nr_orphans));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 if (nr_truncates)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001500 ext3_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
1501 PLURAL(nr_truncates));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502#ifdef CONFIG_QUOTA
1503 /* Turn quotas off */
1504 for (i = 0; i < MAXQUOTAS; i++) {
1505 if (sb_dqopt(sb)->files[i])
Jan Kara2fd83a42008-04-28 02:14:34 -07001506 vfs_quota_off(sb, i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 }
1508#endif
1509 sb->s_flags = s_flags; /* Restore MS_RDONLY status */
1510}
1511
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512/*
1513 * Maximal file size. There is a direct, and {,double-,triple-}indirect
1514 * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
1515 * We need to be 1 filesystem block less than the 2^32 sector limit.
1516 */
1517static loff_t ext3_max_size(int bits)
1518{
1519 loff_t res = EXT3_NDIR_BLOCKS;
Aneesh Kumar K.Vfe7fdc32008-01-28 23:58:26 -05001520 int meta_blocks;
1521 loff_t upper_limit;
1522
1523 /* This is calculated to be the largest file size for a
1524 * dense, file such that the total number of
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 * sectors in the file, including data and all indirect blocks,
Aneesh Kumar K.Vfe7fdc32008-01-28 23:58:26 -05001526 * does not exceed 2^32 -1
1527 * __u32 i_blocks representing the total number of
1528 * 512 bytes blocks of the file
1529 */
1530 upper_limit = (1LL << 32) - 1;
1531
1532 /* total blocks in file system block size */
1533 upper_limit >>= (bits - 9);
1534
1535
1536 /* indirect blocks */
1537 meta_blocks = 1;
1538 /* double indirect blocks */
1539 meta_blocks += 1 + (1LL << (bits-2));
1540 /* tripple indirect blocks */
1541 meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2)));
1542
1543 upper_limit -= meta_blocks;
1544 upper_limit <<= bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545
1546 res += 1LL << (bits-2);
1547 res += 1LL << (2*(bits-2));
1548 res += 1LL << (3*(bits-2));
1549 res <<= bits;
1550 if (res > upper_limit)
1551 res = upper_limit;
Aneesh Kumar K.Vfe7fdc32008-01-28 23:58:26 -05001552
1553 if (res > MAX_LFS_FILESIZE)
1554 res = MAX_LFS_FILESIZE;
1555
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 return res;
1557}
1558
Mingming Cao43d23f92006-06-25 05:48:07 -07001559static ext3_fsblk_t descriptor_loc(struct super_block *sb,
1560 ext3_fsblk_t logic_sb_block,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 int nr)
1562{
1563 struct ext3_sb_info *sbi = EXT3_SB(sb);
Mingming Cao43d23f92006-06-25 05:48:07 -07001564 unsigned long bg, first_meta_bg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 int has_super = 0;
1566
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
1568
1569 if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) ||
1570 nr < first_meta_bg)
1571 return (logic_sb_block + nr + 1);
1572 bg = sbi->s_desc_per_block * nr;
1573 if (ext3_bg_has_super(sb, bg))
1574 has_super = 1;
Mingming Cao43d23f92006-06-25 05:48:07 -07001575 return (has_super + ext3_group_first_block_no(sb, bg));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576}
1577
1578
1579static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1580{
1581 struct buffer_head * bh;
1582 struct ext3_super_block *es = NULL;
1583 struct ext3_sb_info *sbi;
Mingming Cao43d23f92006-06-25 05:48:07 -07001584 ext3_fsblk_t block;
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001585 ext3_fsblk_t sb_block = get_sb_block(&data, sb);
Mingming Cao43d23f92006-06-25 05:48:07 -07001586 ext3_fsblk_t logic_sb_block;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 unsigned long offset = 0;
Eric Sandeeneee194e2006-09-27 01:49:30 -07001588 unsigned int journal_inum = 0;
Johann Lombardi71b96252006-01-08 01:03:20 -08001589 unsigned long journal_devnum = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 unsigned long def_mount_opts;
1591 struct inode *root;
1592 int blocksize;
1593 int hblock;
1594 int db_count;
1595 int i;
1596 int needs_recovery;
David Howells473043d2008-02-07 00:15:36 -08001597 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 __le32 features;
Peter Zijlstra833f4072007-10-16 23:25:45 -07001599 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
Panagiotis Issarisf8314dc2006-09-27 01:49:37 -07001601 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 if (!sbi)
1603 return -ENOMEM;
Pekka Enberg5df096d2009-01-07 18:07:25 -08001604
1605 sbi->s_blockgroup_lock =
1606 kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
1607 if (!sbi->s_blockgroup_lock) {
1608 kfree(sbi);
1609 return -ENOMEM;
1610 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 sb->s_fs_info = sbi;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 sbi->s_mount_opt = 0;
1613 sbi->s_resuid = EXT3_DEF_RESUID;
1614 sbi->s_resgid = EXT3_DEF_RESGID;
Miklos Szeredi571beed2007-10-16 23:26:26 -07001615 sbi->s_sb_block = sb_block;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616
1617 unlock_kernel();
1618
1619 blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
1620 if (!blocksize) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001621 ext3_msg(sb, KERN_ERR, "error: unable to set blocksize");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 goto out_fail;
1623 }
1624
1625 /*
1626 * The ext3 superblock will not be buffer aligned for other than 1kB
1627 * block sizes. We need to calculate the offset from buffer start.
1628 */
1629 if (blocksize != EXT3_MIN_BLOCK_SIZE) {
1630 logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
1631 offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
1632 } else {
1633 logic_sb_block = sb_block;
1634 }
1635
1636 if (!(bh = sb_bread(sb, logic_sb_block))) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001637 ext3_msg(sb, KERN_ERR, "error: unable to read superblock");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 goto out_fail;
1639 }
1640 /*
1641 * Note: s_es must be initialized as soon as possible because
1642 * some ext3 macro-instructions depend on its value
1643 */
1644 es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);
1645 sbi->s_es = es;
1646 sb->s_magic = le16_to_cpu(es->s_magic);
1647 if (sb->s_magic != EXT3_SUPER_MAGIC)
1648 goto cantfind_ext3;
1649
1650 /* Set defaults before we parse the mount options */
1651 def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
1652 if (def_mount_opts & EXT3_DEFM_DEBUG)
1653 set_opt(sbi->s_mount_opt, DEBUG);
1654 if (def_mount_opts & EXT3_DEFM_BSDGROUPS)
1655 set_opt(sbi->s_mount_opt, GRPID);
1656 if (def_mount_opts & EXT3_DEFM_UID16)
1657 set_opt(sbi->s_mount_opt, NO_UID32);
Hugh Dickins2e7842b2007-02-10 01:46:13 -08001658#ifdef CONFIG_EXT3_FS_XATTR
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 if (def_mount_opts & EXT3_DEFM_XATTR_USER)
1660 set_opt(sbi->s_mount_opt, XATTR_USER);
Hugh Dickins2e7842b2007-02-10 01:46:13 -08001661#endif
1662#ifdef CONFIG_EXT3_FS_POSIX_ACL
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 if (def_mount_opts & EXT3_DEFM_ACL)
1664 set_opt(sbi->s_mount_opt, POSIX_ACL);
Hugh Dickins2e7842b2007-02-10 01:46:13 -08001665#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001667 set_opt(sbi->s_mount_opt, JOURNAL_DATA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001669 set_opt(sbi->s_mount_opt, ORDERED_DATA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_WBACK)
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001671 set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672
1673 if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC)
1674 set_opt(sbi->s_mount_opt, ERRORS_PANIC);
Aneesh Kumar K.V1eca93f2008-02-06 01:40:14 -08001675 else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_CONTINUE)
Dmitry Mishin2245d7c2006-10-11 01:21:49 -07001676 set_opt(sbi->s_mount_opt, ERRORS_CONT);
Aneesh Kumar K.V1eca93f2008-02-06 01:40:14 -08001677 else
1678 set_opt(sbi->s_mount_opt, ERRORS_RO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
1680 sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
1681 sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
1682
1683 set_opt(sbi->s_mount_opt, RESERVATION);
1684
Johann Lombardi71b96252006-01-08 01:03:20 -08001685 if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
1686 NULL, 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 goto failed_mount;
1688
1689 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
Dmitry Monakhove3c96432010-02-02 16:05:51 +03001690 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
1692 if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&
1693 (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
1694 EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
1695 EXT3_HAS_INCOMPAT_FEATURE(sb, ~0U)))
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001696 ext3_msg(sb, KERN_WARNING,
1697 "warning: feature flags set on rev 0 fs, "
1698 "running e2fsck is recommended");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 /*
1700 * Check feature flags regardless of the revision level, since we
1701 * previously didn't change the revision level when setting the flags,
1702 * so there is a chance incompat flags are set on a rev 0 filesystem.
1703 */
1704 features = EXT3_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP);
1705 if (features) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001706 ext3_msg(sb, KERN_ERR,
1707 "error: couldn't mount because of unsupported "
1708 "optional features (%x)", le32_to_cpu(features));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 goto failed_mount;
1710 }
1711 features = EXT3_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP);
1712 if (!(sb->s_flags & MS_RDONLY) && features) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001713 ext3_msg(sb, KERN_ERR,
1714 "error: couldn't mount RDWR because of unsupported "
1715 "optional features (%x)", le32_to_cpu(features));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 goto failed_mount;
1717 }
1718 blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
1719
1720 if (blocksize < EXT3_MIN_BLOCK_SIZE ||
1721 blocksize > EXT3_MAX_BLOCK_SIZE) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001722 ext3_msg(sb, KERN_ERR,
1723 "error: couldn't mount because of unsupported "
1724 "filesystem blocksize %d", blocksize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 goto failed_mount;
1726 }
1727
Martin K. Petersene1defc42009-05-22 17:17:49 -04001728 hblock = bdev_logical_block_size(sb->s_bdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 if (sb->s_blocksize != blocksize) {
1730 /*
1731 * Make sure the blocksize for the filesystem is larger
1732 * than the hardware sectorsize for the machine.
1733 */
1734 if (blocksize < hblock) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001735 ext3_msg(sb, KERN_ERR,
1736 "error: fsblocksize %d too small for "
1737 "hardware sectorsize %d", blocksize, hblock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 goto failed_mount;
1739 }
1740
1741 brelse (bh);
Takashi Sato0f0a89e2007-10-18 03:06:56 -07001742 if (!sb_set_blocksize(sb, blocksize)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001743 ext3_msg(sb, KERN_ERR,
1744 "error: bad blocksize %d", blocksize);
Takashi Sato0f0a89e2007-10-18 03:06:56 -07001745 goto out_fail;
1746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
1748 offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
1749 bh = sb_bread(sb, logic_sb_block);
1750 if (!bh) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001751 ext3_msg(sb, KERN_ERR,
1752 "error: can't read superblock on 2nd try");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 goto failed_mount;
1754 }
1755 es = (struct ext3_super_block *)(((char *)bh->b_data) + offset);
1756 sbi->s_es = es;
1757 if (es->s_magic != cpu_to_le16(EXT3_SUPER_MAGIC)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001758 ext3_msg(sb, KERN_ERR,
1759 "error: magic mismatch");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 goto failed_mount;
1761 }
1762 }
1763
1764 sb->s_maxbytes = ext3_max_size(sb->s_blocksize_bits);
1765
1766 if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV) {
1767 sbi->s_inode_size = EXT3_GOOD_OLD_INODE_SIZE;
1768 sbi->s_first_ino = EXT3_GOOD_OLD_FIRST_INO;
1769 } else {
1770 sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
1771 sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
1772 if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
vignesh babu3fc74262007-07-15 23:41:17 -07001773 (!is_power_of_2(sbi->s_inode_size)) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 (sbi->s_inode_size > blocksize)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001775 ext3_msg(sb, KERN_ERR,
1776 "error: unsupported inode size: %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 sbi->s_inode_size);
1778 goto failed_mount;
1779 }
1780 }
1781 sbi->s_frag_size = EXT3_MIN_FRAG_SIZE <<
1782 le32_to_cpu(es->s_log_frag_size);
1783 if (blocksize != sbi->s_frag_size) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001784 ext3_msg(sb, KERN_ERR,
1785 "error: fragsize %lu != blocksize %u (unsupported)",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 sbi->s_frag_size, blocksize);
1787 goto failed_mount;
1788 }
1789 sbi->s_frags_per_block = 1;
1790 sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
1791 sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
1792 sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
Andries E. Brouwerb47b6f32007-12-17 16:19:55 -08001793 if (EXT3_INODE_SIZE(sb) == 0 || EXT3_INODES_PER_GROUP(sb) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 goto cantfind_ext3;
1795 sbi->s_inodes_per_block = blocksize / EXT3_INODE_SIZE(sb);
1796 if (sbi->s_inodes_per_block == 0)
1797 goto cantfind_ext3;
1798 sbi->s_itb_per_group = sbi->s_inodes_per_group /
1799 sbi->s_inodes_per_block;
1800 sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);
1801 sbi->s_sbh = bh;
1802 sbi->s_mount_state = le16_to_cpu(es->s_state);
David Howellsf0d1b0b2006-12-08 02:37:49 -08001803 sbi->s_addr_per_block_bits = ilog2(EXT3_ADDR_PER_BLOCK(sb));
1804 sbi->s_desc_per_block_bits = ilog2(EXT3_DESC_PER_BLOCK(sb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 for (i=0; i < 4; i++)
1806 sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
1807 sbi->s_def_hash_version = es->s_def_hash_version;
Theodore Ts'o5e1f8c92008-10-28 13:21:55 -04001808 i = le32_to_cpu(es->s_flags);
1809 if (i & EXT2_FLAGS_UNSIGNED_HASH)
1810 sbi->s_hash_unsigned = 3;
1811 else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
1812#ifdef __CHAR_UNSIGNED__
1813 es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
1814 sbi->s_hash_unsigned = 3;
1815#else
1816 es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
1817#endif
Theodore Ts'o5e1f8c92008-10-28 13:21:55 -04001818 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820 if (sbi->s_blocks_per_group > blocksize * 8) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001821 ext3_msg(sb, KERN_ERR,
1822 "#blocks per group too big: %lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 sbi->s_blocks_per_group);
1824 goto failed_mount;
1825 }
1826 if (sbi->s_frags_per_group > blocksize * 8) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001827 ext3_msg(sb, KERN_ERR,
1828 "error: #fragments per group too big: %lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 sbi->s_frags_per_group);
1830 goto failed_mount;
1831 }
1832 if (sbi->s_inodes_per_group > blocksize * 8) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001833 ext3_msg(sb, KERN_ERR,
1834 "error: #inodes per group too big: %lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 sbi->s_inodes_per_group);
1836 goto failed_mount;
1837 }
1838
Mingming Caofcd5df32006-06-25 05:47:50 -07001839 if (le32_to_cpu(es->s_blocks_count) >
1840 (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001841 ext3_msg(sb, KERN_ERR,
1842 "error: filesystem is too large to mount safely");
Mingming Caofcd5df32006-06-25 05:47:50 -07001843 if (sizeof(sector_t) < 8)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001844 ext3_msg(sb, KERN_ERR,
1845 "error: CONFIG_LBDAF not enabled");
Mingming Caofcd5df32006-06-25 05:47:50 -07001846 goto failed_mount;
1847 }
1848
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 if (EXT3_BLOCKS_PER_GROUP(sb) == 0)
1850 goto cantfind_ext3;
Eric Sandeen855565e2006-09-27 01:49:29 -07001851 sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
1852 le32_to_cpu(es->s_first_data_block) - 1)
1853 / EXT3_BLOCKS_PER_GROUP(sb)) + 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) /
1855 EXT3_DESC_PER_BLOCK(sb);
1856 sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
1857 GFP_KERNEL);
1858 if (sbi->s_group_desc == NULL) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001859 ext3_msg(sb, KERN_ERR,
1860 "error: not enough memory");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 goto failed_mount;
1862 }
1863
Pekka Enberg5df096d2009-01-07 18:07:25 -08001864 bgl_lock_init(sbi->s_blockgroup_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
1866 for (i = 0; i < db_count; i++) {
1867 block = descriptor_loc(sb, logic_sb_block, i);
1868 sbi->s_group_desc[i] = sb_bread(sb, block);
1869 if (!sbi->s_group_desc[i]) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001870 ext3_msg(sb, KERN_ERR,
1871 "error: can't read group descriptor %d", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 db_count = i;
1873 goto failed_mount2;
1874 }
1875 }
1876 if (!ext3_check_descriptors (sb)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001877 ext3_msg(sb, KERN_ERR,
1878 "error: group descriptors corrupted");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 goto failed_mount2;
1880 }
1881 sbi->s_gdb_count = db_count;
1882 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
1883 spin_lock_init(&sbi->s_next_gen_lock);
Mingming Cao0216bfc2006-06-23 02:05:41 -07001884
Peter Zijlstra833f4072007-10-16 23:25:45 -07001885 err = percpu_counter_init(&sbi->s_freeblocks_counter,
1886 ext3_count_free_blocks(sb));
1887 if (!err) {
1888 err = percpu_counter_init(&sbi->s_freeinodes_counter,
1889 ext3_count_free_inodes(sb));
1890 }
1891 if (!err) {
1892 err = percpu_counter_init(&sbi->s_dirs_counter,
1893 ext3_count_dirs(sb));
1894 }
1895 if (err) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001896 ext3_msg(sb, KERN_ERR, "error: insufficient memory");
Peter Zijlstra833f4072007-10-16 23:25:45 -07001897 goto failed_mount3;
1898 }
Mingming Cao0216bfc2006-06-23 02:05:41 -07001899
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 /* per fileystem reservation list head & lock */
1901 spin_lock_init(&sbi->s_rsv_window_lock);
1902 sbi->s_rsv_window_root = RB_ROOT;
1903 /* Add a single, static dummy reservation to the start of the
1904 * reservation window list --- it gives us a placeholder for
1905 * append-at-start-of-list which makes the allocation logic
1906 * _much_ simpler. */
1907 sbi->s_rsv_window_head.rsv_start = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
1908 sbi->s_rsv_window_head.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
1909 sbi->s_rsv_window_head.rsv_alloc_hit = 0;
1910 sbi->s_rsv_window_head.rsv_goal_size = 0;
1911 ext3_rsv_window_add(sb, &sbi->s_rsv_window_head);
1912
1913 /*
1914 * set up enough so that it can read an inode
1915 */
1916 sb->s_op = &ext3_sops;
1917 sb->s_export_op = &ext3_export_ops;
1918 sb->s_xattr = ext3_xattr_handlers;
1919#ifdef CONFIG_QUOTA
1920 sb->s_qcop = &ext3_qctl_operations;
1921 sb->dq_op = &ext3_quota_operations;
1922#endif
1923 INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
Eric Sandeenb8a052d2009-12-14 13:00:30 -06001924 mutex_init(&sbi->s_orphan_lock);
Eric Sandeen96d2a492009-12-14 13:01:05 -06001925 mutex_init(&sbi->s_resize_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
1927 sb->s_root = NULL;
1928
1929 needs_recovery = (es->s_last_orphan != 0 ||
1930 EXT3_HAS_INCOMPAT_FEATURE(sb,
1931 EXT3_FEATURE_INCOMPAT_RECOVER));
1932
1933 /*
1934 * The first inode we look at is the journal inode. Don't try
1935 * root first: it may be modified in the journal!
1936 */
1937 if (!test_opt(sb, NOLOAD) &&
1938 EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
Johann Lombardi71b96252006-01-08 01:03:20 -08001939 if (ext3_load_journal(sb, es, journal_devnum))
Mingming Cao0216bfc2006-06-23 02:05:41 -07001940 goto failed_mount3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 } else if (journal_inum) {
1942 if (ext3_create_journal(sb, es, journal_inum))
Mingming Cao0216bfc2006-06-23 02:05:41 -07001943 goto failed_mount3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 } else {
1945 if (!silent)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001946 ext3_msg(sb, KERN_ERR,
1947 "error: no journal found. "
1948 "mounting ext3 over ext2?");
Mingming Cao0216bfc2006-06-23 02:05:41 -07001949 goto failed_mount3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 }
1951
1952 /* We have now updated the journal if required, so we can
1953 * validate the data journaling mode. */
1954 switch (test_opt(sb, DATA_FLAGS)) {
1955 case 0:
1956 /* No mode set, assume a default based on the journal
1957 capabilities: ORDERED_DATA if the journal can
1958 cope, else JOURNAL_DATA */
1959 if (journal_check_available_features
1960 (sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE))
Linus Torvaldsbbae8bc2009-04-06 17:16:47 -07001961 set_opt(sbi->s_mount_opt, DEFAULT_DATA_MODE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 else
1963 set_opt(sbi->s_mount_opt, JOURNAL_DATA);
1964 break;
1965
1966 case EXT3_MOUNT_ORDERED_DATA:
1967 case EXT3_MOUNT_WRITEBACK_DATA:
1968 if (!journal_check_available_features
1969 (sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001970 ext3_msg(sb, KERN_ERR,
1971 "error: journal does not support "
1972 "requested data journaling mode");
Mingming Cao0216bfc2006-06-23 02:05:41 -07001973 goto failed_mount4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 }
1975 default:
1976 break;
1977 }
1978
1979 if (test_opt(sb, NOBH)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 if (!(test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001981 ext3_msg(sb, KERN_WARNING,
1982 "warning: ignoring nobh option - "
1983 "it is supported only with writeback mode");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 clear_opt(sbi->s_mount_opt, NOBH);
1985 }
1986 }
1987 /*
1988 * The journal_load will have done any necessary log recovery,
1989 * so we can safely mount the rest of the filesystem now.
1990 */
1991
David Howells473043d2008-02-07 00:15:36 -08001992 root = ext3_iget(sb, EXT3_ROOT_INO);
1993 if (IS_ERR(root)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01001994 ext3_msg(sb, KERN_ERR, "error: get root inode failed");
David Howells473043d2008-02-07 00:15:36 -08001995 ret = PTR_ERR(root);
Mingming Cao0216bfc2006-06-23 02:05:41 -07001996 goto failed_mount4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 }
1998 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
David Howells473043d2008-02-07 00:15:36 -08001999 iput(root);
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002000 ext3_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck");
Mingming Cao0216bfc2006-06-23 02:05:41 -07002001 goto failed_mount4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 }
David Howells473043d2008-02-07 00:15:36 -08002003 sb->s_root = d_alloc_root(root);
2004 if (!sb->s_root) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002005 ext3_msg(sb, KERN_ERR, "error: get root dentry failed");
David Howells473043d2008-02-07 00:15:36 -08002006 iput(root);
2007 ret = -ENOMEM;
2008 goto failed_mount4;
2009 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011 ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
Eric Sandeened505ee2009-12-14 12:59:18 -06002012
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS;
2014 ext3_orphan_cleanup(sb, es);
2015 EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS;
2016 if (needs_recovery)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002017 ext3_msg(sb, KERN_INFO, "recovery complete");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 ext3_mark_recovery_complete(sb, es);
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002019 ext3_msg(sb, KERN_INFO, "mounted filesystem with %s data mode",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
2021 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
2022 "writeback");
2023
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024 lock_kernel();
2025 return 0;
2026
2027cantfind_ext3:
2028 if (!silent)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002029 ext3_msg(sb, KERN_INFO,
2030 "error: can't find ext3 filesystem on dev %s.",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031 sb->s_id);
2032 goto failed_mount;
2033
Mingming Cao0216bfc2006-06-23 02:05:41 -07002034failed_mount4:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 journal_destroy(sbi->s_journal);
Mingming Cao0216bfc2006-06-23 02:05:41 -07002036failed_mount3:
2037 percpu_counter_destroy(&sbi->s_freeblocks_counter);
2038 percpu_counter_destroy(&sbi->s_freeinodes_counter);
2039 percpu_counter_destroy(&sbi->s_dirs_counter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040failed_mount2:
2041 for (i = 0; i < db_count; i++)
2042 brelse(sbi->s_group_desc[i]);
2043 kfree(sbi->s_group_desc);
2044failed_mount:
2045#ifdef CONFIG_QUOTA
2046 for (i = 0; i < MAXQUOTAS; i++)
2047 kfree(sbi->s_qf_names[i]);
2048#endif
2049 ext3_blkdev_remove(sbi);
2050 brelse(bh);
2051out_fail:
2052 sb->s_fs_info = NULL;
Manish Katiyarde5ce032009-05-17 23:52:47 -04002053 kfree(sbi->s_blockgroup_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 kfree(sbi);
2055 lock_kernel();
David Howells473043d2008-02-07 00:15:36 -08002056 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057}
2058
2059/*
2060 * Setup any per-fs journal parameters now. We'll do this both on
2061 * initial mount, once the journal has been initialised but before we've
Mingming Caoae6ddcc2006-09-27 01:49:27 -07002062 * done any recovery; and again on any subsequent remount.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063 */
2064static void ext3_init_journal_params(struct super_block *sb, journal_t *journal)
2065{
2066 struct ext3_sb_info *sbi = EXT3_SB(sb);
2067
2068 if (sbi->s_commit_interval)
2069 journal->j_commit_interval = sbi->s_commit_interval;
2070 /* We could also set up an ext3-specific default for the commit
2071 * interval here, but for now we'll just fall back to the jbd
2072 * default. */
2073
2074 spin_lock(&journal->j_state_lock);
2075 if (test_opt(sb, BARRIER))
2076 journal->j_flags |= JFS_BARRIER;
2077 else
2078 journal->j_flags &= ~JFS_BARRIER;
Hidehiro Kawai0e4fb5e2008-10-18 20:27:57 -07002079 if (test_opt(sb, DATA_ERR_ABORT))
2080 journal->j_flags |= JFS_ABORT_ON_SYNCDATA_ERR;
2081 else
2082 journal->j_flags &= ~JFS_ABORT_ON_SYNCDATA_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 spin_unlock(&journal->j_state_lock);
2084}
2085
Eric Sandeeneee194e2006-09-27 01:49:30 -07002086static journal_t *ext3_get_journal(struct super_block *sb,
2087 unsigned int journal_inum)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088{
2089 struct inode *journal_inode;
2090 journal_t *journal;
2091
2092 /* First, test for the existence of a valid inode on disk. Bad
2093 * things happen if we iget() an unused inode, as the subsequent
2094 * iput() will try to delete it. */
2095
David Howells473043d2008-02-07 00:15:36 -08002096 journal_inode = ext3_iget(sb, journal_inum);
2097 if (IS_ERR(journal_inode)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002098 ext3_msg(sb, KERN_ERR, "error: no journal found");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 return NULL;
2100 }
2101 if (!journal_inode->i_nlink) {
2102 make_bad_inode(journal_inode);
2103 iput(journal_inode);
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002104 ext3_msg(sb, KERN_ERR, "error: journal inode is deleted");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105 return NULL;
2106 }
2107
2108 jbd_debug(2, "Journal inode found at %p: %Ld bytes\n",
2109 journal_inode, journal_inode->i_size);
David Howells473043d2008-02-07 00:15:36 -08002110 if (!S_ISREG(journal_inode->i_mode)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002111 ext3_msg(sb, KERN_ERR, "error: invalid journal inode");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 iput(journal_inode);
2113 return NULL;
2114 }
2115
2116 journal = journal_init_inode(journal_inode);
2117 if (!journal) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002118 ext3_msg(sb, KERN_ERR, "error: could not load journal inode");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 iput(journal_inode);
2120 return NULL;
2121 }
2122 journal->j_private = sb;
2123 ext3_init_journal_params(sb, journal);
2124 return journal;
2125}
2126
2127static journal_t *ext3_get_dev_journal(struct super_block *sb,
2128 dev_t j_dev)
2129{
2130 struct buffer_head * bh;
2131 journal_t *journal;
Mingming Cao43d23f92006-06-25 05:48:07 -07002132 ext3_fsblk_t start;
Mingming Cao1c2bf372006-06-25 05:48:06 -07002133 ext3_fsblk_t len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134 int hblock, blocksize;
Mingming Cao43d23f92006-06-25 05:48:07 -07002135 ext3_fsblk_t sb_block;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136 unsigned long offset;
2137 struct ext3_super_block * es;
2138 struct block_device *bdev;
2139
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002140 bdev = ext3_blkdev_get(j_dev, sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 if (bdev == NULL)
2142 return NULL;
2143
2144 if (bd_claim(bdev, sb)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002145 ext3_msg(sb, KERN_ERR,
2146 "error: failed to claim external journal device");
Al Viro9a1c3542008-02-22 20:40:24 -05002147 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 return NULL;
2149 }
2150
2151 blocksize = sb->s_blocksize;
Martin K. Petersene1defc42009-05-22 17:17:49 -04002152 hblock = bdev_logical_block_size(bdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153 if (blocksize < hblock) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002154 ext3_msg(sb, KERN_ERR,
2155 "error: blocksize too small for journal device");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 goto out_bdev;
2157 }
2158
2159 sb_block = EXT3_MIN_BLOCK_SIZE / blocksize;
2160 offset = EXT3_MIN_BLOCK_SIZE % blocksize;
2161 set_blocksize(bdev, blocksize);
2162 if (!(bh = __bread(bdev, sb_block, blocksize))) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002163 ext3_msg(sb, KERN_ERR, "error: couldn't read superblock of "
2164 "external journal");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165 goto out_bdev;
2166 }
2167
2168 es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);
2169 if ((le16_to_cpu(es->s_magic) != EXT3_SUPER_MAGIC) ||
2170 !(le32_to_cpu(es->s_feature_incompat) &
2171 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002172 ext3_msg(sb, KERN_ERR, "error: external journal has "
2173 "bad superblock");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 brelse(bh);
2175 goto out_bdev;
2176 }
2177
2178 if (memcmp(EXT3_SB(sb)->s_es->s_journal_uuid, es->s_uuid, 16)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002179 ext3_msg(sb, KERN_ERR, "error: journal UUID does not match");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180 brelse(bh);
2181 goto out_bdev;
2182 }
2183
2184 len = le32_to_cpu(es->s_blocks_count);
2185 start = sb_block + 1;
2186 brelse(bh); /* we're done with the superblock */
2187
2188 journal = journal_init_dev(bdev, sb->s_bdev,
2189 start, len, blocksize);
2190 if (!journal) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002191 ext3_msg(sb, KERN_ERR,
2192 "error: failed to create device journal");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 goto out_bdev;
2194 }
2195 journal->j_private = sb;
2196 ll_rw_block(READ, 1, &journal->j_sb_buffer);
2197 wait_on_buffer(journal->j_sb_buffer);
2198 if (!buffer_uptodate(journal->j_sb_buffer)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002199 ext3_msg(sb, KERN_ERR, "I/O error on journal device");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200 goto out_journal;
2201 }
2202 if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002203 ext3_msg(sb, KERN_ERR,
2204 "error: external journal has more than one "
2205 "user (unsupported) - %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 be32_to_cpu(journal->j_superblock->s_nr_users));
2207 goto out_journal;
2208 }
2209 EXT3_SB(sb)->journal_bdev = bdev;
2210 ext3_init_journal_params(sb, journal);
2211 return journal;
2212out_journal:
2213 journal_destroy(journal);
2214out_bdev:
2215 ext3_blkdev_put(bdev);
2216 return NULL;
2217}
2218
Johann Lombardi71b96252006-01-08 01:03:20 -08002219static int ext3_load_journal(struct super_block *sb,
2220 struct ext3_super_block *es,
2221 unsigned long journal_devnum)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222{
2223 journal_t *journal;
Eric Sandeeneee194e2006-09-27 01:49:30 -07002224 unsigned int journal_inum = le32_to_cpu(es->s_journal_inum);
Johann Lombardi71b96252006-01-08 01:03:20 -08002225 dev_t journal_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 int err = 0;
2227 int really_read_only;
2228
Johann Lombardi71b96252006-01-08 01:03:20 -08002229 if (journal_devnum &&
2230 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002231 ext3_msg(sb, KERN_INFO, "external journal device major/minor "
2232 "numbers have changed");
Johann Lombardi71b96252006-01-08 01:03:20 -08002233 journal_dev = new_decode_dev(journal_devnum);
2234 } else
2235 journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
2236
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 really_read_only = bdev_read_only(sb->s_bdev);
2238
2239 /*
2240 * Are we loading a blank journal or performing recovery after a
2241 * crash? For recovery, we need to check in advance whether we
2242 * can get read-write access to the device.
2243 */
2244
2245 if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER)) {
2246 if (sb->s_flags & MS_RDONLY) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002247 ext3_msg(sb, KERN_INFO,
2248 "recovery required on readonly filesystem");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249 if (really_read_only) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002250 ext3_msg(sb, KERN_ERR, "error: write access "
2251 "unavailable, cannot proceed");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 return -EROFS;
2253 }
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002254 ext3_msg(sb, KERN_INFO,
2255 "write access will be enabled during recovery");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256 }
2257 }
2258
2259 if (journal_inum && journal_dev) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002260 ext3_msg(sb, KERN_ERR, "error: filesystem has both journal "
2261 "and inode journals");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 return -EINVAL;
2263 }
2264
2265 if (journal_inum) {
2266 if (!(journal = ext3_get_journal(sb, journal_inum)))
2267 return -EINVAL;
2268 } else {
2269 if (!(journal = ext3_get_dev_journal(sb, journal_dev)))
2270 return -EINVAL;
2271 }
2272
2273 if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
2274 err = journal_update_format(journal);
2275 if (err) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002276 ext3_msg(sb, KERN_ERR, "error updating journal");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277 journal_destroy(journal);
2278 return err;
2279 }
2280 }
2281
2282 if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER))
2283 err = journal_wipe(journal, !really_read_only);
2284 if (!err)
2285 err = journal_load(journal);
2286
2287 if (err) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002288 ext3_msg(sb, KERN_ERR, "error loading journal");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 journal_destroy(journal);
2290 return err;
2291 }
2292
2293 EXT3_SB(sb)->s_journal = journal;
2294 ext3_clear_journal_err(sb, es);
Johann Lombardi71b96252006-01-08 01:03:20 -08002295
2296 if (journal_devnum &&
2297 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
2298 es->s_journal_dev = cpu_to_le32(journal_devnum);
Johann Lombardi71b96252006-01-08 01:03:20 -08002299
2300 /* Make sure we flush the recovery flag to disk. */
2301 ext3_commit_super(sb, es, 1);
2302 }
2303
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304 return 0;
2305}
2306
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002307static int ext3_create_journal(struct super_block *sb,
2308 struct ext3_super_block *es,
Eric Sandeeneee194e2006-09-27 01:49:30 -07002309 unsigned int journal_inum)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310{
2311 journal_t *journal;
Borislav Petkov952d9de2007-07-15 23:41:45 -07002312 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313
2314 if (sb->s_flags & MS_RDONLY) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002315 ext3_msg(sb, KERN_ERR,
2316 "error: readonly filesystem when trying to "
2317 "create journal");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 return -EROFS;
2319 }
2320
Borislav Petkov952d9de2007-07-15 23:41:45 -07002321 journal = ext3_get_journal(sb, journal_inum);
2322 if (!journal)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 return -EINVAL;
2324
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002325 ext3_msg(sb, KERN_INFO, "creating new journal on inode %u",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 journal_inum);
2327
Borislav Petkov952d9de2007-07-15 23:41:45 -07002328 err = journal_create(journal);
2329 if (err) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002330 ext3_msg(sb, KERN_ERR, "error creating journal");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 journal_destroy(journal);
2332 return -EIO;
2333 }
2334
2335 EXT3_SB(sb)->s_journal = journal;
2336
2337 ext3_update_dynamic_rev(sb);
2338 EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
2339 EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL);
2340
2341 es->s_journal_inum = cpu_to_le32(journal_inum);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
2343 /* Make sure we flush the recovery flag to disk. */
2344 ext3_commit_super(sb, es, 1);
2345
2346 return 0;
2347}
2348
Takashi Satoc4be0c12009-01-09 16:40:58 -08002349static int ext3_commit_super(struct super_block *sb,
2350 struct ext3_super_block *es,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351 int sync)
2352{
2353 struct buffer_head *sbh = EXT3_SB(sb)->s_sbh;
Takashi Satoc4be0c12009-01-09 16:40:58 -08002354 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355
2356 if (!sbh)
Takashi Satoc4be0c12009-01-09 16:40:58 -08002357 return error;
Theodore Ts'o96ec2e02009-09-16 11:21:13 -04002358 /*
2359 * If the file system is mounted read-only, don't update the
2360 * superblock write time. This avoids updating the superblock
2361 * write time when we are mounting the root file system
2362 * read/only but we need to replay the journal; at that point,
2363 * for people who are east of GMT and who make their clock
2364 * tick in localtime for Windows bug-for-bug compatibility,
2365 * the clock is set in the future, and this will cause e2fsck
2366 * to complain and force a full file system check.
2367 */
2368 if (!(sb->s_flags & MS_RDONLY))
2369 es->s_wtime = cpu_to_le32(get_seconds());
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb));
2371 es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
2372 BUFFER_TRACE(sbh, "marking dirty");
2373 mark_buffer_dirty(sbh);
2374 if (sync)
Takashi Satoc4be0c12009-01-09 16:40:58 -08002375 error = sync_dirty_buffer(sbh);
2376 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377}
2378
2379
2380/*
2381 * Have we just finished recovery? If so, and if we are mounting (or
2382 * remounting) the filesystem readonly, then we will end up with a
2383 * consistent fs on disk. Record that fact.
2384 */
2385static void ext3_mark_recovery_complete(struct super_block * sb,
2386 struct ext3_super_block * es)
2387{
2388 journal_t *journal = EXT3_SB(sb)->s_journal;
2389
2390 journal_lock_updates(journal);
Hidehiro Kawai2d7c8202008-10-22 14:15:01 -07002391 if (journal_flush(journal) < 0)
2392 goto out;
2393
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394 if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
2395 sb->s_flags & MS_RDONLY) {
2396 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 ext3_commit_super(sb, es, 1);
2398 }
Hidehiro Kawai2d7c8202008-10-22 14:15:01 -07002399
2400out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 journal_unlock_updates(journal);
2402}
2403
2404/*
2405 * If we are mounting (or read-write remounting) a filesystem whose journal
2406 * has recorded an error from a previous lifetime, move that error to the
2407 * main filesystem now.
2408 */
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002409static void ext3_clear_journal_err(struct super_block *sb,
2410 struct ext3_super_block *es)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411{
2412 journal_t *journal;
2413 int j_errno;
2414 const char *errstr;
2415
2416 journal = EXT3_SB(sb)->s_journal;
2417
2418 /*
2419 * Now check for any error status which may have been recorded in the
2420 * journal by a prior ext3_error() or ext3_abort()
2421 */
2422
2423 j_errno = journal_errno(journal);
2424 if (j_errno) {
2425 char nbuf[16];
2426
2427 errstr = ext3_decode_error(sb, j_errno, nbuf);
Harvey Harrisone05b6b52008-04-28 02:16:15 -07002428 ext3_warning(sb, __func__, "Filesystem error recorded "
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 "from previous mount: %s", errstr);
Harvey Harrisone05b6b52008-04-28 02:16:15 -07002430 ext3_warning(sb, __func__, "Marking fs in need of "
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431 "filesystem check.");
2432
2433 EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
2434 es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
2435 ext3_commit_super (sb, es, 1);
2436
2437 journal_clear_err(journal);
2438 }
2439}
2440
2441/*
2442 * Force the running and committing transactions to commit,
2443 * and wait on the commit.
2444 */
2445int ext3_force_commit(struct super_block *sb)
2446{
2447 journal_t *journal;
2448 int ret;
2449
2450 if (sb->s_flags & MS_RDONLY)
2451 return 0;
2452
2453 journal = EXT3_SB(sb)->s_journal;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 ret = ext3_journal_force_commit(journal);
2455 return ret;
2456}
2457
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458static int ext3_sync_fs(struct super_block *sb, int wait)
2459{
Jan Kara02ac5972009-02-11 13:04:26 -08002460 tid_t target;
Arthur Jonesc87591b2008-11-06 12:53:35 -08002461
Jan Kara02ac5972009-02-11 13:04:26 -08002462 if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
2463 if (wait)
2464 log_wait_commit(EXT3_SB(sb)->s_journal, target);
2465 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466 return 0;
2467}
2468
2469/*
2470 * LVM calls this function before a (read-only) snapshot is created. This
2471 * gives us a chance to flush the journal completely and mark the fs clean.
2472 */
Takashi Satoc4be0c12009-01-09 16:40:58 -08002473static int ext3_freeze(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474{
Takashi Satoc4be0c12009-01-09 16:40:58 -08002475 int error = 0;
2476 journal_t *journal;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477
2478 if (!(sb->s_flags & MS_RDONLY)) {
Takashi Satoc4be0c12009-01-09 16:40:58 -08002479 journal = EXT3_SB(sb)->s_journal;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480
2481 /* Now we set up the journal barrier. */
2482 journal_lock_updates(journal);
Hidehiro Kawai2d7c8202008-10-22 14:15:01 -07002483
2484 /*
2485 * We don't want to clear needs_recovery flag when we failed
2486 * to flush the journal.
2487 */
Takashi Satoc4be0c12009-01-09 16:40:58 -08002488 error = journal_flush(journal);
2489 if (error < 0)
2490 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491
2492 /* Journal blocked and flushed, clear needs_recovery flag. */
2493 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
Takashi Satoc4be0c12009-01-09 16:40:58 -08002494 error = ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
2495 if (error)
2496 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 }
Takashi Satoc4be0c12009-01-09 16:40:58 -08002498 return 0;
2499
2500out:
2501 journal_unlock_updates(journal);
2502 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503}
2504
2505/*
2506 * Called by LVM after the snapshot is done. We need to reset the RECOVER
2507 * flag here, even though the filesystem is not technically dirty yet.
2508 */
Takashi Satoc4be0c12009-01-09 16:40:58 -08002509static int ext3_unfreeze(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002510{
2511 if (!(sb->s_flags & MS_RDONLY)) {
2512 lock_super(sb);
2513 /* Reser the needs_recovery flag before the fs is unlocked. */
2514 EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
2515 ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
2516 unlock_super(sb);
2517 journal_unlock_updates(EXT3_SB(sb)->s_journal);
2518 }
Takashi Satoc4be0c12009-01-09 16:40:58 -08002519 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520}
2521
2522static int ext3_remount (struct super_block * sb, int * flags, char * data)
2523{
2524 struct ext3_super_block * es;
2525 struct ext3_sb_info *sbi = EXT3_SB(sb);
Mingming Cao43d23f92006-06-25 05:48:07 -07002526 ext3_fsblk_t n_blocks_count = 0;
Jan Kara08c6a962005-07-12 13:58:28 -07002527 unsigned long old_sb_flags;
2528 struct ext3_mount_options old_opts;
2529 int err;
2530#ifdef CONFIG_QUOTA
2531 int i;
2532#endif
2533
Alessio Igor Bogani337eb002009-05-12 15:10:54 +02002534 lock_kernel();
2535
Jan Kara08c6a962005-07-12 13:58:28 -07002536 /* Store the original options */
Al Virobbd68512009-05-06 10:43:07 -04002537 lock_super(sb);
Jan Kara08c6a962005-07-12 13:58:28 -07002538 old_sb_flags = sb->s_flags;
2539 old_opts.s_mount_opt = sbi->s_mount_opt;
2540 old_opts.s_resuid = sbi->s_resuid;
2541 old_opts.s_resgid = sbi->s_resgid;
2542 old_opts.s_commit_interval = sbi->s_commit_interval;
2543#ifdef CONFIG_QUOTA
2544 old_opts.s_jquota_fmt = sbi->s_jquota_fmt;
2545 for (i = 0; i < MAXQUOTAS; i++)
2546 old_opts.s_qf_names[i] = sbi->s_qf_names[i];
2547#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
2549 /*
2550 * Allow the "check" option to be passed as a remount option.
2551 */
Johann Lombardi71b96252006-01-08 01:03:20 -08002552 if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) {
Jan Kara08c6a962005-07-12 13:58:28 -07002553 err = -EINVAL;
2554 goto restore_opts;
2555 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556
Dmitry Monakhove3c96432010-02-02 16:05:51 +03002557 if (test_opt(sb, ABORT))
Harvey Harrisone05b6b52008-04-28 02:16:15 -07002558 ext3_abort(sb, __func__, "Abort forced by user");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559
2560 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
Dmitry Monakhove3c96432010-02-02 16:05:51 +03002561 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562
2563 es = sbi->s_es;
2564
2565 ext3_init_journal_params(sb, sbi->s_journal);
2566
2567 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
2568 n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
Dmitry Monakhove3c96432010-02-02 16:05:51 +03002569 if (test_opt(sb, ABORT)) {
Jan Kara08c6a962005-07-12 13:58:28 -07002570 err = -EROFS;
2571 goto restore_opts;
2572 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
2574 if (*flags & MS_RDONLY) {
2575 /*
2576 * First of all, the unconditional stuff we have to do
2577 * to disable replay of the journal when we next remount
2578 */
2579 sb->s_flags |= MS_RDONLY;
2580
2581 /*
2582 * OK, test if we are remounting a valid rw partition
2583 * readonly, and if so set the rdonly flag and then
2584 * mark the partition as valid again.
2585 */
2586 if (!(es->s_state & cpu_to_le16(EXT3_VALID_FS)) &&
2587 (sbi->s_mount_state & EXT3_VALID_FS))
2588 es->s_state = cpu_to_le16(sbi->s_mount_state);
2589
2590 ext3_mark_recovery_complete(sb, es);
2591 } else {
2592 __le32 ret;
2593 if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb,
2594 ~EXT3_FEATURE_RO_COMPAT_SUPP))) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002595 ext3_msg(sb, KERN_WARNING,
2596 "warning: couldn't remount RDWR "
2597 "because of unsupported optional "
2598 "features (%x)", le32_to_cpu(ret));
Jan Kara08c6a962005-07-12 13:58:28 -07002599 err = -EROFS;
2600 goto restore_opts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601 }
Eric Sandeenea9a05a2007-02-10 01:46:07 -08002602
2603 /*
2604 * If we have an unprocessed orphan list hanging
2605 * around from a previously readonly bdev mount,
2606 * require a full umount/remount for now.
2607 */
2608 if (es->s_last_orphan) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002609 ext3_msg(sb, KERN_WARNING, "warning: couldn't "
Eric Sandeenea9a05a2007-02-10 01:46:07 -08002610 "remount RDWR because of unprocessed "
2611 "orphan inode list. Please "
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002612 "umount/remount instead.");
Eric Sandeenea9a05a2007-02-10 01:46:07 -08002613 err = -EINVAL;
2614 goto restore_opts;
2615 }
2616
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617 /*
2618 * Mounting a RDONLY partition read-write, so reread
2619 * and store the current valid flag. (It may have
2620 * been changed by e2fsck since we originally mounted
2621 * the partition.)
2622 */
2623 ext3_clear_journal_err(sb, es);
2624 sbi->s_mount_state = le16_to_cpu(es->s_state);
Dave Kleikampa4e4de32006-09-27 01:49:36 -07002625 if ((err = ext3_group_extend(sb, es, n_blocks_count)))
Jan Kara08c6a962005-07-12 13:58:28 -07002626 goto restore_opts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 if (!ext3_setup_super (sb, es, 0))
2628 sb->s_flags &= ~MS_RDONLY;
2629 }
2630 }
Jan Kara08c6a962005-07-12 13:58:28 -07002631#ifdef CONFIG_QUOTA
2632 /* Release old quota file names */
2633 for (i = 0; i < MAXQUOTAS; i++)
2634 if (old_opts.s_qf_names[i] &&
2635 old_opts.s_qf_names[i] != sbi->s_qf_names[i])
2636 kfree(old_opts.s_qf_names[i]);
2637#endif
Al Virobbd68512009-05-06 10:43:07 -04002638 unlock_super(sb);
Alessio Igor Bogani337eb002009-05-12 15:10:54 +02002639 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 return 0;
Jan Kara08c6a962005-07-12 13:58:28 -07002641restore_opts:
2642 sb->s_flags = old_sb_flags;
2643 sbi->s_mount_opt = old_opts.s_mount_opt;
2644 sbi->s_resuid = old_opts.s_resuid;
2645 sbi->s_resgid = old_opts.s_resgid;
2646 sbi->s_commit_interval = old_opts.s_commit_interval;
2647#ifdef CONFIG_QUOTA
2648 sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
2649 for (i = 0; i < MAXQUOTAS; i++) {
2650 if (sbi->s_qf_names[i] &&
2651 old_opts.s_qf_names[i] != sbi->s_qf_names[i])
2652 kfree(sbi->s_qf_names[i]);
2653 sbi->s_qf_names[i] = old_opts.s_qf_names[i];
2654 }
2655#endif
Al Virobbd68512009-05-06 10:43:07 -04002656 unlock_super(sb);
Alessio Igor Bogani337eb002009-05-12 15:10:54 +02002657 unlock_kernel();
Jan Kara08c6a962005-07-12 13:58:28 -07002658 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659}
2660
David Howells726c3342006-06-23 02:02:58 -07002661static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662{
David Howells726c3342006-06-23 02:02:58 -07002663 struct super_block *sb = dentry->d_sb;
Alex Tomas09fe3162006-03-24 03:16:16 -08002664 struct ext3_sb_info *sbi = EXT3_SB(sb);
2665 struct ext3_super_block *es = sbi->s_es;
Pekka Enberg50ee0a32006-12-06 20:35:28 -08002666 u64 fsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
Badari Pulavartya71ce8c2007-07-15 23:41:59 -07002668 if (test_opt(sb, MINIX_DF)) {
2669 sbi->s_overhead_last = 0;
2670 } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
2671 unsigned long ngroups = sbi->s_groups_count, i;
2672 ext3_fsblk_t overhead = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 smp_rmb();
2674
2675 /*
Badari Pulavartya71ce8c2007-07-15 23:41:59 -07002676 * Compute the overhead (FS structures). This is constant
2677 * for a given filesystem unless the number of block groups
2678 * changes so we cache the previous value until it does.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 */
2680
2681 /*
2682 * All of the blocks before first_data_block are
2683 * overhead
2684 */
2685 overhead = le32_to_cpu(es->s_first_data_block);
2686
2687 /*
2688 * Add the overhead attributed to the superblock and
2689 * block group descriptors. If the sparse superblocks
2690 * feature is turned on, then not all groups have this.
2691 */
2692 for (i = 0; i < ngroups; i++) {
2693 overhead += ext3_bg_has_super(sb, i) +
2694 ext3_bg_num_gdb(sb, i);
2695 cond_resched();
2696 }
2697
2698 /*
2699 * Every block group has an inode bitmap, a block
2700 * bitmap, and an inode table.
2701 */
Badari Pulavartya71ce8c2007-07-15 23:41:59 -07002702 overhead += ngroups * (2 + sbi->s_itb_per_group);
2703 sbi->s_overhead_last = overhead;
2704 smp_wmb();
2705 sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706 }
2707
2708 buf->f_type = EXT3_SUPER_MAGIC;
2709 buf->f_bsize = sb->s_blocksize;
Badari Pulavartya71ce8c2007-07-15 23:41:59 -07002710 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
Peter Zijlstra52d9f3b2007-10-16 23:25:44 -07002711 buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
2713 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
2714 buf->f_bavail = 0;
2715 buf->f_files = le32_to_cpu(es->s_inodes_count);
Peter Zijlstra52d9f3b2007-10-16 23:25:44 -07002716 buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717 buf->f_namelen = EXT3_NAME_LEN;
Pekka Enberg50ee0a32006-12-06 20:35:28 -08002718 fsid = le64_to_cpup((void *)es->s_uuid) ^
2719 le64_to_cpup((void *)es->s_uuid + sizeof(u64));
2720 buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL;
2721 buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722 return 0;
2723}
2724
2725/* Helper function for writing quotas on sync - we need to start transaction before quota file
2726 * is locked for write. Otherwise the are possible deadlocks:
2727 * Process 1 Process 2
2728 * ext3_create() quota_sync()
2729 * journal_start() write_dquot()
Jan Kara81a05222009-01-26 16:58:01 +01002730 * vfs_dq_init() down(dqio_mutex)
Ingo Molnard3be9152006-03-23 03:00:29 -08002731 * down(dqio_mutex) journal_start()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732 *
2733 */
2734
2735#ifdef CONFIG_QUOTA
2736
2737static inline struct inode *dquot_to_inode(struct dquot *dquot)
2738{
2739 return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
2740}
2741
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742static int ext3_write_dquot(struct dquot *dquot)
2743{
2744 int ret, err;
2745 handle_t *handle;
2746 struct inode *inode;
2747
2748 inode = dquot_to_inode(dquot);
2749 handle = ext3_journal_start(inode,
Jan Kara1f545872005-06-23 22:01:04 -07002750 EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751 if (IS_ERR(handle))
2752 return PTR_ERR(handle);
2753 ret = dquot_commit(dquot);
2754 err = ext3_journal_stop(handle);
2755 if (!ret)
2756 ret = err;
2757 return ret;
2758}
2759
2760static int ext3_acquire_dquot(struct dquot *dquot)
2761{
2762 int ret, err;
2763 handle_t *handle;
2764
2765 handle = ext3_journal_start(dquot_to_inode(dquot),
Jan Kara1f545872005-06-23 22:01:04 -07002766 EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 if (IS_ERR(handle))
2768 return PTR_ERR(handle);
2769 ret = dquot_acquire(dquot);
2770 err = ext3_journal_stop(handle);
2771 if (!ret)
2772 ret = err;
2773 return ret;
2774}
2775
2776static int ext3_release_dquot(struct dquot *dquot)
2777{
2778 int ret, err;
2779 handle_t *handle;
2780
2781 handle = ext3_journal_start(dquot_to_inode(dquot),
Jan Kara1f545872005-06-23 22:01:04 -07002782 EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
Jan Kara9c3013e2007-09-11 15:23:29 -07002783 if (IS_ERR(handle)) {
2784 /* Release dquot anyway to avoid endless cycle in dqput() */
2785 dquot_release(dquot);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786 return PTR_ERR(handle);
Jan Kara9c3013e2007-09-11 15:23:29 -07002787 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788 ret = dquot_release(dquot);
2789 err = ext3_journal_stop(handle);
2790 if (!ret)
2791 ret = err;
2792 return ret;
2793}
2794
2795static int ext3_mark_dquot_dirty(struct dquot *dquot)
2796{
Jan Kara99aeaf62008-07-25 01:46:17 -07002797 /* Are we journaling quotas? */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798 if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
2799 EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
2800 dquot_mark_dquot_dirty(dquot);
2801 return ext3_write_dquot(dquot);
2802 } else {
2803 return dquot_mark_dquot_dirty(dquot);
2804 }
2805}
2806
2807static int ext3_write_info(struct super_block *sb, int type)
2808{
2809 int ret, err;
2810 handle_t *handle;
2811
2812 /* Data block + inode block */
2813 handle = ext3_journal_start(sb->s_root->d_inode, 2);
2814 if (IS_ERR(handle))
2815 return PTR_ERR(handle);
2816 ret = dquot_commit_info(sb, type);
2817 err = ext3_journal_stop(handle);
2818 if (!ret)
2819 ret = err;
2820 return ret;
2821}
2822
2823/*
2824 * Turn on quotas during mount time - we need to find
2825 * the quota file and such...
2826 */
2827static int ext3_quota_on_mount(struct super_block *sb, int type)
2828{
Christoph Hellwig84de8562005-06-23 00:09:16 -07002829 return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
2830 EXT3_SB(sb)->s_jquota_fmt, type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831}
2832
2833/*
2834 * Standard function to be called on quota_on
2835 */
2836static int ext3_quota_on(struct super_block *sb, int type, int format_id,
Al Viro82646132008-08-02 00:57:06 -04002837 char *name, int remount)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838{
2839 int err;
Al Viro82646132008-08-02 00:57:06 -04002840 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841
Jan Kara1f545872005-06-23 22:01:04 -07002842 if (!test_opt(sb, QUOTA))
2843 return -EINVAL;
Al Viro82646132008-08-02 00:57:06 -04002844 /* When remounting, no checks are needed and in fact, name is NULL */
Jan Kara9cfe7b92008-07-25 01:46:16 -07002845 if (remount)
Al Viro82646132008-08-02 00:57:06 -04002846 return vfs_quota_on(sb, type, format_id, name, remount);
Jan Kara9cfe7b92008-07-25 01:46:16 -07002847
Al Viro82646132008-08-02 00:57:06 -04002848 err = kern_path(name, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 if (err)
2850 return err;
Jan Kara9cfe7b92008-07-25 01:46:16 -07002851
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 /* Quotafile not on the same filesystem? */
Al Viro82646132008-08-02 00:57:06 -04002853 if (path.mnt->mnt_sb != sb) {
2854 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 return -EXDEV;
2856 }
Jan Kara9cfe7b92008-07-25 01:46:16 -07002857 /* Journaling quota? */
2858 if (EXT3_SB(sb)->s_qf_names[type]) {
2859 /* Quotafile not of fs root? */
Al Viro82646132008-08-02 00:57:06 -04002860 if (path.dentry->d_parent != sb->s_root)
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002861 ext3_msg(sb, KERN_WARNING,
2862 "warning: Quota file not on filesystem root. "
2863 "Journaled quota will not work.");
Jan Kara9cfe7b92008-07-25 01:46:16 -07002864 }
2865
2866 /*
2867 * When we journal data on quota file, we have to flush journal to see
2868 * all updates to the file when we bypass pagecache...
2869 */
Al Viro82646132008-08-02 00:57:06 -04002870 if (ext3_should_journal_data(path.dentry->d_inode)) {
Jan Kara9cfe7b92008-07-25 01:46:16 -07002871 /*
2872 * We don't need to lock updates but journal_flush() could
2873 * otherwise be livelocked...
2874 */
2875 journal_lock_updates(EXT3_SB(sb)->s_journal);
Hidehiro Kawai2d7c8202008-10-22 14:15:01 -07002876 err = journal_flush(EXT3_SB(sb)->s_journal);
Jan Kara9cfe7b92008-07-25 01:46:16 -07002877 journal_unlock_updates(EXT3_SB(sb)->s_journal);
Hidehiro Kawai2d7c8202008-10-22 14:15:01 -07002878 if (err) {
Linus Torvalds12e1ec92008-10-23 11:48:56 -07002879 path_put(&path);
Hidehiro Kawai2d7c8202008-10-22 14:15:01 -07002880 return err;
2881 }
Jan Kara9cfe7b92008-07-25 01:46:16 -07002882 }
2883
Al Viro82646132008-08-02 00:57:06 -04002884 err = vfs_quota_on_path(sb, type, format_id, &path);
2885 path_put(&path);
Al Viro77e69da2008-08-01 04:29:18 -04002886 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887}
2888
2889/* Read data from quotafile - avoid pagecache and such because we cannot afford
2890 * acquiring the locks... As quota files are never truncated and quota code
2891 * itself serializes the operations (and noone else should touch the files)
2892 * we don't have to be afraid of races */
2893static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
2894 size_t len, loff_t off)
2895{
2896 struct inode *inode = sb_dqopt(sb)->files[type];
2897 sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
2898 int err = 0;
2899 int offset = off & (sb->s_blocksize - 1);
2900 int tocopy;
2901 size_t toread;
2902 struct buffer_head *bh;
2903 loff_t i_size = i_size_read(inode);
2904
2905 if (off > i_size)
2906 return 0;
2907 if (off+len > i_size)
2908 len = i_size-off;
2909 toread = len;
2910 while (toread > 0) {
2911 tocopy = sb->s_blocksize - offset < toread ?
2912 sb->s_blocksize - offset : toread;
2913 bh = ext3_bread(NULL, inode, blk, 0, &err);
2914 if (err)
2915 return err;
2916 if (!bh) /* A hole? */
2917 memset(data, 0, tocopy);
2918 else
2919 memcpy(data, bh->b_data+offset, tocopy);
2920 brelse(bh);
2921 offset = 0;
2922 toread -= tocopy;
2923 data += tocopy;
2924 blk++;
2925 }
2926 return len;
2927}
2928
2929/* Write to quotafile (we know the transaction is already started and has
2930 * enough credits) */
2931static ssize_t ext3_quota_write(struct super_block *sb, int type,
2932 const char *data, size_t len, loff_t off)
2933{
2934 struct inode *inode = sb_dqopt(sb)->files[type];
2935 sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
2936 int err = 0;
2937 int offset = off & (sb->s_blocksize - 1);
2938 int tocopy;
2939 int journal_quota = EXT3_SB(sb)->s_qf_names[type] != NULL;
2940 size_t towrite = len;
2941 struct buffer_head *bh;
2942 handle_t *handle = journal_current_handle();
2943
Jan Kara9c3013e2007-09-11 15:23:29 -07002944 if (!handle) {
Alexey Fisher4cf46b62009-11-22 20:38:55 +01002945 ext3_msg(sb, KERN_WARNING,
2946 "warning: quota write (off=%llu, len=%llu)"
2947 " cancelled because transaction is not started.",
Jan Kara9c3013e2007-09-11 15:23:29 -07002948 (unsigned long long)off, (unsigned long long)len);
2949 return -EIO;
2950 }
Arjan van de Ven5c81a412006-07-03 00:25:20 -07002951 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 while (towrite > 0) {
2953 tocopy = sb->s_blocksize - offset < towrite ?
2954 sb->s_blocksize - offset : towrite;
2955 bh = ext3_bread(handle, inode, blk, 1, &err);
2956 if (!bh)
2957 goto out;
2958 if (journal_quota) {
2959 err = ext3_journal_get_write_access(handle, bh);
2960 if (err) {
2961 brelse(bh);
2962 goto out;
2963 }
2964 }
2965 lock_buffer(bh);
2966 memcpy(bh->b_data+offset, data, tocopy);
2967 flush_dcache_page(bh->b_page);
2968 unlock_buffer(bh);
2969 if (journal_quota)
2970 err = ext3_journal_dirty_metadata(handle, bh);
2971 else {
2972 /* Always do at least ordered writes for quotas */
2973 err = ext3_journal_dirty_data(handle, bh);
2974 mark_buffer_dirty(bh);
2975 }
2976 brelse(bh);
2977 if (err)
2978 goto out;
2979 offset = 0;
2980 towrite -= tocopy;
2981 data += tocopy;
2982 blk++;
2983 }
2984out:
Jan Karaf5c8f7d2008-07-04 09:59:33 -07002985 if (len == towrite) {
2986 mutex_unlock(&inode->i_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 return err;
Jan Karaf5c8f7d2008-07-04 09:59:33 -07002988 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989 if (inode->i_size < off+len-towrite) {
2990 i_size_write(inode, off+len-towrite);
2991 EXT3_I(inode)->i_disksize = inode->i_size;
2992 }
2993 inode->i_version++;
2994 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
2995 ext3_mark_inode_dirty(handle, inode);
Jes Sorensen1b1dcc12006-01-09 15:59:24 -08002996 mutex_unlock(&inode->i_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 return len - towrite;
2998}
2999
3000#endif
3001
David Howells454e2392006-06-23 02:02:57 -07003002static int ext3_get_sb(struct file_system_type *fs_type,
3003 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004{
David Howells454e2392006-06-23 02:02:57 -07003005 return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super, mnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006}
3007
3008static struct file_system_type ext3_fs_type = {
3009 .owner = THIS_MODULE,
3010 .name = "ext3",
3011 .get_sb = ext3_get_sb,
3012 .kill_sb = kill_block_super,
3013 .fs_flags = FS_REQUIRES_DEV,
3014};
3015
3016static int __init init_ext3_fs(void)
3017{
3018 int err = init_ext3_xattr();
3019 if (err)
3020 return err;
3021 err = init_inodecache();
3022 if (err)
3023 goto out1;
3024 err = register_filesystem(&ext3_fs_type);
3025 if (err)
3026 goto out;
3027 return 0;
3028out:
3029 destroy_inodecache();
3030out1:
Dave Kleikampe9ad5622006-09-27 01:49:35 -07003031 exit_ext3_xattr();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 return err;
3033}
3034
3035static void __exit exit_ext3_fs(void)
3036{
3037 unregister_filesystem(&ext3_fs_type);
3038 destroy_inodecache();
3039 exit_ext3_xattr();
3040}
3041
3042MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
3043MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
3044MODULE_LICENSE("GPL");
3045module_init(init_ext3_fs)
3046module_exit(exit_ext3_fs)