1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * NILFS checkpoint file. 4 * 5 * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation. 6 * 7 * Written by Koji Sato. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/fs.h> 12 #include <linux/string.h> 13 #include <linux/buffer_head.h> 14 #include <linux/errno.h> 15 #include "mdt.h" 16 #include "cpfile.h" 17 18 19 static inline unsigned long 20 nilfs_cpfile_checkpoints_per_block(const struct inode *cpfile) 21 { 22 return NILFS_MDT(cpfile)->mi_entries_per_block; 23 } 24 25 /* block number from the beginning of the file */ 26 static unsigned long 27 nilfs_cpfile_get_blkoff(const struct inode *cpfile, __u64 cno) 28 { 29 __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; 30 31 tcno = div64_ul(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); 32 return (unsigned long)tcno; 33 } 34 35 /* offset in block */ 36 static unsigned long 37 nilfs_cpfile_get_offset(const struct inode *cpfile, __u64 cno) 38 { 39 __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; 40 41 return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); 42 } 43 44 static __u64 nilfs_cpfile_first_checkpoint_in_block(const struct inode *cpfile, 45 unsigned long blkoff) 46 { 47 return (__u64)nilfs_cpfile_checkpoints_per_block(cpfile) * blkoff 48 + 1 - NILFS_MDT(cpfile)->mi_first_entry_offset; 49 } 50 51 static unsigned long 52 nilfs_cpfile_checkpoints_in_block(const struct inode *cpfile, 53 __u64 curr, 54 __u64 max) 55 { 56 return min_t(__u64, 57 nilfs_cpfile_checkpoints_per_block(cpfile) - 58 nilfs_cpfile_get_offset(cpfile, curr), 59 max - curr); 60 } 61 62 static inline int nilfs_cpfile_is_in_first(const struct inode *cpfile, 63 __u64 cno) 64 { 65 return nilfs_cpfile_get_blkoff(cpfile, cno) == 0; 66 } 67 68 static unsigned int 69 nilfs_cpfile_block_add_valid_checkpoints(const struct inode *cpfile, 70 struct buffer_head *bh, 71 unsigned int n) 72 { 73 struct nilfs_checkpoint *cp; 74 unsigned int count; 75 76 cp = kmap_local_folio(bh->b_folio, 77 offset_in_folio(bh->b_folio, bh->b_data)); 78 count = le32_to_cpu(cp->cp_checkpoints_count) + n; 79 cp->cp_checkpoints_count = cpu_to_le32(count); 80 kunmap_local(cp); 81 return count; 82 } 83 84 static unsigned int 85 nilfs_cpfile_block_sub_valid_checkpoints(const struct inode *cpfile, 86 struct buffer_head *bh, 87 unsigned int n) 88 { 89 struct nilfs_checkpoint *cp; 90 unsigned int count; 91 92 cp = kmap_local_folio(bh->b_folio, 93 offset_in_folio(bh->b_folio, bh->b_data)); 94 WARN_ON(le32_to_cpu(cp->cp_checkpoints_count) < n); 95 count = le32_to_cpu(cp->cp_checkpoints_count) - n; 96 cp->cp_checkpoints_count = cpu_to_le32(count); 97 kunmap_local(cp); 98 return count; 99 } 100 101 static void nilfs_cpfile_block_init(struct inode *cpfile, 102 struct buffer_head *bh, 103 void *from) 104 { 105 struct nilfs_checkpoint *cp = from; 106 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 107 int n = nilfs_cpfile_checkpoints_per_block(cpfile); 108 109 while (n-- > 0) { 110 nilfs_checkpoint_set_invalid(cp); 111 cp = (void *)cp + cpsz; 112 } 113 } 114 115 /** 116 * nilfs_cpfile_checkpoint_offset - calculate the byte offset of a checkpoint 117 * entry in the folio containing it 118 * @cpfile: checkpoint file inode 119 * @cno: checkpoint number 120 * @bh: buffer head of block containing checkpoint indexed by @cno 121 * 122 * Return: Byte offset in the folio of the checkpoint specified by @cno. 123 */ 124 static size_t nilfs_cpfile_checkpoint_offset(const struct inode *cpfile, 125 __u64 cno, 126 struct buffer_head *bh) 127 { 128 return offset_in_folio(bh->b_folio, bh->b_data) + 129 nilfs_cpfile_get_offset(cpfile, cno) * 130 NILFS_MDT(cpfile)->mi_entry_size; 131 } 132 133 /** 134 * nilfs_cpfile_cp_snapshot_list_offset - calculate the byte offset of a 135 * checkpoint snapshot list in the folio 136 * containing it 137 * @cpfile: checkpoint file inode 138 * @cno: checkpoint number 139 * @bh: buffer head of block containing checkpoint indexed by @cno 140 * 141 * Return: Byte offset in the folio of the checkpoint snapshot list specified 142 * by @cno. 143 */ 144 static size_t nilfs_cpfile_cp_snapshot_list_offset(const struct inode *cpfile, 145 __u64 cno, 146 struct buffer_head *bh) 147 { 148 return nilfs_cpfile_checkpoint_offset(cpfile, cno, bh) + 149 offsetof(struct nilfs_checkpoint, cp_snapshot_list); 150 } 151 152 /** 153 * nilfs_cpfile_ch_snapshot_list_offset - calculate the byte offset of the 154 * snapshot list in the header 155 * 156 * Return: Byte offset in the folio of the checkpoint snapshot list 157 */ 158 static size_t nilfs_cpfile_ch_snapshot_list_offset(void) 159 { 160 return offsetof(struct nilfs_cpfile_header, ch_snapshot_list); 161 } 162 163 static int nilfs_cpfile_get_header_block(struct inode *cpfile, 164 struct buffer_head **bhp) 165 { 166 int err = nilfs_mdt_get_block(cpfile, 0, 0, NULL, bhp); 167 168 if (unlikely(err == -ENOENT)) { 169 nilfs_error(cpfile->i_sb, 170 "missing header block in checkpoint metadata"); 171 err = -EIO; 172 } 173 return err; 174 } 175 176 static inline int nilfs_cpfile_get_checkpoint_block(struct inode *cpfile, 177 __u64 cno, 178 int create, 179 struct buffer_head **bhp) 180 { 181 return nilfs_mdt_get_block(cpfile, 182 nilfs_cpfile_get_blkoff(cpfile, cno), 183 create, nilfs_cpfile_block_init, bhp); 184 } 185 186 /** 187 * nilfs_cpfile_find_checkpoint_block - find and get a buffer on cpfile 188 * @cpfile: inode of cpfile 189 * @start_cno: start checkpoint number (inclusive) 190 * @end_cno: end checkpoint number (inclusive) 191 * @cnop: place to store the next checkpoint number 192 * @bhp: place to store a pointer to buffer_head struct 193 * 194 * Return: 0 on success, or one of the following negative error codes on 195 * failure: 196 * * %-EIO - I/O error (including metadata corruption). 197 * * %-ENOENT - no block exists in the range. 198 * * %-ENOMEM - Insufficient memory available. 199 */ 200 static int nilfs_cpfile_find_checkpoint_block(struct inode *cpfile, 201 __u64 start_cno, __u64 end_cno, 202 __u64 *cnop, 203 struct buffer_head **bhp) 204 { 205 unsigned long start, end, blkoff; 206 int ret; 207 208 if (unlikely(start_cno > end_cno)) 209 return -ENOENT; 210 211 start = nilfs_cpfile_get_blkoff(cpfile, start_cno); 212 end = nilfs_cpfile_get_blkoff(cpfile, end_cno); 213 214 ret = nilfs_mdt_find_block(cpfile, start, end, &blkoff, bhp); 215 if (!ret) 216 *cnop = (blkoff == start) ? start_cno : 217 nilfs_cpfile_first_checkpoint_in_block(cpfile, blkoff); 218 return ret; 219 } 220 221 static inline int nilfs_cpfile_delete_checkpoint_block(struct inode *cpfile, 222 __u64 cno) 223 { 224 return nilfs_mdt_delete_block(cpfile, 225 nilfs_cpfile_get_blkoff(cpfile, cno)); 226 } 227 228 /** 229 * nilfs_cpfile_read_checkpoint - read a checkpoint entry in cpfile 230 * @cpfile: checkpoint file inode 231 * @cno: number of checkpoint entry to read 232 * @root: nilfs root object 233 * @ifile: ifile's inode to read and attach to @root 234 * 235 * This function imports checkpoint information from the checkpoint file and 236 * stores it to the inode file given by @ifile and the nilfs root object 237 * given by @root. 238 * 239 * Return: 0 on success, or one of the following negative error codes on 240 * failure: 241 * * %-EINVAL - Invalid checkpoint. 242 * * %-ENOMEM - Insufficient memory available. 243 * * %-EIO - I/O error (including metadata corruption). 244 */ 245 int nilfs_cpfile_read_checkpoint(struct inode *cpfile, __u64 cno, 246 struct nilfs_root *root, struct inode *ifile) 247 { 248 struct buffer_head *cp_bh; 249 struct nilfs_checkpoint *cp; 250 size_t offset; 251 int ret; 252 253 if (cno < 1 || cno > nilfs_mdt_cno(cpfile)) 254 return -EINVAL; 255 256 down_read(&NILFS_MDT(cpfile)->mi_sem); 257 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 258 if (unlikely(ret < 0)) { 259 if (ret == -ENOENT) 260 ret = -EINVAL; 261 goto out_sem; 262 } 263 264 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 265 cp = kmap_local_folio(cp_bh->b_folio, offset); 266 if (nilfs_checkpoint_invalid(cp)) { 267 ret = -EINVAL; 268 goto put_cp; 269 } 270 271 ret = nilfs_read_inode_common(ifile, &cp->cp_ifile_inode); 272 if (unlikely(ret)) { 273 /* 274 * Since this inode is on a checkpoint entry, treat errors 275 * as metadata corruption. 276 */ 277 nilfs_err(cpfile->i_sb, 278 "ifile inode (checkpoint number=%llu) corrupted", 279 (unsigned long long)cno); 280 ret = -EIO; 281 goto put_cp; 282 } 283 284 /* Configure the nilfs root object */ 285 atomic64_set(&root->inodes_count, le64_to_cpu(cp->cp_inodes_count)); 286 atomic64_set(&root->blocks_count, le64_to_cpu(cp->cp_blocks_count)); 287 root->ifile = ifile; 288 289 put_cp: 290 kunmap_local(cp); 291 brelse(cp_bh); 292 out_sem: 293 up_read(&NILFS_MDT(cpfile)->mi_sem); 294 return ret; 295 } 296 297 /** 298 * nilfs_cpfile_create_checkpoint - create a checkpoint entry on cpfile 299 * @cpfile: checkpoint file inode 300 * @cno: number of checkpoint to set up 301 * 302 * This function creates a checkpoint with the number specified by @cno on 303 * cpfile. If the specified checkpoint entry already exists due to a past 304 * failure, it will be reused without returning an error. 305 * In either case, the buffer of the block containing the checkpoint entry 306 * and the cpfile inode are made dirty for inclusion in the write log. 307 * 308 * Return: 0 on success, or one of the following negative error codes on 309 * failure: 310 * * %-ENOMEM - Insufficient memory available. 311 * * %-EIO - I/O error (including metadata corruption). 312 * * %-EROFS - Read only filesystem 313 */ 314 int nilfs_cpfile_create_checkpoint(struct inode *cpfile, __u64 cno) 315 { 316 struct buffer_head *header_bh, *cp_bh; 317 struct nilfs_cpfile_header *header; 318 struct nilfs_checkpoint *cp; 319 size_t offset; 320 int ret; 321 322 if (WARN_ON_ONCE(cno < 1)) 323 return -EIO; 324 325 down_write(&NILFS_MDT(cpfile)->mi_sem); 326 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 327 if (unlikely(ret < 0)) 328 goto out_sem; 329 330 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 1, &cp_bh); 331 if (unlikely(ret < 0)) 332 goto out_header; 333 334 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 335 cp = kmap_local_folio(cp_bh->b_folio, offset); 336 if (nilfs_checkpoint_invalid(cp)) { 337 /* a newly-created checkpoint */ 338 nilfs_checkpoint_clear_invalid(cp); 339 kunmap_local(cp); 340 if (!nilfs_cpfile_is_in_first(cpfile, cno)) 341 nilfs_cpfile_block_add_valid_checkpoints(cpfile, cp_bh, 342 1); 343 344 header = kmap_local_folio(header_bh->b_folio, 0); 345 le64_add_cpu(&header->ch_ncheckpoints, 1); 346 kunmap_local(header); 347 mark_buffer_dirty(header_bh); 348 } else { 349 kunmap_local(cp); 350 } 351 352 /* Force the buffer and the inode to become dirty */ 353 mark_buffer_dirty(cp_bh); 354 brelse(cp_bh); 355 nilfs_mdt_mark_dirty(cpfile); 356 357 out_header: 358 brelse(header_bh); 359 360 out_sem: 361 up_write(&NILFS_MDT(cpfile)->mi_sem); 362 return ret; 363 } 364 365 /** 366 * nilfs_cpfile_finalize_checkpoint - fill in a checkpoint entry in cpfile 367 * @cpfile: checkpoint file inode 368 * @cno: checkpoint number 369 * @root: nilfs root object 370 * @blkinc: number of blocks added by this checkpoint 371 * @ctime: checkpoint creation time 372 * @minor: minor checkpoint flag 373 * 374 * This function completes the checkpoint entry numbered by @cno in the 375 * cpfile with the data given by the arguments @root, @blkinc, @ctime, and 376 * @minor. 377 * 378 * Return: 0 on success, or one of the following negative error codes on 379 * failure: 380 * * %-ENOMEM - Insufficient memory available. 381 * * %-EIO - I/O error (including metadata corruption). 382 */ 383 int nilfs_cpfile_finalize_checkpoint(struct inode *cpfile, __u64 cno, 384 struct nilfs_root *root, __u64 blkinc, 385 time64_t ctime, bool minor) 386 { 387 struct buffer_head *cp_bh; 388 struct nilfs_checkpoint *cp; 389 size_t offset; 390 int ret; 391 392 if (WARN_ON_ONCE(cno < 1)) 393 return -EIO; 394 395 down_write(&NILFS_MDT(cpfile)->mi_sem); 396 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 397 if (unlikely(ret < 0)) { 398 if (ret == -ENOENT) 399 goto error; 400 goto out_sem; 401 } 402 403 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 404 cp = kmap_local_folio(cp_bh->b_folio, offset); 405 if (unlikely(nilfs_checkpoint_invalid(cp))) { 406 kunmap_local(cp); 407 brelse(cp_bh); 408 goto error; 409 } 410 411 cp->cp_snapshot_list.ssl_next = 0; 412 cp->cp_snapshot_list.ssl_prev = 0; 413 cp->cp_inodes_count = cpu_to_le64(atomic64_read(&root->inodes_count)); 414 cp->cp_blocks_count = cpu_to_le64(atomic64_read(&root->blocks_count)); 415 cp->cp_nblk_inc = cpu_to_le64(blkinc); 416 cp->cp_create = cpu_to_le64(ctime); 417 cp->cp_cno = cpu_to_le64(cno); 418 419 if (minor) 420 nilfs_checkpoint_set_minor(cp); 421 else 422 nilfs_checkpoint_clear_minor(cp); 423 424 nilfs_write_inode_common(root->ifile, &cp->cp_ifile_inode); 425 nilfs_bmap_write(NILFS_I(root->ifile)->i_bmap, &cp->cp_ifile_inode); 426 427 kunmap_local(cp); 428 brelse(cp_bh); 429 out_sem: 430 up_write(&NILFS_MDT(cpfile)->mi_sem); 431 return ret; 432 433 error: 434 nilfs_error(cpfile->i_sb, 435 "checkpoint finalization failed due to metadata corruption."); 436 ret = -EIO; 437 goto out_sem; 438 } 439 440 /** 441 * nilfs_cpfile_delete_checkpoints - delete checkpoints 442 * @cpfile: inode of checkpoint file 443 * @start: start checkpoint number 444 * @end: end checkpoint number 445 * 446 * Description: nilfs_cpfile_delete_checkpoints() deletes the checkpoints in 447 * the period from @start to @end, excluding @end itself. The checkpoints 448 * which have been already deleted are ignored. 449 * 450 * Return: 0 on success, or one of the following negative error codes on 451 * failure: 452 * * %-EINVAL - Invalid checkpoints. 453 * * %-EIO - I/O error (including metadata corruption). 454 * * %-ENOMEM - Insufficient memory available. 455 */ 456 int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, 457 __u64 start, 458 __u64 end) 459 { 460 struct buffer_head *header_bh, *cp_bh; 461 struct nilfs_cpfile_header *header; 462 struct nilfs_checkpoint *cp; 463 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 464 __u64 cno; 465 size_t offset; 466 void *kaddr; 467 unsigned long tnicps; 468 int ret, ncps, nicps, nss, count, i; 469 470 if (unlikely(start == 0 || start > end)) { 471 nilfs_err(cpfile->i_sb, 472 "cannot delete checkpoints: invalid range [%llu, %llu)", 473 (unsigned long long)start, (unsigned long long)end); 474 return -EINVAL; 475 } 476 477 down_write(&NILFS_MDT(cpfile)->mi_sem); 478 479 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 480 if (ret < 0) 481 goto out_sem; 482 tnicps = 0; 483 nss = 0; 484 485 for (cno = start; cno < end; cno += ncps) { 486 ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, end); 487 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 488 if (ret < 0) { 489 if (ret != -ENOENT) 490 break; 491 /* skip hole */ 492 ret = 0; 493 continue; 494 } 495 496 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 497 cp = kaddr = kmap_local_folio(cp_bh->b_folio, offset); 498 nicps = 0; 499 for (i = 0; i < ncps; i++, cp = (void *)cp + cpsz) { 500 if (nilfs_checkpoint_snapshot(cp)) { 501 nss++; 502 } else if (!nilfs_checkpoint_invalid(cp)) { 503 nilfs_checkpoint_set_invalid(cp); 504 nicps++; 505 } 506 } 507 kunmap_local(kaddr); 508 509 if (nicps <= 0) { 510 brelse(cp_bh); 511 continue; 512 } 513 514 tnicps += nicps; 515 mark_buffer_dirty(cp_bh); 516 nilfs_mdt_mark_dirty(cpfile); 517 if (nilfs_cpfile_is_in_first(cpfile, cno)) { 518 brelse(cp_bh); 519 continue; 520 } 521 522 count = nilfs_cpfile_block_sub_valid_checkpoints(cpfile, cp_bh, 523 nicps); 524 brelse(cp_bh); 525 if (count) 526 continue; 527 528 /* Delete the block if there are no more valid checkpoints */ 529 ret = nilfs_cpfile_delete_checkpoint_block(cpfile, cno); 530 if (unlikely(ret)) { 531 nilfs_err(cpfile->i_sb, 532 "error %d deleting checkpoint block", ret); 533 break; 534 } 535 } 536 537 if (tnicps > 0) { 538 header = kmap_local_folio(header_bh->b_folio, 0); 539 le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps); 540 mark_buffer_dirty(header_bh); 541 nilfs_mdt_mark_dirty(cpfile); 542 kunmap_local(header); 543 } 544 545 brelse(header_bh); 546 if (nss > 0) 547 ret = -EBUSY; 548 549 out_sem: 550 up_write(&NILFS_MDT(cpfile)->mi_sem); 551 return ret; 552 } 553 554 static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile, 555 struct nilfs_checkpoint *cp, 556 struct nilfs_cpinfo *ci) 557 { 558 ci->ci_flags = le32_to_cpu(cp->cp_flags); 559 ci->ci_cno = le64_to_cpu(cp->cp_cno); 560 ci->ci_create = le64_to_cpu(cp->cp_create); 561 ci->ci_nblk_inc = le64_to_cpu(cp->cp_nblk_inc); 562 ci->ci_inodes_count = le64_to_cpu(cp->cp_inodes_count); 563 ci->ci_blocks_count = le64_to_cpu(cp->cp_blocks_count); 564 ci->ci_next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 565 } 566 567 static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, 568 void *buf, unsigned int cisz, 569 size_t nci) 570 { 571 struct nilfs_checkpoint *cp; 572 struct nilfs_cpinfo *ci = buf; 573 struct buffer_head *bh; 574 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 575 __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop; 576 size_t offset; 577 void *kaddr; 578 int n, ret; 579 int ncps, i; 580 581 if (cno == 0) 582 return -ENOENT; /* checkpoint number 0 is invalid */ 583 down_read(&NILFS_MDT(cpfile)->mi_sem); 584 585 for (n = 0; n < nci; cno += ncps) { 586 ret = nilfs_cpfile_find_checkpoint_block( 587 cpfile, cno, cur_cno - 1, &cno, &bh); 588 if (ret < 0) { 589 if (likely(ret == -ENOENT)) 590 break; 591 goto out; 592 } 593 ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno); 594 595 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, bh); 596 cp = kaddr = kmap_local_folio(bh->b_folio, offset); 597 for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) { 598 if (!nilfs_checkpoint_invalid(cp)) { 599 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, 600 ci); 601 ci = (void *)ci + cisz; 602 n++; 603 } 604 } 605 kunmap_local(kaddr); 606 brelse(bh); 607 } 608 609 ret = n; 610 if (n > 0) { 611 ci = (void *)ci - cisz; 612 *cnop = ci->ci_cno + 1; 613 } 614 615 out: 616 up_read(&NILFS_MDT(cpfile)->mi_sem); 617 return ret; 618 } 619 620 static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, 621 void *buf, unsigned int cisz, 622 size_t nci) 623 { 624 struct buffer_head *bh; 625 struct nilfs_cpfile_header *header; 626 struct nilfs_checkpoint *cp; 627 struct nilfs_cpinfo *ci = buf; 628 __u64 curr = *cnop, next; 629 unsigned long curr_blkoff, next_blkoff; 630 size_t offset; 631 int n = 0, ret; 632 633 down_read(&NILFS_MDT(cpfile)->mi_sem); 634 635 if (curr == 0) { 636 ret = nilfs_cpfile_get_header_block(cpfile, &bh); 637 if (ret < 0) 638 goto out; 639 header = kmap_local_folio(bh->b_folio, 0); 640 curr = le64_to_cpu(header->ch_snapshot_list.ssl_next); 641 kunmap_local(header); 642 brelse(bh); 643 if (curr == 0) { 644 ret = 0; 645 goto out; 646 } 647 } else if (unlikely(curr == ~(__u64)0)) { 648 ret = 0; 649 goto out; 650 } 651 652 curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr); 653 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh); 654 if (unlikely(ret < 0)) { 655 if (ret == -ENOENT) 656 ret = 0; /* No snapshots (started from a hole block) */ 657 goto out; 658 } 659 offset = nilfs_cpfile_checkpoint_offset(cpfile, curr, bh); 660 cp = kmap_local_folio(bh->b_folio, offset); 661 while (n < nci) { 662 curr = ~(__u64)0; /* Terminator */ 663 if (unlikely(nilfs_checkpoint_invalid(cp) || 664 !nilfs_checkpoint_snapshot(cp))) 665 break; 666 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, ci); 667 ci = (void *)ci + cisz; 668 n++; 669 next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 670 if (next == 0) 671 break; /* reach end of the snapshot list */ 672 673 kunmap_local(cp); 674 next_blkoff = nilfs_cpfile_get_blkoff(cpfile, next); 675 if (curr_blkoff != next_blkoff) { 676 brelse(bh); 677 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 678 0, &bh); 679 if (unlikely(ret < 0)) { 680 WARN_ON(ret == -ENOENT); 681 goto out; 682 } 683 } 684 offset = nilfs_cpfile_checkpoint_offset(cpfile, next, bh); 685 cp = kmap_local_folio(bh->b_folio, offset); 686 curr = next; 687 curr_blkoff = next_blkoff; 688 } 689 kunmap_local(cp); 690 brelse(bh); 691 *cnop = curr; 692 ret = n; 693 694 out: 695 up_read(&NILFS_MDT(cpfile)->mi_sem); 696 return ret; 697 } 698 699 /** 700 * nilfs_cpfile_get_cpinfo - get information on checkpoints 701 * @cpfile: checkpoint file inode 702 * @cnop: place to pass a starting checkpoint number and receive a 703 * checkpoint number to continue the search 704 * @mode: mode of checkpoints that the caller wants to retrieve 705 * @buf: buffer for storing checkpoints' information 706 * @cisz: byte size of one checkpoint info item in array 707 * @nci: number of checkpoint info items to retrieve 708 * 709 * nilfs_cpfile_get_cpinfo() searches for checkpoints in @mode state 710 * starting from the checkpoint number stored in @cnop, and stores 711 * information about found checkpoints in @buf. 712 * The buffer pointed to by @buf must be large enough to store information 713 * for @nci checkpoints. If at least one checkpoint information is 714 * successfully retrieved, @cnop is updated to point to the checkpoint 715 * number to continue searching. 716 * 717 * Return: Count of checkpoint info items stored in the output buffer on 718 * success, or one of the following negative error codes on failure: 719 * * %-EINVAL - Invalid checkpoint mode. 720 * * %-ENOMEM - Insufficient memory available. 721 * * %-EIO - I/O error (including metadata corruption). 722 * * %-ENOENT - Invalid checkpoint number specified. 723 */ 724 725 ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode, 726 void *buf, unsigned int cisz, size_t nci) 727 { 728 switch (mode) { 729 case NILFS_CHECKPOINT: 730 return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, buf, cisz, nci); 731 case NILFS_SNAPSHOT: 732 return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, buf, cisz, nci); 733 default: 734 return -EINVAL; 735 } 736 } 737 738 /** 739 * nilfs_cpfile_delete_checkpoint - delete a checkpoint 740 * @cpfile: checkpoint file inode 741 * @cno: checkpoint number to delete 742 * 743 * Return: 0 on success, or one of the following negative error codes on 744 * failure: 745 * * %-EBUSY - Checkpoint in use (snapshot specified). 746 * * %-EIO - I/O error (including metadata corruption). 747 * * %-ENOENT - No valid checkpoint found. 748 * * %-ENOMEM - Insufficient memory available. 749 */ 750 int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno) 751 { 752 struct nilfs_cpinfo ci; 753 __u64 tcno = cno; 754 ssize_t nci; 755 756 nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, sizeof(ci), 1); 757 if (nci < 0) 758 return nci; 759 else if (nci == 0 || ci.ci_cno != cno) 760 return -ENOENT; 761 else if (nilfs_cpinfo_snapshot(&ci)) 762 return -EBUSY; 763 764 return nilfs_cpfile_delete_checkpoints(cpfile, cno, cno + 1); 765 } 766 767 static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno) 768 { 769 struct buffer_head *header_bh, *curr_bh, *prev_bh, *cp_bh; 770 struct nilfs_cpfile_header *header; 771 struct nilfs_checkpoint *cp; 772 struct nilfs_snapshot_list *list; 773 __u64 curr, prev; 774 unsigned long curr_blkoff, prev_blkoff; 775 size_t offset, curr_list_offset, prev_list_offset; 776 int ret; 777 778 if (cno == 0) 779 return -ENOENT; /* checkpoint number 0 is invalid */ 780 down_write(&NILFS_MDT(cpfile)->mi_sem); 781 782 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 783 if (unlikely(ret < 0)) 784 goto out_sem; 785 786 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 787 if (ret < 0) 788 goto out_header; 789 790 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 791 cp = kmap_local_folio(cp_bh->b_folio, offset); 792 if (nilfs_checkpoint_invalid(cp)) { 793 ret = -ENOENT; 794 kunmap_local(cp); 795 goto out_cp; 796 } 797 if (nilfs_checkpoint_snapshot(cp)) { 798 ret = 0; 799 kunmap_local(cp); 800 goto out_cp; 801 } 802 kunmap_local(cp); 803 804 /* 805 * Find the last snapshot before the checkpoint being changed to 806 * snapshot mode by going backwards through the snapshot list. 807 * Set "prev" to its checkpoint number, or 0 if not found. 808 */ 809 header = kmap_local_folio(header_bh->b_folio, 0); 810 list = &header->ch_snapshot_list; 811 curr_bh = header_bh; 812 get_bh(curr_bh); 813 curr = 0; 814 curr_blkoff = 0; 815 curr_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 816 prev = le64_to_cpu(list->ssl_prev); 817 while (prev > cno) { 818 prev_blkoff = nilfs_cpfile_get_blkoff(cpfile, prev); 819 curr = prev; 820 kunmap_local(list); 821 if (curr_blkoff != prev_blkoff) { 822 brelse(curr_bh); 823 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 824 0, &curr_bh); 825 if (unlikely(ret < 0)) 826 goto out_cp; 827 } 828 curr_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 829 cpfile, curr, curr_bh); 830 list = kmap_local_folio(curr_bh->b_folio, curr_list_offset); 831 curr_blkoff = prev_blkoff; 832 prev = le64_to_cpu(list->ssl_prev); 833 } 834 kunmap_local(list); 835 836 if (prev != 0) { 837 ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0, 838 &prev_bh); 839 if (ret < 0) 840 goto out_curr; 841 842 prev_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 843 cpfile, prev, prev_bh); 844 } else { 845 prev_bh = header_bh; 846 get_bh(prev_bh); 847 prev_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 848 } 849 850 /* Update the list entry for the next snapshot */ 851 list = kmap_local_folio(curr_bh->b_folio, curr_list_offset); 852 list->ssl_prev = cpu_to_le64(cno); 853 kunmap_local(list); 854 855 /* Update the checkpoint being changed to a snapshot */ 856 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 857 cp = kmap_local_folio(cp_bh->b_folio, offset); 858 cp->cp_snapshot_list.ssl_next = cpu_to_le64(curr); 859 cp->cp_snapshot_list.ssl_prev = cpu_to_le64(prev); 860 nilfs_checkpoint_set_snapshot(cp); 861 kunmap_local(cp); 862 863 /* Update the list entry for the previous snapshot */ 864 list = kmap_local_folio(prev_bh->b_folio, prev_list_offset); 865 list->ssl_next = cpu_to_le64(cno); 866 kunmap_local(list); 867 868 /* Update the statistics in the header */ 869 header = kmap_local_folio(header_bh->b_folio, 0); 870 le64_add_cpu(&header->ch_nsnapshots, 1); 871 kunmap_local(header); 872 873 mark_buffer_dirty(prev_bh); 874 mark_buffer_dirty(curr_bh); 875 mark_buffer_dirty(cp_bh); 876 mark_buffer_dirty(header_bh); 877 nilfs_mdt_mark_dirty(cpfile); 878 879 brelse(prev_bh); 880 881 out_curr: 882 brelse(curr_bh); 883 884 out_cp: 885 brelse(cp_bh); 886 887 out_header: 888 brelse(header_bh); 889 890 out_sem: 891 up_write(&NILFS_MDT(cpfile)->mi_sem); 892 return ret; 893 } 894 895 static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno) 896 { 897 struct buffer_head *header_bh, *next_bh, *prev_bh, *cp_bh; 898 struct nilfs_cpfile_header *header; 899 struct nilfs_checkpoint *cp; 900 struct nilfs_snapshot_list *list; 901 __u64 next, prev; 902 size_t offset, next_list_offset, prev_list_offset; 903 int ret; 904 905 if (cno == 0) 906 return -ENOENT; /* checkpoint number 0 is invalid */ 907 down_write(&NILFS_MDT(cpfile)->mi_sem); 908 909 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 910 if (unlikely(ret < 0)) 911 goto out_sem; 912 913 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 914 if (ret < 0) 915 goto out_header; 916 917 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 918 cp = kmap_local_folio(cp_bh->b_folio, offset); 919 if (nilfs_checkpoint_invalid(cp)) { 920 ret = -ENOENT; 921 kunmap_local(cp); 922 goto out_cp; 923 } 924 if (!nilfs_checkpoint_snapshot(cp)) { 925 ret = 0; 926 kunmap_local(cp); 927 goto out_cp; 928 } 929 930 list = &cp->cp_snapshot_list; 931 next = le64_to_cpu(list->ssl_next); 932 prev = le64_to_cpu(list->ssl_prev); 933 kunmap_local(cp); 934 935 if (next != 0) { 936 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 0, 937 &next_bh); 938 if (ret < 0) 939 goto out_cp; 940 941 next_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 942 cpfile, next, next_bh); 943 } else { 944 next_bh = header_bh; 945 get_bh(next_bh); 946 next_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 947 } 948 if (prev != 0) { 949 ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0, 950 &prev_bh); 951 if (ret < 0) 952 goto out_next; 953 954 prev_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 955 cpfile, prev, prev_bh); 956 } else { 957 prev_bh = header_bh; 958 get_bh(prev_bh); 959 prev_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 960 } 961 962 /* Update the list entry for the next snapshot */ 963 list = kmap_local_folio(next_bh->b_folio, next_list_offset); 964 list->ssl_prev = cpu_to_le64(prev); 965 kunmap_local(list); 966 967 /* Update the list entry for the previous snapshot */ 968 list = kmap_local_folio(prev_bh->b_folio, prev_list_offset); 969 list->ssl_next = cpu_to_le64(next); 970 kunmap_local(list); 971 972 /* Update the snapshot being changed back to a plain checkpoint */ 973 cp = kmap_local_folio(cp_bh->b_folio, offset); 974 cp->cp_snapshot_list.ssl_next = cpu_to_le64(0); 975 cp->cp_snapshot_list.ssl_prev = cpu_to_le64(0); 976 nilfs_checkpoint_clear_snapshot(cp); 977 kunmap_local(cp); 978 979 /* Update the statistics in the header */ 980 header = kmap_local_folio(header_bh->b_folio, 0); 981 le64_add_cpu(&header->ch_nsnapshots, -1); 982 kunmap_local(header); 983 984 mark_buffer_dirty(next_bh); 985 mark_buffer_dirty(prev_bh); 986 mark_buffer_dirty(cp_bh); 987 mark_buffer_dirty(header_bh); 988 nilfs_mdt_mark_dirty(cpfile); 989 990 brelse(prev_bh); 991 992 out_next: 993 brelse(next_bh); 994 995 out_cp: 996 brelse(cp_bh); 997 998 out_header: 999 brelse(header_bh); 1000 1001 out_sem: 1002 up_write(&NILFS_MDT(cpfile)->mi_sem); 1003 return ret; 1004 } 1005 1006 /** 1007 * nilfs_cpfile_is_snapshot - determine if checkpoint is a snapshot 1008 * @cpfile: inode of checkpoint file 1009 * @cno: checkpoint number 1010 * 1011 * Return: 1 if the checkpoint specified by @cno is a snapshot, 0 if not, or 1012 * one of the following negative error codes on failure: 1013 * * %-EIO - I/O error (including metadata corruption). 1014 * * %-ENOENT - No such checkpoint. 1015 * * %-ENOMEM - Insufficient memory available. 1016 */ 1017 int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno) 1018 { 1019 struct buffer_head *bh; 1020 struct nilfs_checkpoint *cp; 1021 size_t offset; 1022 int ret; 1023 1024 /* 1025 * CP number is invalid if it's zero or larger than the 1026 * largest existing one. 1027 */ 1028 if (cno == 0 || cno >= nilfs_mdt_cno(cpfile)) 1029 return -ENOENT; 1030 down_read(&NILFS_MDT(cpfile)->mi_sem); 1031 1032 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh); 1033 if (ret < 0) 1034 goto out; 1035 1036 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, bh); 1037 cp = kmap_local_folio(bh->b_folio, offset); 1038 if (nilfs_checkpoint_invalid(cp)) 1039 ret = -ENOENT; 1040 else 1041 ret = nilfs_checkpoint_snapshot(cp); 1042 kunmap_local(cp); 1043 brelse(bh); 1044 1045 out: 1046 up_read(&NILFS_MDT(cpfile)->mi_sem); 1047 return ret; 1048 } 1049 1050 /** 1051 * nilfs_cpfile_change_cpmode - change checkpoint mode 1052 * @cpfile: inode of checkpoint file 1053 * @cno: checkpoint number 1054 * @mode: mode of checkpoint 1055 * 1056 * Description: nilfs_change_cpmode() changes the mode of the checkpoint 1057 * specified by @cno. The mode @mode is NILFS_CHECKPOINT or NILFS_SNAPSHOT. 1058 * 1059 * Return: 0 on success, or one of the following negative error codes on 1060 * failure: 1061 * * %-EIO - I/O error (including metadata corruption). 1062 * * %-ENOENT - No such checkpoint. 1063 * * %-ENOMEM - Insufficient memory available. 1064 */ 1065 int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode) 1066 { 1067 int ret; 1068 1069 switch (mode) { 1070 case NILFS_CHECKPOINT: 1071 if (nilfs_checkpoint_is_mounted(cpfile->i_sb, cno)) 1072 /* 1073 * Current implementation does not have to protect 1074 * plain read-only mounts since they are exclusive 1075 * with a read/write mount and are protected from the 1076 * cleaner. 1077 */ 1078 ret = -EBUSY; 1079 else 1080 ret = nilfs_cpfile_clear_snapshot(cpfile, cno); 1081 return ret; 1082 case NILFS_SNAPSHOT: 1083 return nilfs_cpfile_set_snapshot(cpfile, cno); 1084 default: 1085 return -EINVAL; 1086 } 1087 } 1088 1089 /** 1090 * nilfs_cpfile_get_stat - get checkpoint statistics 1091 * @cpfile: inode of checkpoint file 1092 * @cpstat: pointer to a structure of checkpoint statistics 1093 * 1094 * Description: nilfs_cpfile_get_stat() returns information about checkpoints. 1095 * The checkpoint statistics are stored in the location pointed to by @cpstat. 1096 * 1097 * Return: 0 on success, or one of the following negative error codes on 1098 * failure: 1099 * * %-EIO - I/O error (including metadata corruption). 1100 * * %-ENOMEM - Insufficient memory available. 1101 */ 1102 int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat) 1103 { 1104 struct buffer_head *bh; 1105 struct nilfs_cpfile_header *header; 1106 int ret; 1107 1108 down_read(&NILFS_MDT(cpfile)->mi_sem); 1109 1110 ret = nilfs_cpfile_get_header_block(cpfile, &bh); 1111 if (ret < 0) 1112 goto out_sem; 1113 header = kmap_local_folio(bh->b_folio, 0); 1114 cpstat->cs_cno = nilfs_mdt_cno(cpfile); 1115 cpstat->cs_ncps = le64_to_cpu(header->ch_ncheckpoints); 1116 cpstat->cs_nsss = le64_to_cpu(header->ch_nsnapshots); 1117 kunmap_local(header); 1118 brelse(bh); 1119 1120 out_sem: 1121 up_read(&NILFS_MDT(cpfile)->mi_sem); 1122 return ret; 1123 } 1124 1125 /** 1126 * nilfs_cpfile_read - read or get cpfile inode 1127 * @sb: super block instance 1128 * @cpsize: size of a checkpoint entry 1129 * @raw_inode: on-disk cpfile inode 1130 * @inodep: buffer to store the inode 1131 * 1132 * Return: 0 on success, or a negative error code on failure. 1133 */ 1134 int nilfs_cpfile_read(struct super_block *sb, size_t cpsize, 1135 struct nilfs_inode *raw_inode, struct inode **inodep) 1136 { 1137 struct inode *cpfile; 1138 int err; 1139 1140 if (cpsize > sb->s_blocksize) { 1141 nilfs_err(sb, "too large checkpoint size: %zu bytes", cpsize); 1142 return -EINVAL; 1143 } else if (cpsize < NILFS_MIN_CHECKPOINT_SIZE) { 1144 nilfs_err(sb, "too small checkpoint size: %zu bytes", cpsize); 1145 return -EINVAL; 1146 } 1147 1148 cpfile = nilfs_iget_locked(sb, NULL, NILFS_CPFILE_INO); 1149 if (unlikely(!cpfile)) 1150 return -ENOMEM; 1151 if (!(cpfile->i_state & I_NEW)) 1152 goto out; 1153 1154 err = nilfs_mdt_init(cpfile, NILFS_MDT_GFP, 0); 1155 if (err) 1156 goto failed; 1157 1158 nilfs_mdt_set_entry_size(cpfile, cpsize, 1159 sizeof(struct nilfs_cpfile_header)); 1160 1161 err = nilfs_read_inode_common(cpfile, raw_inode); 1162 if (err) 1163 goto failed; 1164 1165 unlock_new_inode(cpfile); 1166 out: 1167 *inodep = cpfile; 1168 return 0; 1169 failed: 1170 iget_failed(cpfile); 1171 return err; 1172 } 1173