.. | .. |
---|
373 | 373 | goto out; |
---|
374 | 374 | } |
---|
375 | 375 | nsbp = (void *)nsbh->b_data + offset; |
---|
376 | | - memset(nsbp, 0, nilfs->ns_blocksize); |
---|
| 376 | + |
---|
| 377 | + lock_buffer(nsbh); |
---|
| 378 | + if (sb2i >= 0) { |
---|
| 379 | + /* |
---|
| 380 | + * The position of the second superblock only changes by 4KiB, |
---|
| 381 | + * which is larger than the maximum superblock data size |
---|
| 382 | + * (= 1KiB), so there is no need to use memmove() to allow |
---|
| 383 | + * overlap between source and destination. |
---|
| 384 | + */ |
---|
| 385 | + memcpy(nsbp, nilfs->ns_sbp[sb2i], nilfs->ns_sbsize); |
---|
| 386 | + |
---|
| 387 | + /* |
---|
| 388 | + * Zero fill after copy to avoid overwriting in case of move |
---|
| 389 | + * within the same block. |
---|
| 390 | + */ |
---|
| 391 | + memset(nsbh->b_data, 0, offset); |
---|
| 392 | + memset((void *)nsbp + nilfs->ns_sbsize, 0, |
---|
| 393 | + nsbh->b_size - offset - nilfs->ns_sbsize); |
---|
| 394 | + } else { |
---|
| 395 | + memset(nsbh->b_data, 0, nsbh->b_size); |
---|
| 396 | + } |
---|
| 397 | + set_buffer_uptodate(nsbh); |
---|
| 398 | + unlock_buffer(nsbh); |
---|
377 | 399 | |
---|
378 | 400 | if (sb2i >= 0) { |
---|
379 | | - memcpy(nsbp, nilfs->ns_sbp[sb2i], nilfs->ns_sbsize); |
---|
380 | 401 | brelse(nilfs->ns_sbh[sb2i]); |
---|
381 | 402 | nilfs->ns_sbh[sb2i] = nsbh; |
---|
382 | 403 | nilfs->ns_sbp[sb2i] = nsbp; |
---|
.. | .. |
---|
408 | 429 | devsize = i_size_read(sb->s_bdev->bd_inode); |
---|
409 | 430 | if (newsize > devsize) |
---|
410 | 431 | goto out; |
---|
| 432 | + |
---|
| 433 | + /* |
---|
| 434 | + * Prevent underflow in second superblock position calculation. |
---|
| 435 | + * The exact minimum size check is done in nilfs_sufile_resize(). |
---|
| 436 | + */ |
---|
| 437 | + if (newsize < 4096) { |
---|
| 438 | + ret = -ENOSPC; |
---|
| 439 | + goto out; |
---|
| 440 | + } |
---|
411 | 441 | |
---|
412 | 442 | /* |
---|
413 | 443 | * Write lock is required to protect some functions depending |
---|
.. | .. |
---|
474 | 504 | up_write(&nilfs->ns_sem); |
---|
475 | 505 | } |
---|
476 | 506 | |
---|
| 507 | + nilfs_sysfs_delete_device_group(nilfs); |
---|
477 | 508 | iput(nilfs->ns_sufile); |
---|
478 | 509 | iput(nilfs->ns_cpfile); |
---|
479 | 510 | iput(nilfs->ns_dat); |
---|
.. | .. |
---|
1097 | 1128 | nilfs_put_root(fsroot); |
---|
1098 | 1129 | |
---|
1099 | 1130 | failed_unload: |
---|
| 1131 | + nilfs_sysfs_delete_device_group(nilfs); |
---|
1100 | 1132 | iput(nilfs->ns_sufile); |
---|
1101 | 1133 | iput(nilfs->ns_cpfile); |
---|
1102 | 1134 | iput(nilfs->ns_dat); |
---|