| .. | .. |
|---|
| 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); |
|---|