diff options
Diffstat (limited to 'fs/ext4/super.c')
| -rw-r--r-- | fs/ext4/super.c | 334 |
1 files changed, 236 insertions, 98 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e72d3235b2fd..8d65575f8c8c 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); |
| @@ -946,14 +1001,12 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 946 | seq_puts(seq, ",journal_async_commit"); | 1001 | seq_puts(seq, ",journal_async_commit"); |
| 947 | else if (test_opt(sb, JOURNAL_CHECKSUM)) | 1002 | else if (test_opt(sb, JOURNAL_CHECKSUM)) |
| 948 | seq_puts(seq, ",journal_checksum"); | 1003 | seq_puts(seq, ",journal_checksum"); |
| 949 | if (test_opt(sb, NOBH)) | ||
| 950 | seq_puts(seq, ",nobh"); | ||
| 951 | if (test_opt(sb, I_VERSION)) | 1004 | if (test_opt(sb, I_VERSION)) |
| 952 | seq_puts(seq, ",i_version"); | 1005 | seq_puts(seq, ",i_version"); |
| 953 | if (!test_opt(sb, DELALLOC)) | 1006 | if (!test_opt(sb, DELALLOC) && |
| 1007 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) | ||
| 954 | seq_puts(seq, ",nodelalloc"); | 1008 | seq_puts(seq, ",nodelalloc"); |
| 955 | 1009 | ||
| 956 | |||
| 957 | if (sbi->s_stripe) | 1010 | if (sbi->s_stripe) |
| 958 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | 1011 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); |
| 959 | /* | 1012 | /* |
| @@ -977,7 +1030,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 977 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) | 1030 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) |
| 978 | seq_puts(seq, ",noauto_da_alloc"); | 1031 | seq_puts(seq, ",noauto_da_alloc"); |
| 979 | 1032 | ||
| 980 | if (test_opt(sb, DISCARD)) | 1033 | if (test_opt(sb, DISCARD) && !(def_mount_opts & EXT4_DEFM_DISCARD)) |
| 981 | seq_puts(seq, ",discard"); | 1034 | seq_puts(seq, ",discard"); |
| 982 | 1035 | ||
| 983 | if (test_opt(sb, NOLOAD)) | 1036 | if (test_opt(sb, NOLOAD)) |
| @@ -986,6 +1039,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 986 | if (test_opt(sb, DIOREAD_NOLOCK)) | 1039 | if (test_opt(sb, DIOREAD_NOLOCK)) |
| 987 | seq_puts(seq, ",dioread_nolock"); | 1040 | seq_puts(seq, ",dioread_nolock"); |
| 988 | 1041 | ||
| 1042 | if (test_opt(sb, BLOCK_VALIDITY) && | ||
| 1043 | !(def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY)) | ||
| 1044 | seq_puts(seq, ",block_validity"); | ||
| 1045 | |||
| 989 | ext4_show_quota_options(seq, sb); | 1046 | ext4_show_quota_options(seq, sb); |
| 990 | 1047 | ||
| 991 | return 0; | 1048 | return 0; |
| @@ -1065,6 +1122,7 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot); | |||
| 1065 | static int ext4_write_info(struct super_block *sb, int type); | 1122 | static int ext4_write_info(struct super_block *sb, int type); |
| 1066 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, | 1123 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
| 1067 | char *path); | 1124 | char *path); |
| 1125 | static int ext4_quota_off(struct super_block *sb, int type); | ||
| 1068 | static int ext4_quota_on_mount(struct super_block *sb, int type); | 1126 | static int ext4_quota_on_mount(struct super_block *sb, int type); |
| 1069 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, | 1127 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, |
| 1070 | size_t len, loff_t off); | 1128 | size_t len, loff_t off); |
| @@ -1086,7 +1144,7 @@ static const struct dquot_operations ext4_quota_operations = { | |||
| 1086 | 1144 | ||
| 1087 | static const struct quotactl_ops ext4_qctl_operations = { | 1145 | static const struct quotactl_ops ext4_qctl_operations = { |
| 1088 | .quota_on = ext4_quota_on, | 1146 | .quota_on = ext4_quota_on, |
| 1089 | .quota_off = dquot_quota_off, | 1147 | .quota_off = ext4_quota_off, |
| 1090 | .quota_sync = dquot_quota_sync, | 1148 | .quota_sync = dquot_quota_sync, |
| 1091 | .get_info = dquot_get_dqinfo, | 1149 | .get_info = dquot_get_dqinfo, |
| 1092 | .set_info = dquot_set_dqinfo, | 1150 | .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"); |
| @@ -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) { |
