| .. | .. |
|---|
| 39 | 39 | * Write the MMP block using REQ_SYNC to try to get the block on-disk |
|---|
| 40 | 40 | * faster. |
|---|
| 41 | 41 | */ |
|---|
| 42 | | -static int write_mmp_block(struct super_block *sb, struct buffer_head *bh) |
|---|
| 42 | +static int write_mmp_block_thawed(struct super_block *sb, |
|---|
| 43 | + struct buffer_head *bh) |
|---|
| 43 | 44 | { |
|---|
| 44 | 45 | struct mmp_struct *mmp = (struct mmp_struct *)(bh->b_data); |
|---|
| 45 | 46 | |
|---|
| 46 | | - /* |
|---|
| 47 | | - * We protect against freezing so that we don't create dirty buffers |
|---|
| 48 | | - * on frozen filesystem. |
|---|
| 49 | | - */ |
|---|
| 50 | | - sb_start_write(sb); |
|---|
| 51 | 47 | ext4_mmp_csum_set(sb, mmp); |
|---|
| 52 | 48 | lock_buffer(bh); |
|---|
| 53 | 49 | bh->b_end_io = end_buffer_write_sync; |
|---|
| 54 | 50 | get_bh(bh); |
|---|
| 55 | 51 | submit_bh(REQ_OP_WRITE, REQ_SYNC | REQ_META | REQ_PRIO, bh); |
|---|
| 56 | 52 | wait_on_buffer(bh); |
|---|
| 57 | | - sb_end_write(sb); |
|---|
| 58 | 53 | if (unlikely(!buffer_uptodate(bh))) |
|---|
| 59 | 54 | return -EIO; |
|---|
| 60 | | - |
|---|
| 61 | 55 | return 0; |
|---|
| 56 | +} |
|---|
| 57 | + |
|---|
| 58 | +static int write_mmp_block(struct super_block *sb, struct buffer_head *bh) |
|---|
| 59 | +{ |
|---|
| 60 | + int err; |
|---|
| 61 | + |
|---|
| 62 | + /* |
|---|
| 63 | + * We protect against freezing so that we don't create dirty buffers |
|---|
| 64 | + * on frozen filesystem. |
|---|
| 65 | + */ |
|---|
| 66 | + sb_start_write(sb); |
|---|
| 67 | + err = write_mmp_block_thawed(sb, bh); |
|---|
| 68 | + sb_end_write(sb); |
|---|
| 69 | + return err; |
|---|
| 62 | 70 | } |
|---|
| 63 | 71 | |
|---|
| 64 | 72 | /* |
|---|
| .. | .. |
|---|
| 290 | 298 | if (mmp_block < le32_to_cpu(es->s_first_data_block) || |
|---|
| 291 | 299 | mmp_block >= ext4_blocks_count(es)) { |
|---|
| 292 | 300 | ext4_warning(sb, "Invalid MMP block in superblock"); |
|---|
| 301 | + retval = -EINVAL; |
|---|
| 293 | 302 | goto failed; |
|---|
| 294 | 303 | } |
|---|
| 295 | 304 | |
|---|
| .. | .. |
|---|
| 315 | 324 | |
|---|
| 316 | 325 | if (seq == EXT4_MMP_SEQ_FSCK) { |
|---|
| 317 | 326 | dump_mmp_msg(sb, mmp, "fsck is running on the filesystem"); |
|---|
| 327 | + retval = -EBUSY; |
|---|
| 318 | 328 | goto failed; |
|---|
| 319 | 329 | } |
|---|
| 320 | 330 | |
|---|
| .. | .. |
|---|
| 328 | 338 | |
|---|
| 329 | 339 | if (schedule_timeout_interruptible(HZ * wait_time) != 0) { |
|---|
| 330 | 340 | ext4_warning(sb, "MMP startup interrupted, failing mount\n"); |
|---|
| 341 | + retval = -ETIMEDOUT; |
|---|
| 331 | 342 | goto failed; |
|---|
| 332 | 343 | } |
|---|
| 333 | 344 | |
|---|
| .. | .. |
|---|
| 338 | 349 | if (seq != le32_to_cpu(mmp->mmp_seq)) { |
|---|
| 339 | 350 | dump_mmp_msg(sb, mmp, |
|---|
| 340 | 351 | "Device is already active on another node."); |
|---|
| 352 | + retval = -EBUSY; |
|---|
| 341 | 353 | goto failed; |
|---|
| 342 | 354 | } |
|---|
| 343 | 355 | |
|---|
| .. | .. |
|---|
| 348 | 360 | seq = mmp_new_seq(); |
|---|
| 349 | 361 | mmp->mmp_seq = cpu_to_le32(seq); |
|---|
| 350 | 362 | |
|---|
| 351 | | - retval = write_mmp_block(sb, bh); |
|---|
| 363 | + /* |
|---|
| 364 | + * On mount / remount we are protected against fs freezing (by s_umount |
|---|
| 365 | + * semaphore) and grabbing freeze protection upsets lockdep |
|---|
| 366 | + */ |
|---|
| 367 | + retval = write_mmp_block_thawed(sb, bh); |
|---|
| 352 | 368 | if (retval) |
|---|
| 353 | 369 | goto failed; |
|---|
| 354 | 370 | |
|---|
| .. | .. |
|---|
| 357 | 373 | */ |
|---|
| 358 | 374 | if (schedule_timeout_interruptible(HZ * wait_time) != 0) { |
|---|
| 359 | 375 | ext4_warning(sb, "MMP startup interrupted, failing mount"); |
|---|
| 376 | + retval = -ETIMEDOUT; |
|---|
| 360 | 377 | goto failed; |
|---|
| 361 | 378 | } |
|---|
| 362 | 379 | |
|---|
| .. | .. |
|---|
| 367 | 384 | if (seq != le32_to_cpu(mmp->mmp_seq)) { |
|---|
| 368 | 385 | dump_mmp_msg(sb, mmp, |
|---|
| 369 | 386 | "Device is already active on another node."); |
|---|
| 387 | + retval = -EBUSY; |
|---|
| 370 | 388 | goto failed; |
|---|
| 371 | 389 | } |
|---|
| 372 | 390 | |
|---|
| .. | .. |
|---|
| 383 | 401 | EXT4_SB(sb)->s_mmp_tsk = NULL; |
|---|
| 384 | 402 | ext4_warning(sb, "Unable to create kmmpd thread for %s.", |
|---|
| 385 | 403 | sb->s_id); |
|---|
| 404 | + retval = -ENOMEM; |
|---|
| 386 | 405 | goto failed; |
|---|
| 387 | 406 | } |
|---|
| 388 | 407 | |
|---|
| .. | .. |
|---|
| 390 | 409 | |
|---|
| 391 | 410 | failed: |
|---|
| 392 | 411 | brelse(bh); |
|---|
| 393 | | - return 1; |
|---|
| 412 | + return retval; |
|---|
| 394 | 413 | } |
|---|