1 |
1275 |
phoenix |
/*
|
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 |
|
|
|
19 |
|
|
#include <linux/config.h>
|
20 |
|
|
#include <linux/module.h>
|
21 |
|
|
#include <linux/string.h>
|
22 |
|
|
#include <linux/fs.h>
|
23 |
|
|
#include <linux/sched.h>
|
24 |
|
|
#include <linux/jbd.h>
|
25 |
|
|
#include <linux/ext3_fs.h>
|
26 |
|
|
#include <linux/ext3_jbd.h>
|
27 |
|
|
#include <linux/slab.h>
|
28 |
|
|
#include <linux/init.h>
|
29 |
|
|
#include <linux/locks.h>
|
30 |
|
|
#include <linux/blkdev.h>
|
31 |
|
|
#include <linux/smp_lock.h>
|
32 |
|
|
#include <linux/random.h>
|
33 |
|
|
#include <asm/uaccess.h>
|
34 |
|
|
|
35 |
|
|
#ifdef CONFIG_JBD_DEBUG
|
36 |
|
|
static int ext3_ro_after; /* Make fs read-only after this many jiffies */
|
37 |
|
|
#endif
|
38 |
|
|
|
39 |
|
|
static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
|
40 |
|
|
static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
|
41 |
|
|
int);
|
42 |
|
|
static void ext3_commit_super (struct super_block * sb,
|
43 |
|
|
struct ext3_super_block * es,
|
44 |
|
|
int sync);
|
45 |
|
|
static void ext3_mark_recovery_complete(struct super_block * sb,
|
46 |
|
|
struct ext3_super_block * es);
|
47 |
|
|
static void ext3_clear_journal_err(struct super_block * sb,
|
48 |
|
|
struct ext3_super_block * es);
|
49 |
|
|
|
50 |
|
|
static int ext3_sync_fs(struct super_block * sb);
|
51 |
|
|
|
52 |
|
|
#ifdef CONFIG_JBD_DEBUG
|
53 |
|
|
int journal_no_write[2];
|
54 |
|
|
|
55 |
|
|
/*
|
56 |
|
|
* Debug code for turning filesystems "read-only" after a specified
|
57 |
|
|
* amount of time. This is for crash/recovery testing.
|
58 |
|
|
*/
|
59 |
|
|
|
60 |
|
|
static void make_rdonly(kdev_t dev, int *no_write)
|
61 |
|
|
{
|
62 |
|
|
if (dev) {
|
63 |
|
|
printk(KERN_WARNING "Turning device %s read-only\n",
|
64 |
|
|
bdevname(dev));
|
65 |
|
|
*no_write = 0xdead0000 + dev;
|
66 |
|
|
}
|
67 |
|
|
}
|
68 |
|
|
|
69 |
|
|
static void turn_fs_readonly(unsigned long arg)
|
70 |
|
|
{
|
71 |
|
|
struct super_block *sb = (struct super_block *)arg;
|
72 |
|
|
|
73 |
|
|
make_rdonly(sb->s_dev, &journal_no_write[0]);
|
74 |
|
|
make_rdonly(EXT3_SB(sb)->s_journal->j_dev, &journal_no_write[1]);
|
75 |
|
|
wake_up(&EXT3_SB(sb)->ro_wait_queue);
|
76 |
|
|
}
|
77 |
|
|
|
78 |
|
|
static void setup_ro_after(struct super_block *sb)
|
79 |
|
|
{
|
80 |
|
|
struct ext3_sb_info *sbi = EXT3_SB(sb);
|
81 |
|
|
init_timer(&sbi->turn_ro_timer);
|
82 |
|
|
if (ext3_ro_after) {
|
83 |
|
|
printk(KERN_DEBUG "fs will go read-only in %d jiffies\n",
|
84 |
|
|
ext3_ro_after);
|
85 |
|
|
init_waitqueue_head(&sbi->ro_wait_queue);
|
86 |
|
|
journal_no_write[0] = 0;
|
87 |
|
|
journal_no_write[1] = 0;
|
88 |
|
|
sbi->turn_ro_timer.function = turn_fs_readonly;
|
89 |
|
|
sbi->turn_ro_timer.data = (unsigned long)sb;
|
90 |
|
|
sbi->turn_ro_timer.expires = jiffies + ext3_ro_after;
|
91 |
|
|
ext3_ro_after = 0;
|
92 |
|
|
add_timer(&sbi->turn_ro_timer);
|
93 |
|
|
}
|
94 |
|
|
}
|
95 |
|
|
|
96 |
|
|
static void clear_ro_after(struct super_block *sb)
|
97 |
|
|
{
|
98 |
|
|
del_timer_sync(&EXT3_SB(sb)->turn_ro_timer);
|
99 |
|
|
journal_no_write[0] = 0;
|
100 |
|
|
journal_no_write[1] = 0;
|
101 |
|
|
ext3_ro_after = 0;
|
102 |
|
|
}
|
103 |
|
|
#else
|
104 |
|
|
#define setup_ro_after(sb) do {} while (0)
|
105 |
|
|
#define clear_ro_after(sb) do {} while (0)
|
106 |
|
|
#endif
|
107 |
|
|
|
108 |
|
|
|
109 |
|
|
static char error_buf[1024];
|
110 |
|
|
|
111 |
|
|
/* Determine the appropriate response to ext3_error on a given filesystem */
|
112 |
|
|
|
113 |
|
|
static int ext3_error_behaviour(struct super_block *sb)
|
114 |
|
|
{
|
115 |
|
|
/* First check for mount-time options */
|
116 |
|
|
if (test_opt (sb, ERRORS_PANIC))
|
117 |
|
|
return EXT3_ERRORS_PANIC;
|
118 |
|
|
if (test_opt (sb, ERRORS_RO))
|
119 |
|
|
return EXT3_ERRORS_RO;
|
120 |
|
|
if (test_opt (sb, ERRORS_CONT))
|
121 |
|
|
return EXT3_ERRORS_CONTINUE;
|
122 |
|
|
|
123 |
|
|
/* If no overrides were specified on the mount, then fall back
|
124 |
|
|
* to the default behaviour set in the filesystem's superblock
|
125 |
|
|
* on disk. */
|
126 |
|
|
switch (le16_to_cpu(sb->u.ext3_sb.s_es->s_errors)) {
|
127 |
|
|
case EXT3_ERRORS_PANIC:
|
128 |
|
|
return EXT3_ERRORS_PANIC;
|
129 |
|
|
case EXT3_ERRORS_RO:
|
130 |
|
|
return EXT3_ERRORS_RO;
|
131 |
|
|
default:
|
132 |
|
|
break;
|
133 |
|
|
}
|
134 |
|
|
return EXT3_ERRORS_CONTINUE;
|
135 |
|
|
}
|
136 |
|
|
|
137 |
|
|
/* Deal with the reporting of failure conditions on a filesystem such as
|
138 |
|
|
* inconsistencies detected or read IO failures.
|
139 |
|
|
*
|
140 |
|
|
* On ext2, we can store the error state of the filesystem in the
|
141 |
|
|
* superblock. That is not possible on ext3, because we may have other
|
142 |
|
|
* write ordering constraints on the superblock which prevent us from
|
143 |
|
|
* writing it out straight away; and given that the journal is about to
|
144 |
|
|
* be aborted, we can't rely on the current, or future, transactions to
|
145 |
|
|
* write out the superblock safely.
|
146 |
|
|
*
|
147 |
|
|
* We'll just use the journal_abort() error code to record an error in
|
148 |
|
|
* the journal instead. On recovery, the journal will compain about
|
149 |
|
|
* that error until we've noted it down and cleared it.
|
150 |
|
|
*/
|
151 |
|
|
|
152 |
|
|
static void ext3_handle_error(struct super_block *sb)
|
153 |
|
|
{
|
154 |
|
|
struct ext3_super_block *es = EXT3_SB(sb)->s_es;
|
155 |
|
|
|
156 |
|
|
EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
|
157 |
|
|
es->s_state |= cpu_to_le32(EXT3_ERROR_FS);
|
158 |
|
|
|
159 |
|
|
if (sb->s_flags & MS_RDONLY)
|
160 |
|
|
return;
|
161 |
|
|
|
162 |
|
|
if (ext3_error_behaviour(sb) != EXT3_ERRORS_CONTINUE) {
|
163 |
|
|
EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
|
164 |
|
|
journal_abort(EXT3_SB(sb)->s_journal, -EIO);
|
165 |
|
|
}
|
166 |
|
|
|
167 |
|
|
if (ext3_error_behaviour(sb) == EXT3_ERRORS_PANIC)
|
168 |
|
|
panic ("EXT3-fs (device %s): panic forced after error\n",
|
169 |
|
|
bdevname(sb->s_dev));
|
170 |
|
|
|
171 |
|
|
if (ext3_error_behaviour(sb) == EXT3_ERRORS_RO) {
|
172 |
|
|
printk (KERN_CRIT "Remounting filesystem read-only\n");
|
173 |
|
|
sb->s_flags |= MS_RDONLY;
|
174 |
|
|
}
|
175 |
|
|
|
176 |
|
|
ext3_commit_super(sb, es, 1);
|
177 |
|
|
}
|
178 |
|
|
|
179 |
|
|
void ext3_error (struct super_block * sb, const char * function,
|
180 |
|
|
const char * fmt, ...)
|
181 |
|
|
{
|
182 |
|
|
va_list args;
|
183 |
|
|
|
184 |
|
|
va_start (args, fmt);
|
185 |
|
|
vsprintf (error_buf, fmt, args);
|
186 |
|
|
va_end (args);
|
187 |
|
|
|
188 |
|
|
printk (KERN_CRIT "EXT3-fs error (device %s): %s: %s\n",
|
189 |
|
|
bdevname(sb->s_dev), function, error_buf);
|
190 |
|
|
|
191 |
|
|
ext3_handle_error(sb);
|
192 |
|
|
}
|
193 |
|
|
|
194 |
|
|
const char *ext3_decode_error(struct super_block * sb, int errno, char nbuf[16])
|
195 |
|
|
{
|
196 |
|
|
char *errstr = NULL;
|
197 |
|
|
|
198 |
|
|
switch (errno) {
|
199 |
|
|
case -EIO:
|
200 |
|
|
errstr = "IO failure";
|
201 |
|
|
break;
|
202 |
|
|
case -ENOMEM:
|
203 |
|
|
errstr = "Out of memory";
|
204 |
|
|
break;
|
205 |
|
|
case -EROFS:
|
206 |
|
|
if (!sb || EXT3_SB(sb)->s_journal->j_flags & JFS_ABORT)
|
207 |
|
|
errstr = "Journal has aborted";
|
208 |
|
|
else
|
209 |
|
|
errstr = "Readonly filesystem";
|
210 |
|
|
break;
|
211 |
|
|
default:
|
212 |
|
|
/* If the caller passed in an extra buffer for unknown
|
213 |
|
|
* errors, textualise them now. Else we just return
|
214 |
|
|
* NULL. */
|
215 |
|
|
if (nbuf) {
|
216 |
|
|
/* Check for truncated error codes... */
|
217 |
|
|
if (snprintf(nbuf, 16, "error %d", -errno) >= 0)
|
218 |
|
|
errstr = nbuf;
|
219 |
|
|
}
|
220 |
|
|
|
221 |
|
|
break;
|
222 |
|
|
}
|
223 |
|
|
|
224 |
|
|
return errstr;
|
225 |
|
|
}
|
226 |
|
|
|
227 |
|
|
/* __ext3_std_error decodes expected errors from journaling functions
|
228 |
|
|
* automatically and invokes the appropriate error response. */
|
229 |
|
|
|
230 |
|
|
void __ext3_std_error (struct super_block * sb, const char * function,
|
231 |
|
|
int errno)
|
232 |
|
|
{
|
233 |
|
|
char nbuf[16];
|
234 |
|
|
const char *errstr = ext3_decode_error(sb, errno, nbuf);
|
235 |
|
|
|
236 |
|
|
printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
|
237 |
|
|
bdevname(sb->s_dev), function, errstr);
|
238 |
|
|
|
239 |
|
|
ext3_handle_error(sb);
|
240 |
|
|
}
|
241 |
|
|
|
242 |
|
|
/*
|
243 |
|
|
* ext3_abort is a much stronger failure handler than ext3_error. The
|
244 |
|
|
* abort function may be used to deal with unrecoverable failures such
|
245 |
|
|
* as journal IO errors or ENOMEM at a critical moment in log management.
|
246 |
|
|
*
|
247 |
|
|
* We unconditionally force the filesystem into an ABORT|READONLY state,
|
248 |
|
|
* unless the error response on the fs has been set to panic in which
|
249 |
|
|
* case we take the easy way out and panic immediately.
|
250 |
|
|
*/
|
251 |
|
|
|
252 |
|
|
void ext3_abort (struct super_block * sb, const char * function,
|
253 |
|
|
const char * fmt, ...)
|
254 |
|
|
{
|
255 |
|
|
va_list args;
|
256 |
|
|
|
257 |
|
|
printk (KERN_CRIT "ext3_abort called.\n");
|
258 |
|
|
|
259 |
|
|
va_start (args, fmt);
|
260 |
|
|
vsprintf (error_buf, fmt, args);
|
261 |
|
|
va_end (args);
|
262 |
|
|
|
263 |
|
|
if (ext3_error_behaviour(sb) == EXT3_ERRORS_PANIC)
|
264 |
|
|
panic ("EXT3-fs panic (device %s): %s: %s\n",
|
265 |
|
|
bdevname(sb->s_dev), function, error_buf);
|
266 |
|
|
|
267 |
|
|
printk (KERN_CRIT "EXT3-fs abort (device %s): %s: %s\n",
|
268 |
|
|
bdevname(sb->s_dev), function, error_buf);
|
269 |
|
|
|
270 |
|
|
if (sb->s_flags & MS_RDONLY)
|
271 |
|
|
return;
|
272 |
|
|
|
273 |
|
|
printk (KERN_CRIT "Remounting filesystem read-only\n");
|
274 |
|
|
sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS;
|
275 |
|
|
sb->s_flags |= MS_RDONLY;
|
276 |
|
|
sb->u.ext3_sb.s_mount_opt |= EXT3_MOUNT_ABORT;
|
277 |
|
|
journal_abort(EXT3_SB(sb)->s_journal, -EIO);
|
278 |
|
|
}
|
279 |
|
|
|
280 |
|
|
/* Deal with the reporting of failure conditions while running, such as
|
281 |
|
|
* inconsistencies in operation or invalid system states.
|
282 |
|
|
*
|
283 |
|
|
* Use ext3_error() for cases of invalid filesystem states, as that will
|
284 |
|
|
* record an error on disk and force a filesystem check on the next boot.
|
285 |
|
|
*/
|
286 |
|
|
NORET_TYPE void ext3_panic (struct super_block * sb, const char * function,
|
287 |
|
|
const char * fmt, ...)
|
288 |
|
|
{
|
289 |
|
|
va_list args;
|
290 |
|
|
|
291 |
|
|
va_start (args, fmt);
|
292 |
|
|
vsprintf (error_buf, fmt, args);
|
293 |
|
|
va_end (args);
|
294 |
|
|
|
295 |
|
|
/* this is to prevent panic from syncing this filesystem */
|
296 |
|
|
/* AKPM: is this sufficient? */
|
297 |
|
|
sb->s_flags |= MS_RDONLY;
|
298 |
|
|
panic ("EXT3-fs panic (device %s): %s: %s\n",
|
299 |
|
|
bdevname(sb->s_dev), function, error_buf);
|
300 |
|
|
}
|
301 |
|
|
|
302 |
|
|
void ext3_warning (struct super_block * sb, const char * function,
|
303 |
|
|
const char * fmt, ...)
|
304 |
|
|
{
|
305 |
|
|
va_list args;
|
306 |
|
|
|
307 |
|
|
va_start (args, fmt);
|
308 |
|
|
vsprintf (error_buf, fmt, args);
|
309 |
|
|
va_end (args);
|
310 |
|
|
printk (KERN_WARNING "EXT3-fs warning (device %s): %s: %s\n",
|
311 |
|
|
bdevname(sb->s_dev), function, error_buf);
|
312 |
|
|
}
|
313 |
|
|
|
314 |
|
|
void ext3_update_dynamic_rev(struct super_block *sb)
|
315 |
|
|
{
|
316 |
|
|
struct ext3_super_block *es = EXT3_SB(sb)->s_es;
|
317 |
|
|
|
318 |
|
|
if (le32_to_cpu(es->s_rev_level) > EXT3_GOOD_OLD_REV)
|
319 |
|
|
return;
|
320 |
|
|
|
321 |
|
|
ext3_warning(sb, __FUNCTION__,
|
322 |
|
|
"updating to rev %d because of new feature flag, "
|
323 |
|
|
"running e2fsck is recommended",
|
324 |
|
|
EXT3_DYNAMIC_REV);
|
325 |
|
|
|
326 |
|
|
es->s_first_ino = cpu_to_le32(EXT3_GOOD_OLD_FIRST_INO);
|
327 |
|
|
es->s_inode_size = cpu_to_le16(EXT3_GOOD_OLD_INODE_SIZE);
|
328 |
|
|
es->s_rev_level = cpu_to_le32(EXT3_DYNAMIC_REV);
|
329 |
|
|
/* leave es->s_feature_*compat flags alone */
|
330 |
|
|
/* es->s_uuid will be set by e2fsck if empty */
|
331 |
|
|
|
332 |
|
|
/*
|
333 |
|
|
* The rest of the superblock fields should be zero, and if not it
|
334 |
|
|
* means they are likely already in use, so leave them alone. We
|
335 |
|
|
* can leave it up to e2fsck to clean up any inconsistencies there.
|
336 |
|
|
*/
|
337 |
|
|
}
|
338 |
|
|
|
339 |
|
|
/*
|
340 |
|
|
* Open the external journal device
|
341 |
|
|
*/
|
342 |
|
|
static struct block_device *ext3_blkdev_get(kdev_t dev)
|
343 |
|
|
{
|
344 |
|
|
struct block_device *bdev;
|
345 |
|
|
int err = -ENODEV;
|
346 |
|
|
|
347 |
|
|
bdev = bdget(kdev_t_to_nr(dev));
|
348 |
|
|
if (bdev == NULL)
|
349 |
|
|
goto fail;
|
350 |
|
|
err = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_FS);
|
351 |
|
|
if (err < 0)
|
352 |
|
|
goto fail;
|
353 |
|
|
return bdev;
|
354 |
|
|
|
355 |
|
|
fail:
|
356 |
|
|
printk(KERN_ERR "EXT3: failed to open journal device %s: %d\n",
|
357 |
|
|
bdevname(dev), err);
|
358 |
|
|
return NULL;
|
359 |
|
|
}
|
360 |
|
|
|
361 |
|
|
/*
|
362 |
|
|
* Release the journal device
|
363 |
|
|
*/
|
364 |
|
|
static int ext3_blkdev_put(struct block_device *bdev)
|
365 |
|
|
{
|
366 |
|
|
return blkdev_put(bdev, BDEV_FS);
|
367 |
|
|
}
|
368 |
|
|
|
369 |
|
|
static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
|
370 |
|
|
{
|
371 |
|
|
struct block_device *bdev;
|
372 |
|
|
int ret = -ENODEV;
|
373 |
|
|
|
374 |
|
|
bdev = sbi->journal_bdev;
|
375 |
|
|
if (bdev) {
|
376 |
|
|
ret = ext3_blkdev_put(bdev);
|
377 |
|
|
sbi->journal_bdev = 0;
|
378 |
|
|
}
|
379 |
|
|
return ret;
|
380 |
|
|
}
|
381 |
|
|
|
382 |
|
|
#define orphan_list_entry(l) list_entry((l), struct inode, u.ext3_i.i_orphan)
|
383 |
|
|
|
384 |
|
|
static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
|
385 |
|
|
{
|
386 |
|
|
struct list_head *l;
|
387 |
|
|
|
388 |
|
|
printk(KERN_ERR "sb orphan head is %d\n",
|
389 |
|
|
le32_to_cpu(sbi->s_es->s_last_orphan));
|
390 |
|
|
|
391 |
|
|
printk(KERN_ERR "sb_info orphan list:\n");
|
392 |
|
|
list_for_each(l, &sbi->s_orphan) {
|
393 |
|
|
struct inode *inode = orphan_list_entry(l);
|
394 |
|
|
printk(KERN_ERR " "
|
395 |
|
|
"inode 0x%04x:%ld at %p: mode %o, nlink %d, next %d\n",
|
396 |
|
|
inode->i_dev, inode->i_ino, inode,
|
397 |
|
|
inode->i_mode, inode->i_nlink,
|
398 |
|
|
le32_to_cpu(NEXT_ORPHAN(inode)));
|
399 |
|
|
}
|
400 |
|
|
}
|
401 |
|
|
|
402 |
|
|
void ext3_put_super (struct super_block * sb)
|
403 |
|
|
{
|
404 |
|
|
struct ext3_sb_info *sbi = EXT3_SB(sb);
|
405 |
|
|
struct ext3_super_block *es = sbi->s_es;
|
406 |
|
|
kdev_t j_dev = sbi->s_journal->j_dev;
|
407 |
|
|
int i;
|
408 |
|
|
|
409 |
|
|
journal_destroy(sbi->s_journal);
|
410 |
|
|
if (!(sb->s_flags & MS_RDONLY)) {
|
411 |
|
|
EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
|
412 |
|
|
es->s_state = le16_to_cpu(sbi->s_mount_state);
|
413 |
|
|
BUFFER_TRACE(sbi->s_sbh, "marking dirty");
|
414 |
|
|
mark_buffer_dirty(sbi->s_sbh);
|
415 |
|
|
ext3_commit_super(sb, es, 1);
|
416 |
|
|
}
|
417 |
|
|
|
418 |
|
|
for (i = 0; i < sbi->s_gdb_count; i++)
|
419 |
|
|
brelse(sbi->s_group_desc[i]);
|
420 |
|
|
kfree(sbi->s_group_desc);
|
421 |
|
|
for (i = 0; i < EXT3_MAX_GROUP_LOADED; i++)
|
422 |
|
|
brelse(sbi->s_inode_bitmap[i]);
|
423 |
|
|
for (i = 0; i < EXT3_MAX_GROUP_LOADED; i++)
|
424 |
|
|
brelse(sbi->s_block_bitmap[i]);
|
425 |
|
|
brelse(sbi->s_sbh);
|
426 |
|
|
|
427 |
|
|
/* Debugging code just in case the in-memory inode orphan list
|
428 |
|
|
* isn't empty. The on-disk one can be non-empty if we've
|
429 |
|
|
* detected an error and taken the fs readonly, but the
|
430 |
|
|
* in-memory list had better be clean by this point. */
|
431 |
|
|
if (!list_empty(&sbi->s_orphan))
|
432 |
|
|
dump_orphan_list(sb, sbi);
|
433 |
|
|
J_ASSERT(list_empty(&sbi->s_orphan));
|
434 |
|
|
|
435 |
|
|
invalidate_buffers(sb->s_dev);
|
436 |
|
|
if (j_dev != sb->s_dev) {
|
437 |
|
|
/*
|
438 |
|
|
* Invalidate the journal device's buffers. We don't want them
|
439 |
|
|
* floating about in memory - the physical journal device may
|
440 |
|
|
* hotswapped, and it breaks the `ro-after' testing code.
|
441 |
|
|
*/
|
442 |
|
|
fsync_no_super(j_dev);
|
443 |
|
|
invalidate_buffers(j_dev);
|
444 |
|
|
ext3_blkdev_remove(sbi);
|
445 |
|
|
}
|
446 |
|
|
clear_ro_after(sb);
|
447 |
|
|
|
448 |
|
|
return;
|
449 |
|
|
}
|
450 |
|
|
|
451 |
|
|
static struct dquot_operations ext3_qops;
|
452 |
|
|
|
453 |
|
|
static struct super_operations ext3_sops = {
|
454 |
|
|
read_inode: ext3_read_inode, /* BKL held */
|
455 |
|
|
write_inode: ext3_write_inode, /* BKL not held. Don't need */
|
456 |
|
|
dirty_inode: ext3_dirty_inode, /* BKL not held. We take it */
|
457 |
|
|
put_inode: ext3_put_inode, /* BKL not held. Don't need */
|
458 |
|
|
delete_inode: ext3_delete_inode, /* BKL not held. We take it */
|
459 |
|
|
put_super: ext3_put_super, /* BKL held */
|
460 |
|
|
write_super: ext3_write_super, /* BKL held */
|
461 |
|
|
sync_fs: ext3_sync_fs,
|
462 |
|
|
write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
|
463 |
|
|
unlockfs: ext3_unlockfs, /* BKL not held. We take it */
|
464 |
|
|
statfs: ext3_statfs, /* BKL held */
|
465 |
|
|
remount_fs: ext3_remount, /* BKL held */
|
466 |
|
|
};
|
467 |
|
|
|
468 |
|
|
static int want_value(char *value, char *option)
|
469 |
|
|
{
|
470 |
|
|
if (!value || !*value) {
|
471 |
|
|
printk(KERN_NOTICE "EXT3-fs: the %s option needs an argument\n",
|
472 |
|
|
option);
|
473 |
|
|
return -1;
|
474 |
|
|
}
|
475 |
|
|
return 0;
|
476 |
|
|
}
|
477 |
|
|
|
478 |
|
|
static int want_null_value(char *value, char *option)
|
479 |
|
|
{
|
480 |
|
|
if (*value) {
|
481 |
|
|
printk(KERN_NOTICE "EXT3-fs: Invalid %s argument: %s\n",
|
482 |
|
|
option, value);
|
483 |
|
|
return -1;
|
484 |
|
|
}
|
485 |
|
|
return 0;
|
486 |
|
|
}
|
487 |
|
|
|
488 |
|
|
static int want_numeric(char *value, char *option, unsigned long *number)
|
489 |
|
|
{
|
490 |
|
|
if (want_value(value, option))
|
491 |
|
|
return -1;
|
492 |
|
|
*number = simple_strtoul(value, &value, 0);
|
493 |
|
|
if (want_null_value(value, option))
|
494 |
|
|
return -1;
|
495 |
|
|
return 0;
|
496 |
|
|
}
|
497 |
|
|
|
498 |
|
|
/*
|
499 |
|
|
* This function has been shamelessly adapted from the msdos fs
|
500 |
|
|
*/
|
501 |
|
|
static int parse_options (char * options, unsigned long * sb_block,
|
502 |
|
|
struct ext3_sb_info *sbi,
|
503 |
|
|
unsigned long * inum,
|
504 |
|
|
int is_remount)
|
505 |
|
|
{
|
506 |
|
|
unsigned long *mount_options = &sbi->s_mount_opt;
|
507 |
|
|
uid_t *resuid = &sbi->s_resuid;
|
508 |
|
|
gid_t *resgid = &sbi->s_resgid;
|
509 |
|
|
char * this_char;
|
510 |
|
|
char * value;
|
511 |
|
|
|
512 |
|
|
if (!options)
|
513 |
|
|
return 1;
|
514 |
|
|
for (this_char = strtok (options, ",");
|
515 |
|
|
this_char != NULL;
|
516 |
|
|
this_char = strtok (NULL, ",")) {
|
517 |
|
|
if ((value = strchr (this_char, '=')) != NULL)
|
518 |
|
|
*value++ = 0;
|
519 |
|
|
if (!strcmp (this_char, "bsddf"))
|
520 |
|
|
clear_opt (*mount_options, MINIX_DF);
|
521 |
|
|
else if (!strcmp (this_char, "nouid32")) {
|
522 |
|
|
set_opt (*mount_options, NO_UID32);
|
523 |
|
|
}
|
524 |
|
|
else if (!strcmp (this_char, "abort"))
|
525 |
|
|
set_opt (*mount_options, ABORT);
|
526 |
|
|
else if (!strcmp (this_char, "check")) {
|
527 |
|
|
if (!value || !*value || !strcmp (value, "none"))
|
528 |
|
|
clear_opt (*mount_options, CHECK);
|
529 |
|
|
else
|
530 |
|
|
#ifdef CONFIG_EXT3_CHECK
|
531 |
|
|
set_opt (*mount_options, CHECK);
|
532 |
|
|
#else
|
533 |
|
|
printk(KERN_ERR
|
534 |
|
|
"EXT3 Check option not supported\n");
|
535 |
|
|
#endif
|
536 |
|
|
}
|
537 |
|
|
else if (!strcmp (this_char, "debug"))
|
538 |
|
|
set_opt (*mount_options, DEBUG);
|
539 |
|
|
else if (!strcmp (this_char, "errors")) {
|
540 |
|
|
if (want_value(value, "errors"))
|
541 |
|
|
return 0;
|
542 |
|
|
if (!strcmp (value, "continue")) {
|
543 |
|
|
clear_opt (*mount_options, ERRORS_RO);
|
544 |
|
|
clear_opt (*mount_options, ERRORS_PANIC);
|
545 |
|
|
set_opt (*mount_options, ERRORS_CONT);
|
546 |
|
|
}
|
547 |
|
|
else if (!strcmp (value, "remount-ro")) {
|
548 |
|
|
clear_opt (*mount_options, ERRORS_CONT);
|
549 |
|
|
clear_opt (*mount_options, ERRORS_PANIC);
|
550 |
|
|
set_opt (*mount_options, ERRORS_RO);
|
551 |
|
|
}
|
552 |
|
|
else if (!strcmp (value, "panic")) {
|
553 |
|
|
clear_opt (*mount_options, ERRORS_CONT);
|
554 |
|
|
clear_opt (*mount_options, ERRORS_RO);
|
555 |
|
|
set_opt (*mount_options, ERRORS_PANIC);
|
556 |
|
|
}
|
557 |
|
|
else {
|
558 |
|
|
printk (KERN_ERR
|
559 |
|
|
"EXT3-fs: Invalid errors option: %s\n",
|
560 |
|
|
value);
|
561 |
|
|
return 0;
|
562 |
|
|
}
|
563 |
|
|
}
|
564 |
|
|
else if (!strcmp (this_char, "grpid") ||
|
565 |
|
|
!strcmp (this_char, "bsdgroups"))
|
566 |
|
|
set_opt (*mount_options, GRPID);
|
567 |
|
|
else if (!strcmp (this_char, "minixdf"))
|
568 |
|
|
set_opt (*mount_options, MINIX_DF);
|
569 |
|
|
else if (!strcmp (this_char, "nocheck"))
|
570 |
|
|
clear_opt (*mount_options, CHECK);
|
571 |
|
|
else if (!strcmp (this_char, "nogrpid") ||
|
572 |
|
|
!strcmp (this_char, "sysvgroups"))
|
573 |
|
|
clear_opt (*mount_options, GRPID);
|
574 |
|
|
else if (!strcmp (this_char, "resgid")) {
|
575 |
|
|
unsigned long v;
|
576 |
|
|
if (want_numeric(value, "resgid", &v))
|
577 |
|
|
return 0;
|
578 |
|
|
*resgid = v;
|
579 |
|
|
}
|
580 |
|
|
else if (!strcmp (this_char, "resuid")) {
|
581 |
|
|
unsigned long v;
|
582 |
|
|
if (want_numeric(value, "resuid", &v))
|
583 |
|
|
return 0;
|
584 |
|
|
*resuid = v;
|
585 |
|
|
}
|
586 |
|
|
else if (!strcmp (this_char, "sb")) {
|
587 |
|
|
if (want_numeric(value, "sb", sb_block))
|
588 |
|
|
return 0;
|
589 |
|
|
}
|
590 |
|
|
#ifdef CONFIG_JBD_DEBUG
|
591 |
|
|
else if (!strcmp (this_char, "ro-after")) {
|
592 |
|
|
unsigned long v;
|
593 |
|
|
if (want_numeric(value, "ro-after", &v))
|
594 |
|
|
return 0;
|
595 |
|
|
ext3_ro_after = v;
|
596 |
|
|
}
|
597 |
|
|
#endif
|
598 |
|
|
/* Silently ignore the quota options */
|
599 |
|
|
else if (!strcmp (this_char, "grpquota")
|
600 |
|
|
|| !strcmp (this_char, "noquota")
|
601 |
|
|
|| !strcmp (this_char, "quota")
|
602 |
|
|
|| !strcmp (this_char, "usrquota"))
|
603 |
|
|
/* Don't do anything ;-) */ ;
|
604 |
|
|
else if (!strcmp (this_char, "journal")) {
|
605 |
|
|
/* @@@ FIXME */
|
606 |
|
|
/* Eventually we will want to be able to create
|
607 |
|
|
a journal file here. For now, only allow the
|
608 |
|
|
user to specify an existing inode to be the
|
609 |
|
|
journal file. */
|
610 |
|
|
if (is_remount) {
|
611 |
|
|
printk(KERN_ERR "EXT3-fs: cannot specify "
|
612 |
|
|
"journal on remount\n");
|
613 |
|
|
return 0;
|
614 |
|
|
}
|
615 |
|
|
|
616 |
|
|
if (want_value(value, "journal"))
|
617 |
|
|
return 0;
|
618 |
|
|
if (!strcmp (value, "update"))
|
619 |
|
|
set_opt (*mount_options, UPDATE_JOURNAL);
|
620 |
|
|
else if (want_numeric(value, "journal", inum))
|
621 |
|
|
return 0;
|
622 |
|
|
}
|
623 |
|
|
else if (!strcmp (this_char, "noload"))
|
624 |
|
|
set_opt (*mount_options, NOLOAD);
|
625 |
|
|
else if (!strcmp (this_char, "data")) {
|
626 |
|
|
int data_opt = 0;
|
627 |
|
|
|
628 |
|
|
if (want_value(value, "data"))
|
629 |
|
|
return 0;
|
630 |
|
|
if (!strcmp (value, "journal"))
|
631 |
|
|
data_opt = EXT3_MOUNT_JOURNAL_DATA;
|
632 |
|
|
else if (!strcmp (value, "ordered"))
|
633 |
|
|
data_opt = EXT3_MOUNT_ORDERED_DATA;
|
634 |
|
|
else if (!strcmp (value, "writeback"))
|
635 |
|
|
data_opt = EXT3_MOUNT_WRITEBACK_DATA;
|
636 |
|
|
else {
|
637 |
|
|
printk (KERN_ERR
|
638 |
|
|
"EXT3-fs: Invalid data option: %s\n",
|
639 |
|
|
value);
|
640 |
|
|
return 0;
|
641 |
|
|
}
|
642 |
|
|
if (is_remount) {
|
643 |
|
|
if ((*mount_options & EXT3_MOUNT_DATA_FLAGS) !=
|
644 |
|
|
data_opt) {
|
645 |
|
|
printk(KERN_ERR
|
646 |
|
|
"EXT3-fs: cannot change data "
|
647 |
|
|
"mode on remount\n");
|
648 |
|
|
return 0;
|
649 |
|
|
}
|
650 |
|
|
} else {
|
651 |
|
|
*mount_options &= ~EXT3_MOUNT_DATA_FLAGS;
|
652 |
|
|
*mount_options |= data_opt;
|
653 |
|
|
}
|
654 |
|
|
} else if (!strcmp (this_char, "commit")) {
|
655 |
|
|
unsigned long v;
|
656 |
|
|
if (want_numeric(value, "commit", &v))
|
657 |
|
|
return 0;
|
658 |
|
|
sbi->s_commit_interval = (HZ * v);
|
659 |
|
|
} else {
|
660 |
|
|
printk (KERN_ERR
|
661 |
|
|
"EXT3-fs: Unrecognized mount option %s\n",
|
662 |
|
|
this_char);
|
663 |
|
|
return 0;
|
664 |
|
|
}
|
665 |
|
|
}
|
666 |
|
|
return 1;
|
667 |
|
|
}
|
668 |
|
|
|
669 |
|
|
static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
|
670 |
|
|
int read_only)
|
671 |
|
|
{
|
672 |
|
|
struct ext3_sb_info *sbi = EXT3_SB(sb);
|
673 |
|
|
int res = 0;
|
674 |
|
|
|
675 |
|
|
if (le32_to_cpu(es->s_rev_level) > EXT3_MAX_SUPP_REV) {
|
676 |
|
|
printk (KERN_ERR "EXT3-fs warning: revision level too high, "
|
677 |
|
|
"forcing read-only mode\n");
|
678 |
|
|
res = MS_RDONLY;
|
679 |
|
|
}
|
680 |
|
|
if (read_only)
|
681 |
|
|
return res;
|
682 |
|
|
if (!(sbi->s_mount_state & EXT3_VALID_FS))
|
683 |
|
|
printk (KERN_WARNING "EXT3-fs warning: mounting unchecked fs, "
|
684 |
|
|
"running e2fsck is recommended\n");
|
685 |
|
|
else if ((sbi->s_mount_state & EXT3_ERROR_FS))
|
686 |
|
|
printk (KERN_WARNING
|
687 |
|
|
"EXT3-fs warning: mounting fs with errors, "
|
688 |
|
|
"running e2fsck is recommended\n");
|
689 |
|
|
else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
|
690 |
|
|
le16_to_cpu(es->s_mnt_count) >=
|
691 |
|
|
(unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
|
692 |
|
|
printk (KERN_WARNING
|
693 |
|
|
"EXT3-fs warning: maximal mount count reached, "
|
694 |
|
|
"running e2fsck is recommended\n");
|
695 |
|
|
else if (le32_to_cpu(es->s_checkinterval) &&
|
696 |
|
|
(le32_to_cpu(es->s_lastcheck) +
|
697 |
|
|
le32_to_cpu(es->s_checkinterval) <= CURRENT_TIME))
|
698 |
|
|
printk (KERN_WARNING
|
699 |
|
|
"EXT3-fs warning: checktime reached, "
|
700 |
|
|
"running e2fsck is recommended\n");
|
701 |
|
|
#if 0
|
702 |
|
|
/* @@@ We _will_ want to clear the valid bit if we find
|
703 |
|
|
inconsistencies, to force a fsck at reboot. But for
|
704 |
|
|
a plain journaled filesystem we can keep it set as
|
705 |
|
|
valid forever! :) */
|
706 |
|
|
es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT3_VALID_FS);
|
707 |
|
|
#endif
|
708 |
|
|
if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
|
709 |
|
|
es->s_max_mnt_count =
|
710 |
|
|
(__s16) cpu_to_le16(EXT3_DFL_MAX_MNT_COUNT);
|
711 |
|
|
es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1);
|
712 |
|
|
es->s_mtime = cpu_to_le32(CURRENT_TIME);
|
713 |
|
|
ext3_update_dynamic_rev(sb);
|
714 |
|
|
EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
|
715 |
|
|
ext3_commit_super (sb, es, 1);
|
716 |
|
|
if (test_opt (sb, DEBUG))
|
717 |
|
|
printk (KERN_INFO
|
718 |
|
|
"[EXT3 FS %s, %s, bs=%lu, gc=%lu, "
|
719 |
|
|
"bpg=%lu, ipg=%lu, mo=%04lx]\n",
|
720 |
|
|
EXT3FS_VERSION, EXT3FS_DATE, sb->s_blocksize,
|
721 |
|
|
sbi->s_groups_count,
|
722 |
|
|
EXT3_BLOCKS_PER_GROUP(sb),
|
723 |
|
|
EXT3_INODES_PER_GROUP(sb),
|
724 |
|
|
sbi->s_mount_opt);
|
725 |
|
|
printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
|
726 |
|
|
bdevname(sb->s_dev));
|
727 |
|
|
if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
|
728 |
|
|
printk("external journal on %s\n",
|
729 |
|
|
bdevname(EXT3_SB(sb)->s_journal->j_dev));
|
730 |
|
|
} else {
|
731 |
|
|
printk("internal journal\n");
|
732 |
|
|
}
|
733 |
|
|
#ifdef CONFIG_EXT3_CHECK
|
734 |
|
|
if (test_opt (sb, CHECK)) {
|
735 |
|
|
ext3_check_blocks_bitmap (sb);
|
736 |
|
|
ext3_check_inodes_bitmap (sb);
|
737 |
|
|
}
|
738 |
|
|
#endif
|
739 |
|
|
setup_ro_after(sb);
|
740 |
|
|
return res;
|
741 |
|
|
}
|
742 |
|
|
|
743 |
|
|
static int ext3_check_descriptors (struct super_block * sb)
|
744 |
|
|
{
|
745 |
|
|
struct ext3_sb_info *sbi = EXT3_SB(sb);
|
746 |
|
|
unsigned long block = le32_to_cpu(sbi->s_es->s_first_data_block);
|
747 |
|
|
struct ext3_group_desc * gdp = NULL;
|
748 |
|
|
int desc_block = 0;
|
749 |
|
|
int i;
|
750 |
|
|
|
751 |
|
|
ext3_debug ("Checking group descriptors");
|
752 |
|
|
|
753 |
|
|
for (i = 0; i < sbi->s_groups_count; i++)
|
754 |
|
|
{
|
755 |
|
|
if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0)
|
756 |
|
|
gdp = (struct ext3_group_desc *)
|
757 |
|
|
sbi->s_group_desc[desc_block++]->b_data;
|
758 |
|
|
if (le32_to_cpu(gdp->bg_block_bitmap) < block ||
|
759 |
|
|
le32_to_cpu(gdp->bg_block_bitmap) >=
|
760 |
|
|
block + EXT3_BLOCKS_PER_GROUP(sb))
|
761 |
|
|
{
|
762 |
|
|
ext3_error (sb, "ext3_check_descriptors",
|
763 |
|
|
"Block bitmap for group %d"
|
764 |
|
|
" not in group (block %lu)!",
|
765 |
|
|
i, (unsigned long)
|
766 |
|
|
le32_to_cpu(gdp->bg_block_bitmap));
|
767 |
|
|
return 0;
|
768 |
|
|
}
|
769 |
|
|
if (le32_to_cpu(gdp->bg_inode_bitmap) < block ||
|
770 |
|
|
le32_to_cpu(gdp->bg_inode_bitmap) >=
|
771 |
|
|
block + EXT3_BLOCKS_PER_GROUP(sb))
|
772 |
|
|
{
|
773 |
|
|
ext3_error (sb, "ext3_check_descriptors",
|
774 |
|
|
"Inode bitmap for group %d"
|
775 |
|
|
" not in group (block %lu)!",
|
776 |
|
|
i, (unsigned long)
|
777 |
|
|
le32_to_cpu(gdp->bg_inode_bitmap));
|
778 |
|
|
return 0;
|
779 |
|
|
}
|
780 |
|
|
if (le32_to_cpu(gdp->bg_inode_table) < block ||
|
781 |
|
|
le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group >=
|
782 |
|
|
block + EXT3_BLOCKS_PER_GROUP(sb))
|
783 |
|
|
{
|
784 |
|
|
ext3_error (sb, "ext3_check_descriptors",
|
785 |
|
|
"Inode table for group %d"
|
786 |
|
|
" not in group (block %lu)!",
|
787 |
|
|
i, (unsigned long)
|
788 |
|
|
le32_to_cpu(gdp->bg_inode_table));
|
789 |
|
|
return 0;
|
790 |
|
|
}
|
791 |
|
|
block += EXT3_BLOCKS_PER_GROUP(sb);
|
792 |
|
|
gdp++;
|
793 |
|
|
}
|
794 |
|
|
return 1;
|
795 |
|
|
}
|
796 |
|
|
|
797 |
|
|
static unsigned long descriptor_loc(struct super_block *sb,
|
798 |
|
|
unsigned long logic_sb_block,
|
799 |
|
|
int nr)
|
800 |
|
|
{
|
801 |
|
|
struct ext3_sb_info *sbi = EXT3_SB(sb);
|
802 |
|
|
unsigned long bg, first_data_block, first_meta_bg;
|
803 |
|
|
int has_super = 0;
|
804 |
|
|
|
805 |
|
|
first_data_block = le32_to_cpu(sbi->s_es->s_first_data_block);
|
806 |
|
|
first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
|
807 |
|
|
|
808 |
|
|
if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) ||
|
809 |
|
|
nr < first_meta_bg)
|
810 |
|
|
return (logic_sb_block + nr + 1);
|
811 |
|
|
bg = sbi->s_desc_per_block * nr;
|
812 |
|
|
if (ext3_bg_has_super(sb, bg))
|
813 |
|
|
has_super = 1;
|
814 |
|
|
return (first_data_block + has_super + (bg * sbi->s_blocks_per_group));
|
815 |
|
|
}
|
816 |
|
|
|
817 |
|
|
|
818 |
|
|
/* ext3_orphan_cleanup() walks a singly-linked list of inodes (starting at
|
819 |
|
|
* the superblock) which were deleted from all directories, but held open by
|
820 |
|
|
* a process at the time of a crash. We walk the list and try to delete these
|
821 |
|
|
* inodes at recovery time (only with a read-write filesystem).
|
822 |
|
|
*
|
823 |
|
|
* In order to keep the orphan inode chain consistent during traversal (in
|
824 |
|
|
* case of crash during recovery), we link each inode into the superblock
|
825 |
|
|
* orphan list_head and handle it the same way as an inode deletion during
|
826 |
|
|
* normal operation (which journals the operations for us).
|
827 |
|
|
*
|
828 |
|
|
* We only do an iget() and an iput() on each inode, which is very safe if we
|
829 |
|
|
* accidentally point at an in-use or already deleted inode. The worst that
|
830 |
|
|
* can happen in this case is that we get a "bit already cleared" message from
|
831 |
|
|
* ext3_free_inode(). The only reason we would point at a wrong inode is if
|
832 |
|
|
* e2fsck was run on this filesystem, and it must have already done the orphan
|
833 |
|
|
* inode cleanup for us, so we can safely abort without any further action.
|
834 |
|
|
*/
|
835 |
|
|
static void ext3_orphan_cleanup (struct super_block * sb,
|
836 |
|
|
struct ext3_super_block * es)
|
837 |
|
|
{
|
838 |
|
|
unsigned int s_flags = sb->s_flags;
|
839 |
|
|
int nr_orphans = 0, nr_truncates = 0;
|
840 |
|
|
if (!es->s_last_orphan) {
|
841 |
|
|
jbd_debug(4, "no orphan inodes to clean up\n");
|
842 |
|
|
return;
|
843 |
|
|
}
|
844 |
|
|
|
845 |
|
|
if (sb->u.ext3_sb.s_mount_state & EXT3_ERROR_FS) {
|
846 |
|
|
if (es->s_last_orphan)
|
847 |
|
|
jbd_debug(1, "Errors on filesystem, "
|
848 |
|
|
"clearing orphan list.\n");
|
849 |
|
|
es->s_last_orphan = 0;
|
850 |
|
|
jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
|
851 |
|
|
return;
|
852 |
|
|
}
|
853 |
|
|
|
854 |
|
|
if (s_flags & MS_RDONLY) {
|
855 |
|
|
printk(KERN_INFO "EXT3-fs: %s: orphan cleanup on readonly fs\n",
|
856 |
|
|
bdevname(sb->s_dev));
|
857 |
|
|
sb->s_flags &= ~MS_RDONLY;
|
858 |
|
|
}
|
859 |
|
|
|
860 |
|
|
while (es->s_last_orphan) {
|
861 |
|
|
struct inode *inode;
|
862 |
|
|
|
863 |
|
|
if (!(inode =
|
864 |
|
|
ext3_orphan_get(sb, le32_to_cpu(es->s_last_orphan)))) {
|
865 |
|
|
es->s_last_orphan = 0;
|
866 |
|
|
break;
|
867 |
|
|
}
|
868 |
|
|
|
869 |
|
|
list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
|
870 |
|
|
if (inode->i_nlink) {
|
871 |
|
|
printk(KERN_DEBUG "%s: truncating inode %ld to %Ld "
|
872 |
|
|
"bytes\n", __FUNCTION__, inode->i_ino,
|
873 |
|
|
inode->i_size);
|
874 |
|
|
jbd_debug(2, "truncating inode %ld to %Ld bytes\n",
|
875 |
|
|
inode->i_ino, inode->i_size);
|
876 |
|
|
ext3_truncate(inode);
|
877 |
|
|
nr_truncates++;
|
878 |
|
|
} else {
|
879 |
|
|
printk(KERN_DEBUG "%s: deleting unreferenced "
|
880 |
|
|
"inode %ld\n", __FUNCTION__, inode->i_ino);
|
881 |
|
|
jbd_debug(2, "deleting unreferenced inode %ld\n",
|
882 |
|
|
inode->i_ino);
|
883 |
|
|
nr_orphans++;
|
884 |
|
|
}
|
885 |
|
|
iput(inode); /* The delete magic happens here! */
|
886 |
|
|
}
|
887 |
|
|
|
888 |
|
|
#define PLURAL(x) (x), ((x)==1) ? "" : "s"
|
889 |
|
|
|
890 |
|
|
if (nr_orphans)
|
891 |
|
|
printk(KERN_INFO "EXT3-fs: %s: %d orphan inode%s deleted\n",
|
892 |
|
|
bdevname(sb->s_dev), PLURAL(nr_orphans));
|
893 |
|
|
if (nr_truncates)
|
894 |
|
|
printk(KERN_INFO "EXT3-fs: %s: %d truncate%s cleaned up\n",
|
895 |
|
|
bdevname(sb->s_dev), PLURAL(nr_truncates));
|
896 |
|
|
sb->s_flags = s_flags; /* Restore MS_RDONLY status */
|
897 |
|
|
}
|
898 |
|
|
|
899 |
|
|
#define log2(n) ffz(~(n))
|
900 |
|
|
|
901 |
|
|
/*
|
902 |
|
|
* Maximal file size. There is a direct, and {,double-,triple-}indirect
|
903 |
|
|
* block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
|
904 |
|
|
* We need to be 1 filesystem block less than the 2^32 sector limit.
|
905 |
|
|
*/
|
906 |
|
|
static loff_t ext3_max_size(int bits)
|
907 |
|
|
{
|
908 |
|
|
loff_t res = EXT3_NDIR_BLOCKS;
|
909 |
|
|
res += 1LL << (bits-2);
|
910 |
|
|
res += 1LL << (2*(bits-2));
|
911 |
|
|
res += 1LL << (3*(bits-2));
|
912 |
|
|
res <<= bits;
|
913 |
|
|
if (res > (512LL << 32) - (1 << bits))
|
914 |
|
|
res = (512LL << 32) - (1 << bits);
|
915 |
|
|
return res;
|
916 |
|
|
}
|
917 |
|
|
|
918 |
|
|
struct super_block * ext3_read_super (struct super_block * sb, void * data,
|
919 |
|
|
int silent)
|
920 |
|
|
{
|
921 |
|
|
struct buffer_head * bh;
|
922 |
|
|
struct ext3_super_block *es = 0;
|
923 |
|
|
struct ext3_sb_info *sbi = EXT3_SB(sb);
|
924 |
|
|
unsigned long block;
|
925 |
|
|
unsigned long sb_block = 1;
|
926 |
|
|
unsigned long logic_sb_block = 1;
|
927 |
|
|
unsigned long offset = 0;
|
928 |
|
|
unsigned long journal_inum = 0;
|
929 |
|
|
kdev_t dev = sb->s_dev;
|
930 |
|
|
int blocksize;
|
931 |
|
|
int hblock;
|
932 |
|
|
int db_count;
|
933 |
|
|
int i;
|
934 |
|
|
int needs_recovery;
|
935 |
|
|
|
936 |
|
|
#ifdef CONFIG_JBD_DEBUG
|
937 |
|
|
ext3_ro_after = 0;
|
938 |
|
|
#endif
|
939 |
|
|
/*
|
940 |
|
|
* See what the current blocksize for the device is, and
|
941 |
|
|
* use that as the blocksize. Otherwise (or if the blocksize
|
942 |
|
|
* is smaller than the default) use the default.
|
943 |
|
|
* This is important for devices that have a hardware
|
944 |
|
|
* sectorsize that is larger than the default.
|
945 |
|
|
*/
|
946 |
|
|
blocksize = EXT3_MIN_BLOCK_SIZE;
|
947 |
|
|
hblock = get_hardsect_size(dev);
|
948 |
|
|
if (blocksize < hblock)
|
949 |
|
|
blocksize = hblock;
|
950 |
|
|
|
951 |
|
|
sbi->s_mount_opt = 0;
|
952 |
|
|
sbi->s_resuid = EXT3_DEF_RESUID;
|
953 |
|
|
sbi->s_resgid = EXT3_DEF_RESGID;
|
954 |
|
|
if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
|
955 |
|
|
sb->s_dev = 0;
|
956 |
|
|
goto out_fail;
|
957 |
|
|
}
|
958 |
|
|
|
959 |
|
|
sb->s_blocksize = blocksize;
|
960 |
|
|
set_blocksize (dev, blocksize);
|
961 |
|
|
|
962 |
|
|
/*
|
963 |
|
|
* The ext3 superblock will not be buffer aligned for other than 1kB
|
964 |
|
|
* block sizes. We need to calculate the offset from buffer start.
|
965 |
|
|
*/
|
966 |
|
|
if (blocksize != EXT3_MIN_BLOCK_SIZE) {
|
967 |
|
|
logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
|
968 |
|
|
offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
|
969 |
|
|
}
|
970 |
|
|
|
971 |
|
|
if (!(bh = sb_bread(sb, logic_sb_block))) {
|
972 |
|
|
printk (KERN_ERR "EXT3-fs: unable to read superblock\n");
|
973 |
|
|
goto out_fail;
|
974 |
|
|
}
|
975 |
|
|
/*
|
976 |
|
|
* Note: s_es must be initialized as soon as possible because
|
977 |
|
|
* some ext3 macro-instructions depend on its value
|
978 |
|
|
*/
|
979 |
|
|
es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);
|
980 |
|
|
sbi->s_es = es;
|
981 |
|
|
sb->s_magic = le16_to_cpu(es->s_magic);
|
982 |
|
|
if (sb->s_magic != EXT3_SUPER_MAGIC) {
|
983 |
|
|
if (!silent)
|
984 |
|
|
printk(KERN_ERR
|
985 |
|
|
"VFS: Can't find ext3 filesystem on dev %s.\n",
|
986 |
|
|
bdevname(dev));
|
987 |
|
|
goto failed_mount;
|
988 |
|
|
}
|
989 |
|
|
if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&
|
990 |
|
|
(EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
|
991 |
|
|
EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
|
992 |
|
|
EXT3_HAS_INCOMPAT_FEATURE(sb, ~0U)))
|
993 |
|
|
printk(KERN_WARNING
|
994 |
|
|
"EXT3-fs warning: feature flags set on rev 0 fs, "
|
995 |
|
|
"running e2fsck is recommended\n");
|
996 |
|
|
/*
|
997 |
|
|
* Check feature flags regardless of the revision level, since we
|
998 |
|
|
* previously didn't change the revision level when setting the flags,
|
999 |
|
|
* so there is a chance incompat flags are set on a rev 0 filesystem.
|
1000 |
|
|
*/
|
1001 |
|
|
if ((i = EXT3_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP))) {
|
1002 |
|
|
printk(KERN_ERR "EXT3-fs: %s: couldn't mount because of "
|
1003 |
|
|
"unsupported optional features (%x).\n",
|
1004 |
|
|
bdevname(dev), i);
|
1005 |
|
|
goto failed_mount;
|
1006 |
|
|
}
|
1007 |
|
|
if (!(sb->s_flags & MS_RDONLY) &&
|
1008 |
|
|
(i = EXT3_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP))){
|
1009 |
|
|
printk(KERN_ERR "EXT3-fs: %s: couldn't mount RDWR because of "
|
1010 |
|
|
"unsupported optional features (%x).\n",
|
1011 |
|
|
bdevname(dev), i);
|
1012 |
|
|
goto failed_mount;
|
1013 |
|
|
}
|
1014 |
|
|
sb->s_blocksize_bits = le32_to_cpu(es->s_log_block_size) + 10;
|
1015 |
|
|
sb->s_blocksize = 1 << sb->s_blocksize_bits;
|
1016 |
|
|
|
1017 |
|
|
if (sb->s_blocksize < EXT3_MIN_BLOCK_SIZE ||
|
1018 |
|
|
sb->s_blocksize > EXT3_MAX_BLOCK_SIZE) {
|
1019 |
|
|
printk(KERN_ERR
|
1020 |
|
|
"EXT3-fs: Unsupported filesystem blocksize %d on %s.\n",
|
1021 |
|
|
blocksize, bdevname(dev));
|
1022 |
|
|
goto failed_mount;
|
1023 |
|
|
}
|
1024 |
|
|
|
1025 |
|
|
sb->s_maxbytes = ext3_max_size(sb->s_blocksize_bits);
|
1026 |
|
|
|
1027 |
|
|
if (sb->s_blocksize != blocksize) {
|
1028 |
|
|
blocksize = sb->s_blocksize;
|
1029 |
|
|
|
1030 |
|
|
/*
|
1031 |
|
|
* Make sure the blocksize for the filesystem is larger
|
1032 |
|
|
* than the hardware sectorsize for the machine.
|
1033 |
|
|
*/
|
1034 |
|
|
if (sb->s_blocksize < hblock) {
|
1035 |
|
|
printk(KERN_ERR "EXT3-fs: blocksize %d too small for "
|
1036 |
|
|
"device blocksize %d.\n", blocksize, hblock);
|
1037 |
|
|
goto failed_mount;
|
1038 |
|
|
}
|
1039 |
|
|
|
1040 |
|
|
brelse (bh);
|
1041 |
|
|
set_blocksize (dev, sb->s_blocksize);
|
1042 |
|
|
logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
|
1043 |
|
|
offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
|
1044 |
|
|
bh = sb_bread(sb, logic_sb_block);
|
1045 |
|
|
if (!bh) {
|
1046 |
|
|
printk(KERN_ERR
|
1047 |
|
|
"EXT3-fs: Can't read superblock on 2nd try.\n");
|
1048 |
|
|
return NULL;
|
1049 |
|
|
}
|
1050 |
|
|
es = (struct ext3_super_block *)(((char *)bh->b_data) + offset);
|
1051 |
|
|
sbi->s_es = es;
|
1052 |
|
|
if (es->s_magic != le16_to_cpu(EXT3_SUPER_MAGIC)) {
|
1053 |
|
|
printk (KERN_ERR
|
1054 |
|
|
"EXT3-fs: Magic mismatch, very weird !\n");
|
1055 |
|
|
goto failed_mount;
|
1056 |
|
|
}
|
1057 |
|
|
}
|
1058 |
|
|
|
1059 |
|
|
if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV) {
|
1060 |
|
|
sbi->s_inode_size = EXT3_GOOD_OLD_INODE_SIZE;
|
1061 |
|
|
sbi->s_first_ino = EXT3_GOOD_OLD_FIRST_INO;
|
1062 |
|
|
} else {
|
1063 |
|
|
sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
|
1064 |
|
|
sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
|
1065 |
|
|
if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
|
1066 |
|
|
(sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
|
1067 |
|
|
(sbi->s_inode_size > blocksize)) {
|
1068 |
|
|
printk (KERN_ERR
|
1069 |
|
|
"EXT3-fs: unsupported inode size: %d\n",
|
1070 |
|
|
sbi->s_inode_size);
|
1071 |
|
|
goto failed_mount;
|
1072 |
|
|
}
|
1073 |
|
|
}
|
1074 |
|
|
sbi->s_frag_size = EXT3_MIN_FRAG_SIZE <<
|
1075 |
|
|
le32_to_cpu(es->s_log_frag_size);
|
1076 |
|
|
if (blocksize != sbi->s_frag_size) {
|
1077 |
|
|
printk(KERN_ERR
|
1078 |
|
|
"EXT3-fs: fragsize %lu != blocksize %u (unsupported)\n",
|
1079 |
|
|
sbi->s_frag_size, blocksize);
|
1080 |
|
|
goto failed_mount;
|
1081 |
|
|
}
|
1082 |
|
|
sbi->s_frags_per_block = 1;
|
1083 |
|
|
sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
|
1084 |
|
|
sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
|
1085 |
|
|
sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
|
1086 |
|
|
sbi->s_inodes_per_block = blocksize / EXT3_INODE_SIZE(sb);
|
1087 |
|
|
sbi->s_itb_per_group = sbi->s_inodes_per_group /sbi->s_inodes_per_block;
|
1088 |
|
|
sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);
|
1089 |
|
|
sbi->s_sbh = bh;
|
1090 |
|
|
if (sbi->s_resuid == EXT3_DEF_RESUID)
|
1091 |
|
|
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
|
1092 |
|
|
if (sbi->s_resgid == EXT3_DEF_RESGID)
|
1093 |
|
|
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
|
1094 |
|
|
sbi->s_mount_state = le16_to_cpu(es->s_state);
|
1095 |
|
|
sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
|
1096 |
|
|
sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
|
1097 |
|
|
|
1098 |
|
|
if (sbi->s_blocks_per_group > blocksize * 8) {
|
1099 |
|
|
printk (KERN_ERR
|
1100 |
|
|
"EXT3-fs: #blocks per group too big: %lu\n",
|
1101 |
|
|
sbi->s_blocks_per_group);
|
1102 |
|
|
goto failed_mount;
|
1103 |
|
|
}
|
1104 |
|
|
if (sbi->s_frags_per_group > blocksize * 8) {
|
1105 |
|
|
printk (KERN_ERR
|
1106 |
|
|
"EXT3-fs: #fragments per group too big: %lu\n",
|
1107 |
|
|
sbi->s_frags_per_group);
|
1108 |
|
|
goto failed_mount;
|
1109 |
|
|
}
|
1110 |
|
|
if (sbi->s_inodes_per_group > blocksize * 8) {
|
1111 |
|
|
printk (KERN_ERR
|
1112 |
|
|
"EXT3-fs: #inodes per group too big: %lu\n",
|
1113 |
|
|
sbi->s_inodes_per_group);
|
1114 |
|
|
goto failed_mount;
|
1115 |
|
|
}
|
1116 |
|
|
|
1117 |
|
|
sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
|
1118 |
|
|
le32_to_cpu(es->s_first_data_block) +
|
1119 |
|
|
EXT3_BLOCKS_PER_GROUP(sb) - 1) /
|
1120 |
|
|
EXT3_BLOCKS_PER_GROUP(sb);
|
1121 |
|
|
db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) /
|
1122 |
|
|
EXT3_DESC_PER_BLOCK(sb);
|
1123 |
|
|
sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
|
1124 |
|
|
GFP_KERNEL);
|
1125 |
|
|
if (sbi->s_group_desc == NULL) {
|
1126 |
|
|
printk (KERN_ERR "EXT3-fs: not enough memory\n");
|
1127 |
|
|
goto failed_mount;
|
1128 |
|
|
}
|
1129 |
|
|
for (i = 0; i < db_count; i++) {
|
1130 |
|
|
block = descriptor_loc(sb, logic_sb_block, i);
|
1131 |
|
|
sbi->s_group_desc[i] = sb_bread(sb, block);
|
1132 |
|
|
if (!sbi->s_group_desc[i]) {
|
1133 |
|
|
printk (KERN_ERR "EXT3-fs: "
|
1134 |
|
|
"can't read group descriptor %d\n", i);
|
1135 |
|
|
db_count = i;
|
1136 |
|
|
goto failed_mount2;
|
1137 |
|
|
}
|
1138 |
|
|
}
|
1139 |
|
|
if (!ext3_check_descriptors (sb)) {
|
1140 |
|
|
printk (KERN_ERR "EXT3-fs: group descriptors corrupted !\n");
|
1141 |
|
|
goto failed_mount2;
|
1142 |
|
|
}
|
1143 |
|
|
for (i = 0; i < EXT3_MAX_GROUP_LOADED; i++) {
|
1144 |
|
|
sbi->s_inode_bitmap_number[i] = 0;
|
1145 |
|
|
sbi->s_inode_bitmap[i] = NULL;
|
1146 |
|
|
sbi->s_block_bitmap_number[i] = 0;
|
1147 |
|
|
sbi->s_block_bitmap[i] = NULL;
|
1148 |
|
|
}
|
1149 |
|
|
sbi->s_loaded_inode_bitmaps = 0;
|
1150 |
|
|
sbi->s_loaded_block_bitmaps = 0;
|
1151 |
|
|
sbi->s_gdb_count = db_count;
|
1152 |
|
|
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
|
1153 |
|
|
/*
|
1154 |
|
|
* set up enough so that it can read an inode
|
1155 |
|
|
*/
|
1156 |
|
|
sb->s_op = &ext3_sops;
|
1157 |
|
|
sb->dq_op = &ext3_qops;
|
1158 |
|
|
INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
|
1159 |
|
|
|
1160 |
|
|
sb->s_root = 0;
|
1161 |
|
|
|
1162 |
|
|
needs_recovery = (es->s_last_orphan != 0 ||
|
1163 |
|
|
EXT3_HAS_INCOMPAT_FEATURE(sb,
|
1164 |
|
|
EXT3_FEATURE_INCOMPAT_RECOVER));
|
1165 |
|
|
|
1166 |
|
|
/*
|
1167 |
|
|
* The first inode we look at is the journal inode. Don't try
|
1168 |
|
|
* root first: it may be modified in the journal!
|
1169 |
|
|
*/
|
1170 |
|
|
if (!test_opt(sb, NOLOAD) &&
|
1171 |
|
|
EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
|
1172 |
|
|
if (ext3_load_journal(sb, es))
|
1173 |
|
|
goto failed_mount2;
|
1174 |
|
|
} else if (journal_inum) {
|
1175 |
|
|
if (ext3_create_journal(sb, es, journal_inum))
|
1176 |
|
|
goto failed_mount2;
|
1177 |
|
|
} else {
|
1178 |
|
|
if (!silent)
|
1179 |
|
|
printk (KERN_ERR
|
1180 |
|
|
"ext3: No journal on filesystem on %s\n",
|
1181 |
|
|
bdevname(dev));
|
1182 |
|
|
goto failed_mount2;
|
1183 |
|
|
}
|
1184 |
|
|
|
1185 |
|
|
/* We have now updated the journal if required, so we can
|
1186 |
|
|
* validate the data journaling mode. */
|
1187 |
|
|
switch (test_opt(sb, DATA_FLAGS)) {
|
1188 |
|
|
case 0:
|
1189 |
|
|
/* No mode set, assume a default based on the journal
|
1190 |
|
|
capabilities: ORDERED_DATA if the journal can
|
1191 |
|
|
cope, else JOURNAL_DATA */
|
1192 |
|
|
if (journal_check_available_features
|
1193 |
|
|
(sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE))
|
1194 |
|
|
set_opt(sbi->s_mount_opt, ORDERED_DATA);
|
1195 |
|
|
else
|
1196 |
|
|
set_opt(sbi->s_mount_opt, JOURNAL_DATA);
|
1197 |
|
|
break;
|
1198 |
|
|
|
1199 |
|
|
case EXT3_MOUNT_ORDERED_DATA:
|
1200 |
|
|
case EXT3_MOUNT_WRITEBACK_DATA:
|
1201 |
|
|
if (!journal_check_available_features
|
1202 |
|
|
(sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)) {
|
1203 |
|
|
printk(KERN_ERR "EXT3-fs: Journal does not support "
|
1204 |
|
|
"requested data journaling mode\n");
|
1205 |
|
|
goto failed_mount3;
|
1206 |
|
|
}
|
1207 |
|
|
default:
|
1208 |
|
|
break;
|
1209 |
|
|
}
|
1210 |
|
|
|
1211 |
|
|
/*
|
1212 |
|
|
* The journal_load will have done any necessary log recovery,
|
1213 |
|
|
* so we can safely mount the rest of the filesystem now.
|
1214 |
|
|
*/
|
1215 |
|
|
|
1216 |
|
|
sb->s_root = d_alloc_root(iget(sb, EXT3_ROOT_INO));
|
1217 |
|
|
if (!sb->s_root || !S_ISDIR(sb->s_root->d_inode->i_mode) ||
|
1218 |
|
|
!sb->s_root->d_inode->i_blocks || !sb->s_root->d_inode->i_size) {
|
1219 |
|
|
if (sb->s_root) {
|
1220 |
|
|
dput(sb->s_root);
|
1221 |
|
|
sb->s_root = NULL;
|
1222 |
|
|
printk(KERN_ERR
|
1223 |
|
|
"EXT3-fs: corrupt root inode, run e2fsck\n");
|
1224 |
|
|
} else
|
1225 |
|
|
printk(KERN_ERR "EXT3-fs: get root inode failed\n");
|
1226 |
|
|
goto failed_mount3;
|
1227 |
|
|
}
|
1228 |
|
|
|
1229 |
|
|
ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
|
1230 |
|
|
/*
|
1231 |
|
|
* akpm: core read_super() calls in here with the superblock locked.
|
1232 |
|
|
* That deadlocks, because orphan cleanup needs to lock the superblock
|
1233 |
|
|
* in numerous places. Here we just pop the lock - it's relatively
|
1234 |
|
|
* harmless, because we are now ready to accept write_super() requests,
|
1235 |
|
|
* and aviro says that's the only reason for hanging onto the
|
1236 |
|
|
* superblock lock.
|
1237 |
|
|
*/
|
1238 |
|
|
EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS;
|
1239 |
|
|
unlock_super(sb); /* akpm: sigh */
|
1240 |
|
|
ext3_orphan_cleanup(sb, es);
|
1241 |
|
|
lock_super(sb);
|
1242 |
|
|
EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS;
|
1243 |
|
|
if (needs_recovery)
|
1244 |
|
|
printk (KERN_INFO "EXT3-fs: recovery complete.\n");
|
1245 |
|
|
ext3_mark_recovery_complete(sb, es);
|
1246 |
|
|
printk (KERN_INFO "EXT3-fs: mounted filesystem with %s data mode.\n",
|
1247 |
|
|
test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
|
1248 |
|
|
test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
|
1249 |
|
|
"writeback");
|
1250 |
|
|
|
1251 |
|
|
return sb;
|
1252 |
|
|
|
1253 |
|
|
failed_mount3:
|
1254 |
|
|
journal_destroy(sbi->s_journal);
|
1255 |
|
|
failed_mount2:
|
1256 |
|
|
for (i = 0; i < db_count; i++)
|
1257 |
|
|
brelse(sbi->s_group_desc[i]);
|
1258 |
|
|
kfree(sbi->s_group_desc);
|
1259 |
|
|
failed_mount:
|
1260 |
|
|
ext3_blkdev_remove(sbi);
|
1261 |
|
|
brelse(bh);
|
1262 |
|
|
out_fail:
|
1263 |
|
|
return NULL;
|
1264 |
|
|
}
|
1265 |
|
|
|
1266 |
|
|
/*
|
1267 |
|
|
* Setup any per-fs journal parameters now. We'll do this both on
|
1268 |
|
|
* initial mount, once the journal has been initialised but before we've
|
1269 |
|
|
* done any recovery; and again on any subsequent remount.
|
1270 |
|
|
*/
|
1271 |
|
|
static void ext3_init_journal_params(struct ext3_sb_info *sbi,
|
1272 |
|
|
journal_t *journal)
|
1273 |
|
|
{
|
1274 |
|
|
if (sbi->s_commit_interval)
|
1275 |
|
|
journal->j_commit_interval = sbi->s_commit_interval;
|
1276 |
|
|
/* We could also set up an ext3-specific default for the commit
|
1277 |
|
|
* interval here, but for now we'll just fall back to the jbd
|
1278 |
|
|
* default. */
|
1279 |
|
|
}
|
1280 |
|
|
|
1281 |
|
|
|
1282 |
|
|
static journal_t *ext3_get_journal(struct super_block *sb, int journal_inum)
|
1283 |
|
|
{
|
1284 |
|
|
struct inode *journal_inode;
|
1285 |
|
|
journal_t *journal;
|
1286 |
|
|
|
1287 |
|
|
/* First, test for the existence of a valid inode on disk. Bad
|
1288 |
|
|
* things happen if we iget() an unused inode, as the subsequent
|
1289 |
|
|
* iput() will try to delete it. */
|
1290 |
|
|
|
1291 |
|
|
journal_inode = iget(sb, journal_inum);
|
1292 |
|
|
if (!journal_inode) {
|
1293 |
|
|
printk(KERN_ERR "EXT3-fs: no journal found.\n");
|
1294 |
|
|
return NULL;
|
1295 |
|
|
}
|
1296 |
|
|
if (!journal_inode->i_nlink) {
|
1297 |
|
|
make_bad_inode(journal_inode);
|
1298 |
|
|
iput(journal_inode);
|
1299 |
|
|
printk(KERN_ERR "EXT3-fs: journal inode is deleted.\n");
|
1300 |
|
|
return NULL;
|
1301 |
|
|
}
|
1302 |
|
|
|
1303 |
|
|
jbd_debug(2, "Journal inode found at %p: %Ld bytes\n",
|
1304 |
|
|
journal_inode, journal_inode->i_size);
|
1305 |
|
|
if (is_bad_inode(journal_inode) || !S_ISREG(journal_inode->i_mode)) {
|
1306 |
|
|
printk(KERN_ERR "EXT3-fs: invalid journal inode.\n");
|
1307 |
|
|
iput(journal_inode);
|
1308 |
|
|
return NULL;
|
1309 |
|
|
}
|
1310 |
|
|
|
1311 |
|
|
journal = journal_init_inode(journal_inode);
|
1312 |
|
|
if (!journal) {
|
1313 |
|
|
printk(KERN_ERR "EXT3-fs: Could not load journal inode\n");
|
1314 |
|
|
iput(journal_inode);
|
1315 |
|
|
}
|
1316 |
|
|
ext3_init_journal_params(EXT3_SB(sb), journal);
|
1317 |
|
|
return journal;
|
1318 |
|
|
}
|
1319 |
|
|
|
1320 |
|
|
static journal_t *ext3_get_dev_journal(struct super_block *sb,
|
1321 |
|
|
int dev)
|
1322 |
|
|
{
|
1323 |
|
|
struct buffer_head * bh;
|
1324 |
|
|
journal_t *journal;
|
1325 |
|
|
int start;
|
1326 |
|
|
int len;
|
1327 |
|
|
int hblock, blocksize;
|
1328 |
|
|
unsigned long sb_block;
|
1329 |
|
|
unsigned long offset;
|
1330 |
|
|
kdev_t journal_dev = to_kdev_t(dev);
|
1331 |
|
|
struct ext3_super_block * es;
|
1332 |
|
|
struct block_device *bdev;
|
1333 |
|
|
|
1334 |
|
|
bdev = ext3_blkdev_get(journal_dev);
|
1335 |
|
|
if (bdev == NULL)
|
1336 |
|
|
return NULL;
|
1337 |
|
|
|
1338 |
|
|
blocksize = sb->s_blocksize;
|
1339 |
|
|
hblock = get_hardsect_size(journal_dev);
|
1340 |
|
|
if (blocksize < hblock) {
|
1341 |
|
|
printk(KERN_ERR
|
1342 |
|
|
"EXT3-fs: blocksize too small for journal device.\n");
|
1343 |
|
|
goto out_bdev;
|
1344 |
|
|
}
|
1345 |
|
|
|
1346 |
|
|
sb_block = EXT3_MIN_BLOCK_SIZE / blocksize;
|
1347 |
|
|
offset = EXT3_MIN_BLOCK_SIZE % blocksize;
|
1348 |
|
|
set_blocksize(dev, blocksize);
|
1349 |
|
|
if (!(bh = bread(dev, sb_block, blocksize))) {
|
1350 |
|
|
printk(KERN_ERR "EXT3-fs: couldn't read superblock of "
|
1351 |
|
|
"external journal\n");
|
1352 |
|
|
goto out_bdev;
|
1353 |
|
|
}
|
1354 |
|
|
|
1355 |
|
|
es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);
|
1356 |
|
|
if ((le16_to_cpu(es->s_magic) != EXT3_SUPER_MAGIC) ||
|
1357 |
|
|
!(le32_to_cpu(es->s_feature_incompat) &
|
1358 |
|
|
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
|
1359 |
|
|
printk(KERN_ERR "EXT3-fs: external journal has "
|
1360 |
|
|
"bad superblock\n");
|
1361 |
|
|
brelse(bh);
|
1362 |
|
|
goto out_bdev;
|
1363 |
|
|
}
|
1364 |
|
|
|
1365 |
|
|
if (memcmp(EXT3_SB(sb)->s_es->s_journal_uuid, es->s_uuid, 16)) {
|
1366 |
|
|
printk(KERN_ERR "EXT3-fs: journal UUID does not match\n");
|
1367 |
|
|
brelse(bh);
|
1368 |
|
|
goto out_bdev;
|
1369 |
|
|
}
|
1370 |
|
|
|
1371 |
|
|
len = le32_to_cpu(es->s_blocks_count);
|
1372 |
|
|
start = sb_block + 1;
|
1373 |
|
|
brelse(bh); /* we're done with the superblock */
|
1374 |
|
|
|
1375 |
|
|
journal = journal_init_dev(journal_dev, sb->s_dev,
|
1376 |
|
|
start, len, blocksize);
|
1377 |
|
|
if (!journal) {
|
1378 |
|
|
printk(KERN_ERR "EXT3-fs: failed to create device journal\n");
|
1379 |
|
|
goto out_bdev;
|
1380 |
|
|
}
|
1381 |
|
|
ll_rw_block(READ, 1, &journal->j_sb_buffer);
|
1382 |
|
|
wait_on_buffer(journal->j_sb_buffer);
|
1383 |
|
|
if (!buffer_uptodate(journal->j_sb_buffer)) {
|
1384 |
|
|
printk(KERN_ERR "EXT3-fs: I/O error on journal device\n");
|
1385 |
|
|
goto out_journal;
|
1386 |
|
|
}
|
1387 |
|
|
if (ntohl(journal->j_superblock->s_nr_users) != 1) {
|
1388 |
|
|
printk(KERN_ERR "EXT3-fs: External journal has more than one "
|
1389 |
|
|
"user (unsupported) - %d\n",
|
1390 |
|
|
ntohl(journal->j_superblock->s_nr_users));
|
1391 |
|
|
goto out_journal;
|
1392 |
|
|
}
|
1393 |
|
|
EXT3_SB(sb)->journal_bdev = bdev;
|
1394 |
|
|
ext3_init_journal_params(EXT3_SB(sb), journal);
|
1395 |
|
|
return journal;
|
1396 |
|
|
out_journal:
|
1397 |
|
|
journal_destroy(journal);
|
1398 |
|
|
out_bdev:
|
1399 |
|
|
ext3_blkdev_put(bdev);
|
1400 |
|
|
return NULL;
|
1401 |
|
|
}
|
1402 |
|
|
|
1403 |
|
|
static int ext3_load_journal(struct super_block * sb,
|
1404 |
|
|
struct ext3_super_block * es)
|
1405 |
|
|
{
|
1406 |
|
|
journal_t *journal;
|
1407 |
|
|
int journal_inum = le32_to_cpu(es->s_journal_inum);
|
1408 |
|
|
int journal_dev = le32_to_cpu(es->s_journal_dev);
|
1409 |
|
|
int err = 0;
|
1410 |
|
|
int really_read_only;
|
1411 |
|
|
|
1412 |
|
|
really_read_only = is_read_only(sb->s_dev);
|
1413 |
|
|
|
1414 |
|
|
/*
|
1415 |
|
|
* Are we loading a blank journal or performing recovery after a
|
1416 |
|
|
* crash? For recovery, we need to check in advance whether we
|
1417 |
|
|
* can get read-write access to the device.
|
1418 |
|
|
*/
|
1419 |
|
|
|
1420 |
|
|
if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER)) {
|
1421 |
|
|
if (sb->s_flags & MS_RDONLY) {
|
1422 |
|
|
printk(KERN_INFO "EXT3-fs: INFO: recovery "
|
1423 |
|
|
"required on readonly filesystem.\n");
|
1424 |
|
|
if (really_read_only) {
|
1425 |
|
|
printk(KERN_ERR "EXT3-fs: write access "
|
1426 |
|
|
"unavailable, cannot proceed.\n");
|
1427 |
|
|
return -EROFS;
|
1428 |
|
|
}
|
1429 |
|
|
printk (KERN_INFO "EXT3-fs: write access will "
|
1430 |
|
|
"be enabled during recovery.\n");
|
1431 |
|
|
}
|
1432 |
|
|
}
|
1433 |
|
|
|
1434 |
|
|
if (journal_inum && journal_dev) {
|
1435 |
|
|
printk(KERN_ERR "EXT3-fs: filesystem has both journal "
|
1436 |
|
|
"and inode journals!\n");
|
1437 |
|
|
return -EINVAL;
|
1438 |
|
|
}
|
1439 |
|
|
|
1440 |
|
|
if (journal_inum) {
|
1441 |
|
|
if (!(journal = ext3_get_journal(sb, journal_inum)))
|
1442 |
|
|
return -EINVAL;
|
1443 |
|
|
} else {
|
1444 |
|
|
if (!(journal = ext3_get_dev_journal(sb, journal_dev)))
|
1445 |
|
|
return -EINVAL;
|
1446 |
|
|
}
|
1447 |
|
|
|
1448 |
|
|
|
1449 |
|
|
if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
|
1450 |
|
|
err = journal_update_format(journal);
|
1451 |
|
|
if (err) {
|
1452 |
|
|
printk(KERN_ERR "EXT3-fs: error updating journal.\n");
|
1453 |
|
|
journal_destroy(journal);
|
1454 |
|
|
return err;
|
1455 |
|
|
}
|
1456 |
|
|
}
|
1457 |
|
|
|
1458 |
|
|
if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER))
|
1459 |
|
|
err = journal_wipe(journal, !really_read_only);
|
1460 |
|
|
if (!err)
|
1461 |
|
|
err = journal_load(journal);
|
1462 |
|
|
|
1463 |
|
|
if (err) {
|
1464 |
|
|
printk(KERN_ERR "EXT3-fs: error loading journal.\n");
|
1465 |
|
|
journal_destroy(journal);
|
1466 |
|
|
return err;
|
1467 |
|
|
}
|
1468 |
|
|
|
1469 |
|
|
EXT3_SB(sb)->s_journal = journal;
|
1470 |
|
|
ext3_clear_journal_err(sb, es);
|
1471 |
|
|
return 0;
|
1472 |
|
|
}
|
1473 |
|
|
|
1474 |
|
|
static int ext3_create_journal(struct super_block * sb,
|
1475 |
|
|
struct ext3_super_block * es,
|
1476 |
|
|
int journal_inum)
|
1477 |
|
|
{
|
1478 |
|
|
journal_t *journal;
|
1479 |
|
|
|
1480 |
|
|
if (sb->s_flags & MS_RDONLY) {
|
1481 |
|
|
printk(KERN_ERR "EXT3-fs: readonly filesystem when trying to "
|
1482 |
|
|
"create journal.\n");
|
1483 |
|
|
return -EROFS;
|
1484 |
|
|
}
|
1485 |
|
|
|
1486 |
|
|
if (!(journal = ext3_get_journal(sb, journal_inum)))
|
1487 |
|
|
return -EINVAL;
|
1488 |
|
|
|
1489 |
|
|
printk(KERN_INFO "EXT3-fs: creating new journal on inode %d\n",
|
1490 |
|
|
journal_inum);
|
1491 |
|
|
|
1492 |
|
|
if (journal_create(journal)) {
|
1493 |
|
|
printk(KERN_ERR "EXT3-fs: error creating journal.\n");
|
1494 |
|
|
journal_destroy(journal);
|
1495 |
|
|
return -EIO;
|
1496 |
|
|
}
|
1497 |
|
|
|
1498 |
|
|
EXT3_SB(sb)->s_journal = journal;
|
1499 |
|
|
|
1500 |
|
|
ext3_update_dynamic_rev(sb);
|
1501 |
|
|
EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
|
1502 |
|
|
EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL);
|
1503 |
|
|
|
1504 |
|
|
es->s_journal_inum = cpu_to_le32(journal_inum);
|
1505 |
|
|
sb->s_dirt = 1;
|
1506 |
|
|
|
1507 |
|
|
/* Make sure we flush the recovery flag to disk. */
|
1508 |
|
|
ext3_commit_super(sb, es, 1);
|
1509 |
|
|
|
1510 |
|
|
return 0;
|
1511 |
|
|
}
|
1512 |
|
|
|
1513 |
|
|
static void ext3_commit_super (struct super_block * sb,
|
1514 |
|
|
struct ext3_super_block * es,
|
1515 |
|
|
int sync)
|
1516 |
|
|
{
|
1517 |
|
|
es->s_wtime = cpu_to_le32(CURRENT_TIME);
|
1518 |
|
|
BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "marking dirty");
|
1519 |
|
|
mark_buffer_dirty(sb->u.ext3_sb.s_sbh);
|
1520 |
|
|
if (sync) {
|
1521 |
|
|
ll_rw_block(WRITE, 1, &sb->u.ext3_sb.s_sbh);
|
1522 |
|
|
wait_on_buffer(sb->u.ext3_sb.s_sbh);
|
1523 |
|
|
}
|
1524 |
|
|
}
|
1525 |
|
|
|
1526 |
|
|
|
1527 |
|
|
/*
|
1528 |
|
|
* Have we just finished recovery? If so, and if we are mounting (or
|
1529 |
|
|
* remounting) the filesystem readonly, then we will end up with a
|
1530 |
|
|
* consistent fs on disk. Record that fact.
|
1531 |
|
|
*/
|
1532 |
|
|
static void ext3_mark_recovery_complete(struct super_block * sb,
|
1533 |
|
|
struct ext3_super_block * es)
|
1534 |
|
|
{
|
1535 |
|
|
journal_flush(EXT3_SB(sb)->s_journal);
|
1536 |
|
|
if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
|
1537 |
|
|
sb->s_flags & MS_RDONLY) {
|
1538 |
|
|
EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
|
1539 |
|
|
sb->s_dirt = 0;
|
1540 |
|
|
ext3_commit_super(sb, es, 1);
|
1541 |
|
|
}
|
1542 |
|
|
}
|
1543 |
|
|
|
1544 |
|
|
/*
|
1545 |
|
|
* If we are mounting (or read-write remounting) a filesystem whose journal
|
1546 |
|
|
* has recorded an error from a previous lifetime, move that error to the
|
1547 |
|
|
* main filesystem now.
|
1548 |
|
|
*/
|
1549 |
|
|
static void ext3_clear_journal_err(struct super_block * sb,
|
1550 |
|
|
struct ext3_super_block * es)
|
1551 |
|
|
{
|
1552 |
|
|
journal_t *journal;
|
1553 |
|
|
int j_errno;
|
1554 |
|
|
const char *errstr;
|
1555 |
|
|
|
1556 |
|
|
journal = EXT3_SB(sb)->s_journal;
|
1557 |
|
|
|
1558 |
|
|
/*
|
1559 |
|
|
* Now check for any error status which may have been recorded in the
|
1560 |
|
|
* journal by a prior ext3_error() or ext3_abort()
|
1561 |
|
|
*/
|
1562 |
|
|
|
1563 |
|
|
j_errno = journal_errno(journal);
|
1564 |
|
|
if (j_errno) {
|
1565 |
|
|
char nbuf[16];
|
1566 |
|
|
|
1567 |
|
|
errstr = ext3_decode_error(sb, j_errno, nbuf);
|
1568 |
|
|
ext3_warning(sb, __FUNCTION__, "Filesystem error recorded "
|
1569 |
|
|
"from previous mount: %s", errstr);
|
1570 |
|
|
ext3_warning(sb, __FUNCTION__, "Marking fs in need of "
|
1571 |
|
|
"filesystem check.");
|
1572 |
|
|
|
1573 |
|
|
sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS;
|
1574 |
|
|
es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
|
1575 |
|
|
ext3_commit_super (sb, es, 1);
|
1576 |
|
|
|
1577 |
|
|
journal_clear_err(journal);
|
1578 |
|
|
}
|
1579 |
|
|
}
|
1580 |
|
|
|
1581 |
|
|
/*
|
1582 |
|
|
* Force the running and committing transactions to commit,
|
1583 |
|
|
* and wait on the commit.
|
1584 |
|
|
*/
|
1585 |
|
|
int ext3_force_commit(struct super_block *sb)
|
1586 |
|
|
{
|
1587 |
|
|
journal_t *journal;
|
1588 |
|
|
int ret;
|
1589 |
|
|
|
1590 |
|
|
if (sb->s_flags & MS_RDONLY)
|
1591 |
|
|
return 0;
|
1592 |
|
|
|
1593 |
|
|
journal = EXT3_SB(sb)->s_journal;
|
1594 |
|
|
sb->s_dirt = 0;
|
1595 |
|
|
lock_kernel(); /* important: lock down j_running_transaction */
|
1596 |
|
|
ret = ext3_journal_force_commit(journal);
|
1597 |
|
|
unlock_kernel();
|
1598 |
|
|
return ret;
|
1599 |
|
|
}
|
1600 |
|
|
|
1601 |
|
|
/*
|
1602 |
|
|
* Ext3 always journals updates to the superblock itself, so we don't
|
1603 |
|
|
* have to propagate any other updates to the superblock on disk at this
|
1604 |
|
|
* point. Just start an async writeback to get the buffers on their way
|
1605 |
|
|
* to the disk.
|
1606 |
|
|
*
|
1607 |
|
|
* This implicitly triggers the writebehind on sync().
|
1608 |
|
|
*/
|
1609 |
|
|
|
1610 |
|
|
void ext3_write_super (struct super_block * sb)
|
1611 |
|
|
{
|
1612 |
|
|
if (down_trylock(&sb->s_lock) == 0)
|
1613 |
|
|
BUG();
|
1614 |
|
|
sb->s_dirt = 0;
|
1615 |
|
|
log_start_commit(EXT3_SB(sb)->s_journal, NULL);
|
1616 |
|
|
}
|
1617 |
|
|
|
1618 |
|
|
static int ext3_sync_fs(struct super_block *sb)
|
1619 |
|
|
{
|
1620 |
|
|
tid_t target;
|
1621 |
|
|
|
1622 |
|
|
sb->s_dirt = 0;
|
1623 |
|
|
target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
|
1624 |
|
|
log_wait_commit(EXT3_SB(sb)->s_journal, target);
|
1625 |
|
|
return 0;
|
1626 |
|
|
}
|
1627 |
|
|
|
1628 |
|
|
/*
|
1629 |
|
|
* LVM calls this function before a (read-only) snapshot is created. This
|
1630 |
|
|
* gives us a chance to flush the journal completely and mark the fs clean.
|
1631 |
|
|
*/
|
1632 |
|
|
void ext3_write_super_lockfs(struct super_block *sb)
|
1633 |
|
|
{
|
1634 |
|
|
sb->s_dirt = 0;
|
1635 |
|
|
|
1636 |
|
|
lock_kernel(); /* 2.4.5 forgot to do this for us */
|
1637 |
|
|
if (!(sb->s_flags & MS_RDONLY)) {
|
1638 |
|
|
journal_t *journal = EXT3_SB(sb)->s_journal;
|
1639 |
|
|
|
1640 |
|
|
/* Now we set up the journal barrier. */
|
1641 |
|
|
unlock_super(sb);
|
1642 |
|
|
journal_lock_updates(journal);
|
1643 |
|
|
journal_flush(journal);
|
1644 |
|
|
lock_super(sb);
|
1645 |
|
|
|
1646 |
|
|
/* Journal blocked and flushed, clear needs_recovery flag. */
|
1647 |
|
|
EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
|
1648 |
|
|
ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
|
1649 |
|
|
}
|
1650 |
|
|
unlock_kernel();
|
1651 |
|
|
}
|
1652 |
|
|
|
1653 |
|
|
/*
|
1654 |
|
|
* Called by LVM after the snapshot is done. We need to reset the RECOVER
|
1655 |
|
|
* flag here, even though the filesystem is not technically dirty yet.
|
1656 |
|
|
*/
|
1657 |
|
|
void ext3_unlockfs(struct super_block *sb)
|
1658 |
|
|
{
|
1659 |
|
|
if (!(sb->s_flags & MS_RDONLY)) {
|
1660 |
|
|
lock_kernel();
|
1661 |
|
|
lock_super(sb);
|
1662 |
|
|
/* Reser the needs_recovery flag before the fs is unlocked. */
|
1663 |
|
|
EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
|
1664 |
|
|
ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
|
1665 |
|
|
unlock_super(sb);
|
1666 |
|
|
journal_unlock_updates(EXT3_SB(sb)->s_journal);
|
1667 |
|
|
unlock_kernel();
|
1668 |
|
|
}
|
1669 |
|
|
}
|
1670 |
|
|
|
1671 |
|
|
int ext3_remount (struct super_block * sb, int * flags, char * data)
|
1672 |
|
|
{
|
1673 |
|
|
struct ext3_super_block * es;
|
1674 |
|
|
struct ext3_sb_info *sbi = EXT3_SB(sb);
|
1675 |
|
|
unsigned long tmp;
|
1676 |
|
|
|
1677 |
|
|
clear_ro_after(sb);
|
1678 |
|
|
|
1679 |
|
|
/*
|
1680 |
|
|
* Allow the "check" option to be passed as a remount option.
|
1681 |
|
|
*/
|
1682 |
|
|
if (!parse_options(data, &tmp, sbi, &tmp, 1))
|
1683 |
|
|
return -EINVAL;
|
1684 |
|
|
|
1685 |
|
|
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
|
1686 |
|
|
ext3_abort(sb, __FUNCTION__, "Abort forced by user");
|
1687 |
|
|
|
1688 |
|
|
es = sbi->s_es;
|
1689 |
|
|
|
1690 |
|
|
ext3_init_journal_params(sbi, sbi->s_journal);
|
1691 |
|
|
|
1692 |
|
|
if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
|
1693 |
|
|
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
|
1694 |
|
|
return -EROFS;
|
1695 |
|
|
|
1696 |
|
|
if (*flags & MS_RDONLY) {
|
1697 |
|
|
/*
|
1698 |
|
|
* First of all, the unconditional stuff we have to do
|
1699 |
|
|
* to disable replay of the journal when we next remount
|
1700 |
|
|
*/
|
1701 |
|
|
sb->s_flags |= MS_RDONLY;
|
1702 |
|
|
|
1703 |
|
|
/*
|
1704 |
|
|
* OK, test if we are remounting a valid rw partition
|
1705 |
|
|
* readonly, and if so set the rdonly flag and then
|
1706 |
|
|
* mark the partition as valid again.
|
1707 |
|
|
*/
|
1708 |
|
|
if (!(es->s_state & cpu_to_le16(EXT3_VALID_FS)) &&
|
1709 |
|
|
(sbi->s_mount_state & EXT3_VALID_FS))
|
1710 |
|
|
es->s_state = cpu_to_le16(sbi->s_mount_state);
|
1711 |
|
|
|
1712 |
|
|
ext3_mark_recovery_complete(sb, es);
|
1713 |
|
|
} else {
|
1714 |
|
|
int ret;
|
1715 |
|
|
if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb,
|
1716 |
|
|
~EXT3_FEATURE_RO_COMPAT_SUPP))) {
|
1717 |
|
|
printk(KERN_WARNING "EXT3-fs: %s: couldn't "
|
1718 |
|
|
"remount RDWR because of unsupported "
|
1719 |
|
|
"optional features (%x).\n",
|
1720 |
|
|
bdevname(sb->s_dev), ret);
|
1721 |
|
|
return -EROFS;
|
1722 |
|
|
}
|
1723 |
|
|
/*
|
1724 |
|
|
* Mounting a RDONLY partition read-write, so reread
|
1725 |
|
|
* and store the current valid flag. (It may have
|
1726 |
|
|
* been changed by e2fsck since we originally mounted
|
1727 |
|
|
* the partition.)
|
1728 |
|
|
*/
|
1729 |
|
|
ext3_clear_journal_err(sb, es);
|
1730 |
|
|
sbi->s_mount_state = le16_to_cpu(es->s_state);
|
1731 |
|
|
if (!ext3_setup_super (sb, es, 0))
|
1732 |
|
|
sb->s_flags &= ~MS_RDONLY;
|
1733 |
|
|
}
|
1734 |
|
|
}
|
1735 |
|
|
setup_ro_after(sb);
|
1736 |
|
|
return 0;
|
1737 |
|
|
}
|
1738 |
|
|
|
1739 |
|
|
int ext3_statfs (struct super_block * sb, struct statfs * buf)
|
1740 |
|
|
{
|
1741 |
|
|
struct ext3_super_block *es = EXT3_SB(sb)->s_es;
|
1742 |
|
|
unsigned long overhead;
|
1743 |
|
|
int i;
|
1744 |
|
|
|
1745 |
|
|
if (test_opt (sb, MINIX_DF))
|
1746 |
|
|
overhead = 0;
|
1747 |
|
|
else {
|
1748 |
|
|
/*
|
1749 |
|
|
* Compute the overhead (FS structures)
|
1750 |
|
|
*/
|
1751 |
|
|
|
1752 |
|
|
/*
|
1753 |
|
|
* All of the blocks before first_data_block are
|
1754 |
|
|
* overhead
|
1755 |
|
|
*/
|
1756 |
|
|
overhead = le32_to_cpu(es->s_first_data_block);
|
1757 |
|
|
|
1758 |
|
|
/*
|
1759 |
|
|
* Add the overhead attributed to the superblock and
|
1760 |
|
|
* block group descriptors. If the sparse superblocks
|
1761 |
|
|
* feature is turned on, then not all groups have this.
|
1762 |
|
|
*/
|
1763 |
|
|
for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++)
|
1764 |
|
|
overhead += ext3_bg_has_super(sb, i) +
|
1765 |
|
|
ext3_bg_num_gdb(sb, i);
|
1766 |
|
|
|
1767 |
|
|
/*
|
1768 |
|
|
* Every block group has an inode bitmap, a block
|
1769 |
|
|
* bitmap, and an inode table.
|
1770 |
|
|
*/
|
1771 |
|
|
overhead += (EXT3_SB(sb)->s_groups_count *
|
1772 |
|
|
(2 + EXT3_SB(sb)->s_itb_per_group));
|
1773 |
|
|
}
|
1774 |
|
|
|
1775 |
|
|
buf->f_type = EXT3_SUPER_MAGIC;
|
1776 |
|
|
buf->f_bsize = sb->s_blocksize;
|
1777 |
|
|
buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
|
1778 |
|
|
buf->f_bfree = ext3_count_free_blocks (sb);
|
1779 |
|
|
buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
|
1780 |
|
|
if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
|
1781 |
|
|
buf->f_bavail = 0;
|
1782 |
|
|
buf->f_files = le32_to_cpu(es->s_inodes_count);
|
1783 |
|
|
buf->f_ffree = ext3_count_free_inodes (sb);
|
1784 |
|
|
buf->f_namelen = EXT3_NAME_LEN;
|
1785 |
|
|
return 0;
|
1786 |
|
|
}
|
1787 |
|
|
|
1788 |
|
|
/* Helper function for writing quotas on sync - we need to start transaction before quota file
|
1789 |
|
|
* is locked for write. Otherwise the are possible deadlocks:
|
1790 |
|
|
* Process 1 Process 2
|
1791 |
|
|
* ext3_create() quota_sync()
|
1792 |
|
|
* journal_start() write_dquot()
|
1793 |
|
|
* DQUOT_INIT() down(dqio_sem)
|
1794 |
|
|
* down(dqio_sem) journal_start()
|
1795 |
|
|
*
|
1796 |
|
|
*/
|
1797 |
|
|
|
1798 |
|
|
#ifdef CONFIG_QUOTA
|
1799 |
|
|
|
1800 |
|
|
static int (*old_write_dquot)(struct dquot *dquot);
|
1801 |
|
|
|
1802 |
|
|
/* Blocks: (2 data blocks) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */
|
1803 |
|
|
#define EXT3_OLD_QFMT_BLOCKS 11
|
1804 |
|
|
/* Blocks: quota info + (4 pointer blocks + 1 entry block) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */
|
1805 |
|
|
#define EXT3_V0_QFMT_BLOCKS 27
|
1806 |
|
|
|
1807 |
|
|
static int ext3_write_dquot(struct dquot *dquot)
|
1808 |
|
|
{
|
1809 |
|
|
int nblocks, ret;
|
1810 |
|
|
handle_t *handle;
|
1811 |
|
|
struct quota_info *dqops = sb_dqopt(dquot->dq_sb);
|
1812 |
|
|
struct inode *qinode;
|
1813 |
|
|
|
1814 |
|
|
switch (dqops->info[dquot->dq_type].dqi_format->qf_fmt_id) {
|
1815 |
|
|
case QFMT_VFS_OLD:
|
1816 |
|
|
nblocks = EXT3_OLD_QFMT_BLOCKS;
|
1817 |
|
|
break;
|
1818 |
|
|
case QFMT_VFS_V0:
|
1819 |
|
|
nblocks = EXT3_V0_QFMT_BLOCKS;
|
1820 |
|
|
break;
|
1821 |
|
|
default:
|
1822 |
|
|
nblocks = EXT3_MAX_TRANS_DATA;
|
1823 |
|
|
}
|
1824 |
|
|
lock_kernel();
|
1825 |
|
|
qinode = dqops->files[dquot->dq_type]->f_dentry->d_inode;
|
1826 |
|
|
handle = ext3_journal_start(qinode, nblocks);
|
1827 |
|
|
if (IS_ERR(handle)) {
|
1828 |
|
|
unlock_kernel();
|
1829 |
|
|
return PTR_ERR(handle);
|
1830 |
|
|
}
|
1831 |
|
|
unlock_kernel();
|
1832 |
|
|
ret = old_write_dquot(dquot);
|
1833 |
|
|
lock_kernel();
|
1834 |
|
|
ret = ext3_journal_stop(handle, qinode);
|
1835 |
|
|
unlock_kernel();
|
1836 |
|
|
return ret;
|
1837 |
|
|
}
|
1838 |
|
|
#endif
|
1839 |
|
|
|
1840 |
|
|
static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super);
|
1841 |
|
|
|
1842 |
|
|
static int __init init_ext3_fs(void)
|
1843 |
|
|
{
|
1844 |
|
|
#ifdef CONFIG_QUOTA
|
1845 |
|
|
init_dquot_operations(&ext3_qops);
|
1846 |
|
|
old_write_dquot = ext3_qops.write_dquot;
|
1847 |
|
|
ext3_qops.write_dquot = ext3_write_dquot;
|
1848 |
|
|
#endif
|
1849 |
|
|
return register_filesystem(&ext3_fs_type);
|
1850 |
|
|
}
|
1851 |
|
|
|
1852 |
|
|
static void __exit exit_ext3_fs(void)
|
1853 |
|
|
{
|
1854 |
|
|
unregister_filesystem(&ext3_fs_type);
|
1855 |
|
|
}
|
1856 |
|
|
|
1857 |
|
|
EXPORT_NO_SYMBOLS;
|
1858 |
|
|
|
1859 |
|
|
MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
|
1860 |
|
|
MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
|
1861 |
|
|
MODULE_LICENSE("GPL");
|
1862 |
|
|
module_init(init_ext3_fs)
|
1863 |
|
|
module_exit(exit_ext3_fs)
|