diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 336 |
1 files changed, 237 insertions, 99 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index f627a6a4c317..26147746c272 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -241,14 +241,14 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | |||
241 | if (sb->s_flags & MS_RDONLY) | 241 | if (sb->s_flags & MS_RDONLY) |
242 | return ERR_PTR(-EROFS); | 242 | return ERR_PTR(-EROFS); |
243 | 243 | ||
244 | vfs_check_frozen(sb, SB_FREEZE_WRITE); | 244 | vfs_check_frozen(sb, SB_FREEZE_TRANS); |
245 | /* Special case here: if the journal has aborted behind our | 245 | /* Special case here: if the journal has aborted behind our |
246 | * backs (eg. EIO in the commit thread), then we still need to | 246 | * backs (eg. EIO in the commit thread), then we still need to |
247 | * take the FS itself readonly cleanly. */ | 247 | * take the FS itself readonly cleanly. */ |
248 | journal = EXT4_SB(sb)->s_journal; | 248 | journal = EXT4_SB(sb)->s_journal; |
249 | if (journal) { | 249 | if (journal) { |
250 | if (is_journal_aborted(journal)) { | 250 | if (is_journal_aborted(journal)) { |
251 | ext4_abort(sb, __func__, "Detected aborted journal"); | 251 | ext4_abort(sb, "Detected aborted journal"); |
252 | return ERR_PTR(-EROFS); | 252 | return ERR_PTR(-EROFS); |
253 | } | 253 | } |
254 | return jbd2_journal_start(journal, nblocks); | 254 | return jbd2_journal_start(journal, nblocks); |
@@ -262,7 +262,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | |||
262 | * that sync() will call the filesystem's write_super callback if | 262 | * that sync() will call the filesystem's write_super callback if |
263 | * appropriate. | 263 | * appropriate. |
264 | */ | 264 | */ |
265 | int __ext4_journal_stop(const char *where, handle_t *handle) | 265 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) |
266 | { | 266 | { |
267 | struct super_block *sb; | 267 | struct super_block *sb; |
268 | int err; | 268 | int err; |
@@ -279,12 +279,13 @@ int __ext4_journal_stop(const char *where, handle_t *handle) | |||
279 | if (!err) | 279 | if (!err) |
280 | err = rc; | 280 | err = rc; |
281 | if (err) | 281 | if (err) |
282 | __ext4_std_error(sb, where, err); | 282 | __ext4_std_error(sb, where, line, err); |
283 | return err; | 283 | return err; |
284 | } | 284 | } |
285 | 285 | ||
286 | void ext4_journal_abort_handle(const char *caller, const char *err_fn, | 286 | void ext4_journal_abort_handle(const char *caller, unsigned int line, |
287 | struct buffer_head *bh, handle_t *handle, int err) | 287 | const char *err_fn, struct buffer_head *bh, |
288 | handle_t *handle, int err) | ||
288 | { | 289 | { |
289 | char nbuf[16]; | 290 | char nbuf[16]; |
290 | const char *errstr = ext4_decode_error(NULL, err, nbuf); | 291 | const char *errstr = ext4_decode_error(NULL, err, nbuf); |
@@ -300,12 +301,47 @@ void ext4_journal_abort_handle(const char *caller, const char *err_fn, | |||
300 | if (is_handle_aborted(handle)) | 301 | if (is_handle_aborted(handle)) |
301 | return; | 302 | return; |
302 | 303 | ||
303 | printk(KERN_ERR "%s: aborting transaction: %s in %s\n", | 304 | printk(KERN_ERR "%s:%d: aborting transaction: %s in %s\n", |
304 | caller, errstr, err_fn); | 305 | caller, line, errstr, err_fn); |
305 | 306 | ||
306 | jbd2_journal_abort_handle(handle); | 307 | jbd2_journal_abort_handle(handle); |
307 | } | 308 | } |
308 | 309 | ||
310 | static void __save_error_info(struct super_block *sb, const char *func, | ||
311 | unsigned int line) | ||
312 | { | ||
313 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | ||
314 | |||
315 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
316 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
317 | es->s_last_error_time = cpu_to_le32(get_seconds()); | ||
318 | strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func)); | ||
319 | es->s_last_error_line = cpu_to_le32(line); | ||
320 | if (!es->s_first_error_time) { | ||
321 | es->s_first_error_time = es->s_last_error_time; | ||
322 | strncpy(es->s_first_error_func, func, | ||
323 | sizeof(es->s_first_error_func)); | ||
324 | es->s_first_error_line = cpu_to_le32(line); | ||
325 | es->s_first_error_ino = es->s_last_error_ino; | ||
326 | es->s_first_error_block = es->s_last_error_block; | ||
327 | } | ||
328 | /* | ||
329 | * Start the daily error reporting function if it hasn't been | ||
330 | * started already | ||
331 | */ | ||
332 | if (!es->s_error_count) | ||
333 | mod_timer(&EXT4_SB(sb)->s_err_report, jiffies + 24*60*60*HZ); | ||
334 | es->s_error_count = cpu_to_le32(le32_to_cpu(es->s_error_count) + 1); | ||
335 | } | ||
336 | |||
337 | static void save_error_info(struct super_block *sb, const char *func, | ||
338 | unsigned int line) | ||
339 | { | ||
340 | __save_error_info(sb, func, line); | ||
341 | ext4_commit_super(sb, 1); | ||
342 | } | ||
343 | |||
344 | |||
309 | /* Deal with the reporting of failure conditions on a filesystem such as | 345 | /* Deal with the reporting of failure conditions on a filesystem such as |
310 | * inconsistencies detected or read IO failures. | 346 | * inconsistencies detected or read IO failures. |
311 | * | 347 | * |
@@ -323,11 +359,6 @@ void ext4_journal_abort_handle(const char *caller, const char *err_fn, | |||
323 | 359 | ||
324 | static void ext4_handle_error(struct super_block *sb) | 360 | static void ext4_handle_error(struct super_block *sb) |
325 | { | 361 | { |
326 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | ||
327 | |||
328 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
329 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
330 | |||
331 | if (sb->s_flags & MS_RDONLY) | 362 | if (sb->s_flags & MS_RDONLY) |
332 | return; | 363 | return; |
333 | 364 | ||
@@ -342,19 +373,19 @@ static void ext4_handle_error(struct super_block *sb) | |||
342 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); | 373 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); |
343 | sb->s_flags |= MS_RDONLY; | 374 | sb->s_flags |= MS_RDONLY; |
344 | } | 375 | } |
345 | ext4_commit_super(sb, 1); | ||
346 | if (test_opt(sb, ERRORS_PANIC)) | 376 | if (test_opt(sb, ERRORS_PANIC)) |
347 | panic("EXT4-fs (device %s): panic forced after error\n", | 377 | panic("EXT4-fs (device %s): panic forced after error\n", |
348 | sb->s_id); | 378 | sb->s_id); |
349 | } | 379 | } |
350 | 380 | ||
351 | void __ext4_error(struct super_block *sb, const char *function, | 381 | void __ext4_error(struct super_block *sb, const char *function, |
352 | const char *fmt, ...) | 382 | unsigned int line, const char *fmt, ...) |
353 | { | 383 | { |
354 | va_list args; | 384 | va_list args; |
355 | 385 | ||
356 | va_start(args, fmt); | 386 | va_start(args, fmt); |
357 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: ", sb->s_id, function); | 387 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: ", |
388 | sb->s_id, function, line, current->comm); | ||
358 | vprintk(fmt, args); | 389 | vprintk(fmt, args); |
359 | printk("\n"); | 390 | printk("\n"); |
360 | va_end(args); | 391 | va_end(args); |
@@ -362,14 +393,22 @@ void __ext4_error(struct super_block *sb, const char *function, | |||
362 | ext4_handle_error(sb); | 393 | ext4_handle_error(sb); |
363 | } | 394 | } |
364 | 395 | ||
365 | void ext4_error_inode(const char *function, struct inode *inode, | 396 | void ext4_error_inode(struct inode *inode, const char *function, |
397 | unsigned int line, ext4_fsblk_t block, | ||
366 | const char *fmt, ...) | 398 | const char *fmt, ...) |
367 | { | 399 | { |
368 | va_list args; | 400 | va_list args; |
401 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; | ||
369 | 402 | ||
403 | es->s_last_error_ino = cpu_to_le32(inode->i_ino); | ||
404 | es->s_last_error_block = cpu_to_le64(block); | ||
405 | save_error_info(inode->i_sb, function, line); | ||
370 | va_start(args, fmt); | 406 | va_start(args, fmt); |
371 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: inode #%lu: (comm %s) ", | 407 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ", |
372 | inode->i_sb->s_id, function, inode->i_ino, current->comm); | 408 | inode->i_sb->s_id, function, line, inode->i_ino); |
409 | if (block) | ||
410 | printk("block %llu: ", block); | ||
411 | printk("comm %s: ", current->comm); | ||
373 | vprintk(fmt, args); | 412 | vprintk(fmt, args); |
374 | printk("\n"); | 413 | printk("\n"); |
375 | va_end(args); | 414 | va_end(args); |
@@ -377,20 +416,26 @@ void ext4_error_inode(const char *function, struct inode *inode, | |||
377 | ext4_handle_error(inode->i_sb); | 416 | ext4_handle_error(inode->i_sb); |
378 | } | 417 | } |
379 | 418 | ||
380 | void ext4_error_file(const char *function, struct file *file, | 419 | void ext4_error_file(struct file *file, const char *function, |
381 | const char *fmt, ...) | 420 | unsigned int line, const char *fmt, ...) |
382 | { | 421 | { |
383 | va_list args; | 422 | va_list args; |
423 | struct ext4_super_block *es; | ||
384 | struct inode *inode = file->f_dentry->d_inode; | 424 | struct inode *inode = file->f_dentry->d_inode; |
385 | char pathname[80], *path; | 425 | char pathname[80], *path; |
386 | 426 | ||
427 | es = EXT4_SB(inode->i_sb)->s_es; | ||
428 | es->s_last_error_ino = cpu_to_le32(inode->i_ino); | ||
429 | save_error_info(inode->i_sb, function, line); | ||
387 | va_start(args, fmt); | 430 | va_start(args, fmt); |
388 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); | 431 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); |
389 | if (!path) | 432 | if (!path) |
390 | path = "(unknown)"; | 433 | path = "(unknown)"; |
391 | printk(KERN_CRIT | 434 | printk(KERN_CRIT |
392 | "EXT4-fs error (device %s): %s: inode #%lu (comm %s path %s): ", | 435 | "EXT4-fs error (device %s): %s:%d: inode #%lu " |
393 | inode->i_sb->s_id, function, inode->i_ino, current->comm, path); | 436 | "(comm %s path %s): ", |
437 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
438 | current->comm, path); | ||
394 | vprintk(fmt, args); | 439 | vprintk(fmt, args); |
395 | printk("\n"); | 440 | printk("\n"); |
396 | va_end(args); | 441 | va_end(args); |
@@ -435,7 +480,8 @@ static const char *ext4_decode_error(struct super_block *sb, int errno, | |||
435 | /* __ext4_std_error decodes expected errors from journaling functions | 480 | /* __ext4_std_error decodes expected errors from journaling functions |
436 | * automatically and invokes the appropriate error response. */ | 481 | * automatically and invokes the appropriate error response. */ |
437 | 482 | ||
438 | void __ext4_std_error(struct super_block *sb, const char *function, int errno) | 483 | void __ext4_std_error(struct super_block *sb, const char *function, |
484 | unsigned int line, int errno) | ||
439 | { | 485 | { |
440 | char nbuf[16]; | 486 | char nbuf[16]; |
441 | const char *errstr; | 487 | const char *errstr; |
@@ -448,8 +494,9 @@ void __ext4_std_error(struct super_block *sb, const char *function, int errno) | |||
448 | return; | 494 | return; |
449 | 495 | ||
450 | errstr = ext4_decode_error(sb, errno, nbuf); | 496 | errstr = ext4_decode_error(sb, errno, nbuf); |
451 | printk(KERN_CRIT "EXT4-fs error (device %s) in %s: %s\n", | 497 | printk(KERN_CRIT "EXT4-fs error (device %s) in %s:%d: %s\n", |
452 | sb->s_id, function, errstr); | 498 | sb->s_id, function, line, errstr); |
499 | save_error_info(sb, function, line); | ||
453 | 500 | ||
454 | ext4_handle_error(sb); | 501 | ext4_handle_error(sb); |
455 | } | 502 | } |
@@ -464,29 +511,29 @@ void __ext4_std_error(struct super_block *sb, const char *function, int errno) | |||
464 | * case we take the easy way out and panic immediately. | 511 | * case we take the easy way out and panic immediately. |
465 | */ | 512 | */ |
466 | 513 | ||
467 | void ext4_abort(struct super_block *sb, const char *function, | 514 | void __ext4_abort(struct super_block *sb, const char *function, |
468 | const char *fmt, ...) | 515 | unsigned int line, const char *fmt, ...) |
469 | { | 516 | { |
470 | va_list args; | 517 | va_list args; |
471 | 518 | ||
519 | save_error_info(sb, function, line); | ||
472 | va_start(args, fmt); | 520 | va_start(args, fmt); |
473 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: ", sb->s_id, function); | 521 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: ", sb->s_id, |
522 | function, line); | ||
474 | vprintk(fmt, args); | 523 | vprintk(fmt, args); |
475 | printk("\n"); | 524 | printk("\n"); |
476 | va_end(args); | 525 | va_end(args); |
477 | 526 | ||
527 | if ((sb->s_flags & MS_RDONLY) == 0) { | ||
528 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); | ||
529 | sb->s_flags |= MS_RDONLY; | ||
530 | EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; | ||
531 | if (EXT4_SB(sb)->s_journal) | ||
532 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); | ||
533 | save_error_info(sb, function, line); | ||
534 | } | ||
478 | if (test_opt(sb, ERRORS_PANIC)) | 535 | if (test_opt(sb, ERRORS_PANIC)) |
479 | panic("EXT4-fs panic from previous error\n"); | 536 | panic("EXT4-fs panic from previous error\n"); |
480 | |||
481 | if (sb->s_flags & MS_RDONLY) | ||
482 | return; | ||
483 | |||
484 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); | ||
485 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
486 | sb->s_flags |= MS_RDONLY; | ||
487 | EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; | ||
488 | if (EXT4_SB(sb)->s_journal) | ||
489 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); | ||
490 | } | 537 | } |
491 | 538 | ||
492 | void ext4_msg (struct super_block * sb, const char *prefix, | 539 | void ext4_msg (struct super_block * sb, const char *prefix, |
@@ -502,38 +549,47 @@ void ext4_msg (struct super_block * sb, const char *prefix, | |||
502 | } | 549 | } |
503 | 550 | ||
504 | void __ext4_warning(struct super_block *sb, const char *function, | 551 | void __ext4_warning(struct super_block *sb, const char *function, |
505 | const char *fmt, ...) | 552 | unsigned int line, const char *fmt, ...) |
506 | { | 553 | { |
507 | va_list args; | 554 | va_list args; |
508 | 555 | ||
509 | va_start(args, fmt); | 556 | va_start(args, fmt); |
510 | printk(KERN_WARNING "EXT4-fs warning (device %s): %s: ", | 557 | printk(KERN_WARNING "EXT4-fs warning (device %s): %s:%d: ", |
511 | sb->s_id, function); | 558 | sb->s_id, function, line); |
512 | vprintk(fmt, args); | 559 | vprintk(fmt, args); |
513 | printk("\n"); | 560 | printk("\n"); |
514 | va_end(args); | 561 | va_end(args); |
515 | } | 562 | } |
516 | 563 | ||
517 | void ext4_grp_locked_error(struct super_block *sb, ext4_group_t grp, | 564 | void __ext4_grp_locked_error(const char *function, unsigned int line, |
518 | const char *function, const char *fmt, ...) | 565 | struct super_block *sb, ext4_group_t grp, |
566 | unsigned long ino, ext4_fsblk_t block, | ||
567 | const char *fmt, ...) | ||
519 | __releases(bitlock) | 568 | __releases(bitlock) |
520 | __acquires(bitlock) | 569 | __acquires(bitlock) |
521 | { | 570 | { |
522 | va_list args; | 571 | va_list args; |
523 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | 572 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; |
524 | 573 | ||
574 | es->s_last_error_ino = cpu_to_le32(ino); | ||
575 | es->s_last_error_block = cpu_to_le64(block); | ||
576 | __save_error_info(sb, function, line); | ||
525 | va_start(args, fmt); | 577 | va_start(args, fmt); |
526 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: ", sb->s_id, function); | 578 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: group %u", |
579 | sb->s_id, function, line, grp); | ||
580 | if (ino) | ||
581 | printk("inode %lu: ", ino); | ||
582 | if (block) | ||
583 | printk("block %llu:", (unsigned long long) block); | ||
527 | vprintk(fmt, args); | 584 | vprintk(fmt, args); |
528 | printk("\n"); | 585 | printk("\n"); |
529 | va_end(args); | 586 | va_end(args); |
530 | 587 | ||
531 | if (test_opt(sb, ERRORS_CONT)) { | 588 | if (test_opt(sb, ERRORS_CONT)) { |
532 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
533 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
534 | ext4_commit_super(sb, 0); | 589 | ext4_commit_super(sb, 0); |
535 | return; | 590 | return; |
536 | } | 591 | } |
592 | |||
537 | ext4_unlock_group(sb, grp); | 593 | ext4_unlock_group(sb, grp); |
538 | ext4_handle_error(sb); | 594 | ext4_handle_error(sb); |
539 | /* | 595 | /* |
@@ -660,8 +716,7 @@ static void ext4_put_super(struct super_block *sb) | |||
660 | err = jbd2_journal_destroy(sbi->s_journal); | 716 | err = jbd2_journal_destroy(sbi->s_journal); |
661 | sbi->s_journal = NULL; | 717 | sbi->s_journal = NULL; |
662 | if (err < 0) | 718 | if (err < 0) |
663 | ext4_abort(sb, __func__, | 719 | ext4_abort(sb, "Couldn't clean up the journal"); |
664 | "Couldn't clean up the journal"); | ||
665 | } | 720 | } |
666 | 721 | ||
667 | ext4_release_system_zone(sb); | 722 | ext4_release_system_zone(sb); |
@@ -948,14 +1003,12 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
948 | seq_puts(seq, ",journal_async_commit"); | 1003 | seq_puts(seq, ",journal_async_commit"); |
949 | else if (test_opt(sb, JOURNAL_CHECKSUM)) | 1004 | else if (test_opt(sb, JOURNAL_CHECKSUM)) |
950 | seq_puts(seq, ",journal_checksum"); | 1005 | seq_puts(seq, ",journal_checksum"); |
951 | if (test_opt(sb, NOBH)) | ||
952 | seq_puts(seq, ",nobh"); | ||
953 | if (test_opt(sb, I_VERSION)) | 1006 | if (test_opt(sb, I_VERSION)) |
954 | seq_puts(seq, ",i_version"); | 1007 | seq_puts(seq, ",i_version"); |
955 | if (!test_opt(sb, DELALLOC)) | 1008 | if (!test_opt(sb, DELALLOC) && |
1009 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) | ||
956 | seq_puts(seq, ",nodelalloc"); | 1010 | seq_puts(seq, ",nodelalloc"); |
957 | 1011 | ||
958 | |||
959 | if (sbi->s_stripe) | 1012 | if (sbi->s_stripe) |
960 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | 1013 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); |
961 | /* | 1014 | /* |
@@ -979,7 +1032,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
979 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) | 1032 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) |
980 | seq_puts(seq, ",noauto_da_alloc"); | 1033 | seq_puts(seq, ",noauto_da_alloc"); |
981 | 1034 | ||
982 | if (test_opt(sb, DISCARD)) | 1035 | if (test_opt(sb, DISCARD) && !(def_mount_opts & EXT4_DEFM_DISCARD)) |
983 | seq_puts(seq, ",discard"); | 1036 | seq_puts(seq, ",discard"); |
984 | 1037 | ||
985 | if (test_opt(sb, NOLOAD)) | 1038 | if (test_opt(sb, NOLOAD)) |
@@ -988,6 +1041,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
988 | if (test_opt(sb, DIOREAD_NOLOCK)) | 1041 | if (test_opt(sb, DIOREAD_NOLOCK)) |
989 | seq_puts(seq, ",dioread_nolock"); | 1042 | seq_puts(seq, ",dioread_nolock"); |
990 | 1043 | ||
1044 | if (test_opt(sb, BLOCK_VALIDITY) && | ||
1045 | !(def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY)) | ||
1046 | seq_puts(seq, ",block_validity"); | ||
1047 | |||
991 | ext4_show_quota_options(seq, sb); | 1048 | ext4_show_quota_options(seq, sb); |
992 | 1049 | ||
993 | return 0; | 1050 | return 0; |
@@ -1067,6 +1124,7 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot); | |||
1067 | static int ext4_write_info(struct super_block *sb, int type); | 1124 | static int ext4_write_info(struct super_block *sb, int type); |
1068 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, | 1125 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
1069 | char *path); | 1126 | char *path); |
1127 | static int ext4_quota_off(struct super_block *sb, int type); | ||
1070 | static int ext4_quota_on_mount(struct super_block *sb, int type); | 1128 | static int ext4_quota_on_mount(struct super_block *sb, int type); |
1071 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, | 1129 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, |
1072 | size_t len, loff_t off); | 1130 | size_t len, loff_t off); |
@@ -1088,7 +1146,7 @@ static const struct dquot_operations ext4_quota_operations = { | |||
1088 | 1146 | ||
1089 | static const struct quotactl_ops ext4_qctl_operations = { | 1147 | static const struct quotactl_ops ext4_qctl_operations = { |
1090 | .quota_on = ext4_quota_on, | 1148 | .quota_on = ext4_quota_on, |
1091 | .quota_off = dquot_quota_off, | 1149 | .quota_off = ext4_quota_off, |
1092 | .quota_sync = dquot_quota_sync, | 1150 | .quota_sync = dquot_quota_sync, |
1093 | .get_info = dquot_get_dqinfo, | 1151 | .get_info = dquot_get_dqinfo, |
1094 | .set_info = dquot_set_dqinfo, | 1152 | .set_info = dquot_set_dqinfo, |
@@ -1624,10 +1682,12 @@ set_qf_format: | |||
1624 | *n_blocks_count = option; | 1682 | *n_blocks_count = option; |
1625 | break; | 1683 | break; |
1626 | case Opt_nobh: | 1684 | case Opt_nobh: |
1627 | set_opt(sbi->s_mount_opt, NOBH); | 1685 | ext4_msg(sb, KERN_WARNING, |
1686 | "Ignoring deprecated nobh option"); | ||
1628 | break; | 1687 | break; |
1629 | case Opt_bh: | 1688 | case Opt_bh: |
1630 | clear_opt(sbi->s_mount_opt, NOBH); | 1689 | ext4_msg(sb, KERN_WARNING, |
1690 | "Ignoring deprecated bh option"); | ||
1631 | break; | 1691 | break; |
1632 | case Opt_i_version: | 1692 | case Opt_i_version: |
1633 | set_opt(sbi->s_mount_opt, I_VERSION); | 1693 | set_opt(sbi->s_mount_opt, I_VERSION); |
@@ -2249,6 +2309,8 @@ static ssize_t session_write_kbytes_show(struct ext4_attr *a, | |||
2249 | { | 2309 | { |
2250 | struct super_block *sb = sbi->s_buddy_cache->i_sb; | 2310 | struct super_block *sb = sbi->s_buddy_cache->i_sb; |
2251 | 2311 | ||
2312 | if (!sb->s_bdev->bd_part) | ||
2313 | return snprintf(buf, PAGE_SIZE, "0\n"); | ||
2252 | return snprintf(buf, PAGE_SIZE, "%lu\n", | 2314 | return snprintf(buf, PAGE_SIZE, "%lu\n", |
2253 | (part_stat_read(sb->s_bdev->bd_part, sectors[1]) - | 2315 | (part_stat_read(sb->s_bdev->bd_part, sectors[1]) - |
2254 | sbi->s_sectors_written_start) >> 1); | 2316 | sbi->s_sectors_written_start) >> 1); |
@@ -2259,6 +2321,8 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, | |||
2259 | { | 2321 | { |
2260 | struct super_block *sb = sbi->s_buddy_cache->i_sb; | 2322 | struct super_block *sb = sbi->s_buddy_cache->i_sb; |
2261 | 2323 | ||
2324 | if (!sb->s_bdev->bd_part) | ||
2325 | return snprintf(buf, PAGE_SIZE, "0\n"); | ||
2262 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 2326 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
2263 | (unsigned long long)(sbi->s_kbytes_written + | 2327 | (unsigned long long)(sbi->s_kbytes_written + |
2264 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - | 2328 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - |
@@ -2431,6 +2495,53 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly) | |||
2431 | return 1; | 2495 | return 1; |
2432 | } | 2496 | } |
2433 | 2497 | ||
2498 | /* | ||
2499 | * This function is called once a day if we have errors logged | ||
2500 | * on the file system | ||
2501 | */ | ||
2502 | static void print_daily_error_info(unsigned long arg) | ||
2503 | { | ||
2504 | struct super_block *sb = (struct super_block *) arg; | ||
2505 | struct ext4_sb_info *sbi; | ||
2506 | struct ext4_super_block *es; | ||
2507 | |||
2508 | sbi = EXT4_SB(sb); | ||
2509 | es = sbi->s_es; | ||
2510 | |||
2511 | if (es->s_error_count) | ||
2512 | ext4_msg(sb, KERN_NOTICE, "error count: %u", | ||
2513 | le32_to_cpu(es->s_error_count)); | ||
2514 | if (es->s_first_error_time) { | ||
2515 | printk(KERN_NOTICE "EXT4-fs (%s): initial error at %u: %.*s:%d", | ||
2516 | sb->s_id, le32_to_cpu(es->s_first_error_time), | ||
2517 | (int) sizeof(es->s_first_error_func), | ||
2518 | es->s_first_error_func, | ||
2519 | le32_to_cpu(es->s_first_error_line)); | ||
2520 | if (es->s_first_error_ino) | ||
2521 | printk(": inode %u", | ||
2522 | le32_to_cpu(es->s_first_error_ino)); | ||
2523 | if (es->s_first_error_block) | ||
2524 | printk(": block %llu", (unsigned long long) | ||
2525 | le64_to_cpu(es->s_first_error_block)); | ||
2526 | printk("\n"); | ||
2527 | } | ||
2528 | if (es->s_last_error_time) { | ||
2529 | printk(KERN_NOTICE "EXT4-fs (%s): last error at %u: %.*s:%d", | ||
2530 | sb->s_id, le32_to_cpu(es->s_last_error_time), | ||
2531 | (int) sizeof(es->s_last_error_func), | ||
2532 | es->s_last_error_func, | ||
2533 | le32_to_cpu(es->s_last_error_line)); | ||
2534 | if (es->s_last_error_ino) | ||
2535 | printk(": inode %u", | ||
2536 | le32_to_cpu(es->s_last_error_ino)); | ||
2537 | if (es->s_last_error_block) | ||
2538 | printk(": block %llu", (unsigned long long) | ||
2539 | le64_to_cpu(es->s_last_error_block)); | ||
2540 | printk("\n"); | ||
2541 | } | ||
2542 | mod_timer(&sbi->s_err_report, jiffies + 24*60*60*HZ); /* Once a day */ | ||
2543 | } | ||
2544 | |||
2434 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) | 2545 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) |
2435 | __releases(kernel_lock) | 2546 | __releases(kernel_lock) |
2436 | __acquires(kernel_lock) | 2547 | __acquires(kernel_lock) |
@@ -2448,7 +2559,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2448 | struct inode *root; | 2559 | struct inode *root; |
2449 | char *cp; | 2560 | char *cp; |
2450 | const char *descr; | 2561 | const char *descr; |
2451 | int ret = -EINVAL; | 2562 | int ret = -ENOMEM; |
2452 | int blocksize; | 2563 | int blocksize; |
2453 | unsigned int db_count; | 2564 | unsigned int db_count; |
2454 | unsigned int i; | 2565 | unsigned int i; |
@@ -2459,13 +2570,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2459 | 2570 | ||
2460 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 2571 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
2461 | if (!sbi) | 2572 | if (!sbi) |
2462 | return -ENOMEM; | 2573 | goto out_free_orig; |
2463 | 2574 | ||
2464 | sbi->s_blockgroup_lock = | 2575 | sbi->s_blockgroup_lock = |
2465 | kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); | 2576 | kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); |
2466 | if (!sbi->s_blockgroup_lock) { | 2577 | if (!sbi->s_blockgroup_lock) { |
2467 | kfree(sbi); | 2578 | kfree(sbi); |
2468 | return -ENOMEM; | 2579 | goto out_free_orig; |
2469 | } | 2580 | } |
2470 | sb->s_fs_info = sbi; | 2581 | sb->s_fs_info = sbi; |
2471 | sbi->s_mount_opt = 0; | 2582 | sbi->s_mount_opt = 0; |
@@ -2473,8 +2584,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2473 | sbi->s_resgid = EXT4_DEF_RESGID; | 2584 | sbi->s_resgid = EXT4_DEF_RESGID; |
2474 | sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS; | 2585 | sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS; |
2475 | sbi->s_sb_block = sb_block; | 2586 | sbi->s_sb_block = sb_block; |
2476 | sbi->s_sectors_written_start = part_stat_read(sb->s_bdev->bd_part, | 2587 | if (sb->s_bdev->bd_part) |
2477 | sectors[1]); | 2588 | sbi->s_sectors_written_start = |
2589 | part_stat_read(sb->s_bdev->bd_part, sectors[1]); | ||
2478 | 2590 | ||
2479 | unlock_kernel(); | 2591 | unlock_kernel(); |
2480 | 2592 | ||
@@ -2482,6 +2594,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2482 | for (cp = sb->s_id; (cp = strchr(cp, '/'));) | 2594 | for (cp = sb->s_id; (cp = strchr(cp, '/'));) |
2483 | *cp = '!'; | 2595 | *cp = '!'; |
2484 | 2596 | ||
2597 | ret = -EINVAL; | ||
2485 | blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); | 2598 | blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); |
2486 | if (!blocksize) { | 2599 | if (!blocksize) { |
2487 | ext4_msg(sb, KERN_ERR, "unable to set blocksize"); | 2600 | ext4_msg(sb, KERN_ERR, "unable to set blocksize"); |
@@ -2546,6 +2659,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2546 | set_opt(sbi->s_mount_opt, ERRORS_CONT); | 2659 | set_opt(sbi->s_mount_opt, ERRORS_CONT); |
2547 | else | 2660 | else |
2548 | set_opt(sbi->s_mount_opt, ERRORS_RO); | 2661 | set_opt(sbi->s_mount_opt, ERRORS_RO); |
2662 | if (def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY) | ||
2663 | set_opt(sbi->s_mount_opt, BLOCK_VALIDITY); | ||
2664 | if (def_mount_opts & EXT4_DEFM_DISCARD) | ||
2665 | set_opt(sbi->s_mount_opt, DISCARD); | ||
2549 | 2666 | ||
2550 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); | 2667 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); |
2551 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); | 2668 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); |
@@ -2553,15 +2670,23 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2553 | sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; | 2670 | sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; |
2554 | sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; | 2671 | sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; |
2555 | 2672 | ||
2556 | set_opt(sbi->s_mount_opt, BARRIER); | 2673 | if ((def_mount_opts & EXT4_DEFM_NOBARRIER) == 0) |
2674 | set_opt(sbi->s_mount_opt, BARRIER); | ||
2557 | 2675 | ||
2558 | /* | 2676 | /* |
2559 | * enable delayed allocation by default | 2677 | * enable delayed allocation by default |
2560 | * Use -o nodelalloc to turn it off | 2678 | * Use -o nodelalloc to turn it off |
2561 | */ | 2679 | */ |
2562 | if (!IS_EXT3_SB(sb)) | 2680 | if (!IS_EXT3_SB(sb) && |
2681 | ((def_mount_opts & EXT4_DEFM_NODELALLOC) == 0)) | ||
2563 | set_opt(sbi->s_mount_opt, DELALLOC); | 2682 | set_opt(sbi->s_mount_opt, DELALLOC); |
2564 | 2683 | ||
2684 | if (!parse_options((char *) sbi->s_es->s_mount_opts, sb, | ||
2685 | &journal_devnum, &journal_ioprio, NULL, 0)) { | ||
2686 | ext4_msg(sb, KERN_WARNING, | ||
2687 | "failed to parse options in superblock: %s", | ||
2688 | sbi->s_es->s_mount_opts); | ||
2689 | } | ||
2565 | if (!parse_options((char *) data, sb, &journal_devnum, | 2690 | if (!parse_options((char *) data, sb, &journal_devnum, |
2566 | &journal_ioprio, NULL, 0)) | 2691 | &journal_ioprio, NULL, 0)) |
2567 | goto failed_mount; | 2692 | goto failed_mount; |
@@ -2912,18 +3037,7 @@ no_journal: | |||
2912 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | 3037 | ext4_msg(sb, KERN_ERR, "insufficient memory"); |
2913 | goto failed_mount_wq; | 3038 | goto failed_mount_wq; |
2914 | } | 3039 | } |
2915 | if (test_opt(sb, NOBH)) { | 3040 | |
2916 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { | ||
2917 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " | ||
2918 | "its supported only with writeback mode"); | ||
2919 | clear_opt(sbi->s_mount_opt, NOBH); | ||
2920 | } | ||
2921 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
2922 | ext4_msg(sb, KERN_WARNING, "dioread_nolock option is " | ||
2923 | "not supported with nobh mode"); | ||
2924 | goto failed_mount_wq; | ||
2925 | } | ||
2926 | } | ||
2927 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 3041 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
2928 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 3042 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
2929 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); | 3043 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); |
@@ -3010,7 +3124,7 @@ no_journal: | |||
3010 | ext4_ext_init(sb); | 3124 | ext4_ext_init(sb); |
3011 | err = ext4_mb_init(sb, needs_recovery); | 3125 | err = ext4_mb_init(sb, needs_recovery); |
3012 | if (err) { | 3126 | if (err) { |
3013 | ext4_msg(sb, KERN_ERR, "failed to initalize mballoc (%d)", | 3127 | ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", |
3014 | err); | 3128 | err); |
3015 | goto failed_mount4; | 3129 | goto failed_mount4; |
3016 | } | 3130 | } |
@@ -3043,7 +3157,14 @@ no_journal: | |||
3043 | descr = "out journal"; | 3157 | descr = "out journal"; |
3044 | 3158 | ||
3045 | ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. " | 3159 | ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. " |
3046 | "Opts: %s", descr, orig_data); | 3160 | "Opts: %s%s%s", descr, sbi->s_es->s_mount_opts, |
3161 | *sbi->s_es->s_mount_opts ? "; " : "", orig_data); | ||
3162 | |||
3163 | init_timer(&sbi->s_err_report); | ||
3164 | sbi->s_err_report.function = print_daily_error_info; | ||
3165 | sbi->s_err_report.data = (unsigned long) sb; | ||
3166 | if (es->s_error_count) | ||
3167 | mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */ | ||
3047 | 3168 | ||
3048 | lock_kernel(); | 3169 | lock_kernel(); |
3049 | kfree(orig_data); | 3170 | kfree(orig_data); |
@@ -3093,6 +3214,7 @@ out_fail: | |||
3093 | kfree(sbi->s_blockgroup_lock); | 3214 | kfree(sbi->s_blockgroup_lock); |
3094 | kfree(sbi); | 3215 | kfree(sbi); |
3095 | lock_kernel(); | 3216 | lock_kernel(); |
3217 | out_free_orig: | ||
3096 | kfree(orig_data); | 3218 | kfree(orig_data); |
3097 | return ret; | 3219 | return ret; |
3098 | } | 3220 | } |
@@ -3110,7 +3232,7 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal) | |||
3110 | journal->j_min_batch_time = sbi->s_min_batch_time; | 3232 | journal->j_min_batch_time = sbi->s_min_batch_time; |
3111 | journal->j_max_batch_time = sbi->s_max_batch_time; | 3233 | journal->j_max_batch_time = sbi->s_max_batch_time; |
3112 | 3234 | ||
3113 | spin_lock(&journal->j_state_lock); | 3235 | write_lock(&journal->j_state_lock); |
3114 | if (test_opt(sb, BARRIER)) | 3236 | if (test_opt(sb, BARRIER)) |
3115 | journal->j_flags |= JBD2_BARRIER; | 3237 | journal->j_flags |= JBD2_BARRIER; |
3116 | else | 3238 | else |
@@ -3119,7 +3241,7 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal) | |||
3119 | journal->j_flags |= JBD2_ABORT_ON_SYNCDATA_ERR; | 3241 | journal->j_flags |= JBD2_ABORT_ON_SYNCDATA_ERR; |
3120 | else | 3242 | else |
3121 | journal->j_flags &= ~JBD2_ABORT_ON_SYNCDATA_ERR; | 3243 | journal->j_flags &= ~JBD2_ABORT_ON_SYNCDATA_ERR; |
3122 | spin_unlock(&journal->j_state_lock); | 3244 | write_unlock(&journal->j_state_lock); |
3123 | } | 3245 | } |
3124 | 3246 | ||
3125 | static journal_t *ext4_get_journal(struct super_block *sb, | 3247 | static journal_t *ext4_get_journal(struct super_block *sb, |
@@ -3327,8 +3449,17 @@ static int ext4_load_journal(struct super_block *sb, | |||
3327 | 3449 | ||
3328 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) | 3450 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) |
3329 | err = jbd2_journal_wipe(journal, !really_read_only); | 3451 | err = jbd2_journal_wipe(journal, !really_read_only); |
3330 | if (!err) | 3452 | if (!err) { |
3453 | char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL); | ||
3454 | if (save) | ||
3455 | memcpy(save, ((char *) es) + | ||
3456 | EXT4_S_ERR_START, EXT4_S_ERR_LEN); | ||
3331 | err = jbd2_journal_load(journal); | 3457 | err = jbd2_journal_load(journal); |
3458 | if (save) | ||
3459 | memcpy(((char *) es) + EXT4_S_ERR_START, | ||
3460 | save, EXT4_S_ERR_LEN); | ||
3461 | kfree(save); | ||
3462 | } | ||
3332 | 3463 | ||
3333 | if (err) { | 3464 | if (err) { |
3334 | ext4_msg(sb, KERN_ERR, "error loading journal"); | 3465 | ext4_msg(sb, KERN_ERR, "error loading journal"); |
@@ -3384,10 +3515,14 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
3384 | */ | 3515 | */ |
3385 | if (!(sb->s_flags & MS_RDONLY)) | 3516 | if (!(sb->s_flags & MS_RDONLY)) |
3386 | es->s_wtime = cpu_to_le32(get_seconds()); | 3517 | es->s_wtime = cpu_to_le32(get_seconds()); |
3387 | es->s_kbytes_written = | 3518 | if (sb->s_bdev->bd_part) |
3388 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written + | 3519 | es->s_kbytes_written = |
3520 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written + | ||
3389 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - | 3521 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - |
3390 | EXT4_SB(sb)->s_sectors_written_start) >> 1)); | 3522 | EXT4_SB(sb)->s_sectors_written_start) >> 1)); |
3523 | else | ||
3524 | es->s_kbytes_written = | ||
3525 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); | ||
3391 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( | 3526 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( |
3392 | &EXT4_SB(sb)->s_freeblocks_counter)); | 3527 | &EXT4_SB(sb)->s_freeblocks_counter)); |
3393 | es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( | 3528 | es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( |
@@ -3491,7 +3626,7 @@ int ext4_force_commit(struct super_block *sb) | |||
3491 | 3626 | ||
3492 | journal = EXT4_SB(sb)->s_journal; | 3627 | journal = EXT4_SB(sb)->s_journal; |
3493 | if (journal) { | 3628 | if (journal) { |
3494 | vfs_check_frozen(sb, SB_FREEZE_WRITE); | 3629 | vfs_check_frozen(sb, SB_FREEZE_TRANS); |
3495 | ret = ext4_journal_force_commit(journal); | 3630 | ret = ext4_journal_force_commit(journal); |
3496 | } | 3631 | } |
3497 | 3632 | ||
@@ -3616,7 +3751,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3616 | } | 3751 | } |
3617 | 3752 | ||
3618 | if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) | 3753 | if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) |
3619 | ext4_abort(sb, __func__, "Abort forced by user"); | 3754 | ext4_abort(sb, "Abort forced by user"); |
3620 | 3755 | ||
3621 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 3756 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3622 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); | 3757 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
@@ -3981,6 +4116,18 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
3981 | return err; | 4116 | return err; |
3982 | } | 4117 | } |
3983 | 4118 | ||
4119 | static int ext4_quota_off(struct super_block *sb, int type) | ||
4120 | { | ||
4121 | /* Force all delayed allocation blocks to be allocated */ | ||
4122 | if (test_opt(sb, DELALLOC)) { | ||
4123 | down_read(&sb->s_umount); | ||
4124 | sync_filesystem(sb); | ||
4125 | up_read(&sb->s_umount); | ||
4126 | } | ||
4127 | |||
4128 | return dquot_quota_off(sb, type); | ||
4129 | } | ||
4130 | |||
3984 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | 4131 | /* Read data from quotafile - avoid pagecache and such because we cannot afford |
3985 | * acquiring the locks... As quota files are never truncated and quota code | 4132 | * acquiring the locks... As quota files are never truncated and quota code |
3986 | * itself serializes the operations (and noone else should touch the files) | 4133 | * itself serializes the operations (and noone else should touch the files) |
@@ -4030,7 +4177,6 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
4030 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); | 4177 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); |
4031 | int err = 0; | 4178 | int err = 0; |
4032 | int offset = off & (sb->s_blocksize - 1); | 4179 | int offset = off & (sb->s_blocksize - 1); |
4033 | int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; | ||
4034 | struct buffer_head *bh; | 4180 | struct buffer_head *bh; |
4035 | handle_t *handle = journal_current_handle(); | 4181 | handle_t *handle = journal_current_handle(); |
4036 | 4182 | ||
@@ -4055,24 +4201,16 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
4055 | bh = ext4_bread(handle, inode, blk, 1, &err); | 4201 | bh = ext4_bread(handle, inode, blk, 1, &err); |
4056 | if (!bh) | 4202 | if (!bh) |
4057 | goto out; | 4203 | goto out; |
4058 | if (journal_quota) { | 4204 | err = ext4_journal_get_write_access(handle, bh); |
4059 | err = ext4_journal_get_write_access(handle, bh); | 4205 | if (err) { |
4060 | if (err) { | 4206 | brelse(bh); |
4061 | brelse(bh); | 4207 | goto out; |
4062 | goto out; | ||
4063 | } | ||
4064 | } | 4208 | } |
4065 | lock_buffer(bh); | 4209 | lock_buffer(bh); |
4066 | memcpy(bh->b_data+offset, data, len); | 4210 | memcpy(bh->b_data+offset, data, len); |
4067 | flush_dcache_page(bh->b_page); | 4211 | flush_dcache_page(bh->b_page); |
4068 | unlock_buffer(bh); | 4212 | unlock_buffer(bh); |
4069 | if (journal_quota) | 4213 | err = ext4_handle_dirty_metadata(handle, NULL, bh); |
4070 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | ||
4071 | else { | ||
4072 | /* Always do at least ordered writes for quotas */ | ||
4073 | err = ext4_jbd2_file_inode(handle, inode); | ||
4074 | mark_buffer_dirty(bh); | ||
4075 | } | ||
4076 | brelse(bh); | 4214 | brelse(bh); |
4077 | out: | 4215 | out: |
4078 | if (err) { | 4216 | if (err) { |