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 Value: On success, it returns 0. On error, the following negative 195 * error code is returned. 196 * 197 * %-ENOMEM - Insufficient memory available. 198 * 199 * %-EIO - I/O error 200 * 201 * %-ENOENT - no block exists in the range. 202 */ 203 static int nilfs_cpfile_find_checkpoint_block(struct inode *cpfile, 204 __u64 start_cno, __u64 end_cno, 205 __u64 *cnop, 206 struct buffer_head **bhp) 207 { 208 unsigned long start, end, blkoff; 209 int ret; 210 211 if (unlikely(start_cno > end_cno)) 212 return -ENOENT; 213 214 start = nilfs_cpfile_get_blkoff(cpfile, start_cno); 215 end = nilfs_cpfile_get_blkoff(cpfile, end_cno); 216 217 ret = nilfs_mdt_find_block(cpfile, start, end, &blkoff, bhp); 218 if (!ret) 219 *cnop = (blkoff == start) ? start_cno : 220 nilfs_cpfile_first_checkpoint_in_block(cpfile, blkoff); 221 return ret; 222 } 223 224 static inline int nilfs_cpfile_delete_checkpoint_block(struct inode *cpfile, 225 __u64 cno) 226 { 227 return nilfs_mdt_delete_block(cpfile, 228 nilfs_cpfile_get_blkoff(cpfile, cno)); 229 } 230 231 /** 232 * nilfs_cpfile_read_checkpoint - read a checkpoint entry in cpfile 233 * @cpfile: checkpoint file inode 234 * @cno: number of checkpoint entry to read 235 * @root: nilfs root object 236 * @ifile: ifile's inode to read and attach to @root 237 * 238 * This function imports checkpoint information from the checkpoint file and 239 * stores it to the inode file given by @ifile and the nilfs root object 240 * given by @root. 241 * 242 * Return: 0 on success, or the following negative error code on failure. 243 * * %-EINVAL - Invalid checkpoint. 244 * * %-ENOMEM - Insufficient memory available. 245 * * %-EIO - I/O error (including metadata corruption). 246 */ 247 int nilfs_cpfile_read_checkpoint(struct inode *cpfile, __u64 cno, 248 struct nilfs_root *root, struct inode *ifile) 249 { 250 struct buffer_head *cp_bh; 251 struct nilfs_checkpoint *cp; 252 size_t offset; 253 int ret; 254 255 if (cno < 1 || cno > nilfs_mdt_cno(cpfile)) 256 return -EINVAL; 257 258 down_read(&NILFS_MDT(cpfile)->mi_sem); 259 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 260 if (unlikely(ret < 0)) { 261 if (ret == -ENOENT) 262 ret = -EINVAL; 263 goto out_sem; 264 } 265 266 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 267 cp = kmap_local_folio(cp_bh->b_folio, offset); 268 if (nilfs_checkpoint_invalid(cp)) { 269 ret = -EINVAL; 270 goto put_cp; 271 } 272 273 ret = nilfs_read_inode_common(ifile, &cp->cp_ifile_inode); 274 if (unlikely(ret)) { 275 /* 276 * Since this inode is on a checkpoint entry, treat errors 277 * as metadata corruption. 278 */ 279 nilfs_err(cpfile->i_sb, 280 "ifile inode (checkpoint number=%llu) corrupted", 281 (unsigned long long)cno); 282 ret = -EIO; 283 goto put_cp; 284 } 285 286 /* Configure the nilfs root object */ 287 atomic64_set(&root->inodes_count, le64_to_cpu(cp->cp_inodes_count)); 288 atomic64_set(&root->blocks_count, le64_to_cpu(cp->cp_blocks_count)); 289 root->ifile = ifile; 290 291 put_cp: 292 kunmap_local(cp); 293 brelse(cp_bh); 294 out_sem: 295 up_read(&NILFS_MDT(cpfile)->mi_sem); 296 return ret; 297 } 298 299 /** 300 * nilfs_cpfile_create_checkpoint - create a checkpoint entry on cpfile 301 * @cpfile: checkpoint file inode 302 * @cno: number of checkpoint to set up 303 * 304 * This function creates a checkpoint with the number specified by @cno on 305 * cpfile. If the specified checkpoint entry already exists due to a past 306 * failure, it will be reused without returning an error. 307 * In either case, the buffer of the block containing the checkpoint entry 308 * and the cpfile inode are made dirty for inclusion in the write log. 309 * 310 * Return: 0 on success, or the following negative error code on failure. 311 * * %-ENOMEM - Insufficient memory available. 312 * * %-EIO - I/O error (including metadata corruption). 313 * * %-EROFS - Read only filesystem 314 */ 315 int nilfs_cpfile_create_checkpoint(struct inode *cpfile, __u64 cno) 316 { 317 struct buffer_head *header_bh, *cp_bh; 318 struct nilfs_cpfile_header *header; 319 struct nilfs_checkpoint *cp; 320 size_t offset; 321 int ret; 322 323 if (WARN_ON_ONCE(cno < 1)) 324 return -EIO; 325 326 down_write(&NILFS_MDT(cpfile)->mi_sem); 327 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 328 if (unlikely(ret < 0)) 329 goto out_sem; 330 331 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 1, &cp_bh); 332 if (unlikely(ret < 0)) 333 goto out_header; 334 335 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 336 cp = kmap_local_folio(cp_bh->b_folio, offset); 337 if (nilfs_checkpoint_invalid(cp)) { 338 /* a newly-created checkpoint */ 339 nilfs_checkpoint_clear_invalid(cp); 340 kunmap_local(cp); 341 if (!nilfs_cpfile_is_in_first(cpfile, cno)) 342 nilfs_cpfile_block_add_valid_checkpoints(cpfile, cp_bh, 343 1); 344 345 header = kmap_local_folio(header_bh->b_folio, 0); 346 le64_add_cpu(&header->ch_ncheckpoints, 1); 347 kunmap_local(header); 348 mark_buffer_dirty(header_bh); 349 } else { 350 kunmap_local(cp); 351 } 352 353 /* Force the buffer and the inode to become dirty */ 354 mark_buffer_dirty(cp_bh); 355 brelse(cp_bh); 356 nilfs_mdt_mark_dirty(cpfile); 357 358 out_header: 359 brelse(header_bh); 360 361 out_sem: 362 up_write(&NILFS_MDT(cpfile)->mi_sem); 363 return ret; 364 } 365 366 /** 367 * nilfs_cpfile_finalize_checkpoint - fill in a checkpoint entry in cpfile 368 * @cpfile: checkpoint file inode 369 * @cno: checkpoint number 370 * @root: nilfs root object 371 * @blkinc: number of blocks added by this checkpoint 372 * @ctime: checkpoint creation time 373 * @minor: minor checkpoint flag 374 * 375 * This function completes the checkpoint entry numbered by @cno in the 376 * cpfile with the data given by the arguments @root, @blkinc, @ctime, and 377 * @minor. 378 * 379 * Return: 0 on success, or the following negative error code on 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 Value: On success, 0 is returned. On error, one of the following 451 * negative error codes is returned. 452 * 453 * %-EIO - I/O error. 454 * 455 * %-ENOMEM - Insufficient amount of memory available. 456 * 457 * %-EINVAL - invalid checkpoints. 458 */ 459 int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, 460 __u64 start, 461 __u64 end) 462 { 463 struct buffer_head *header_bh, *cp_bh; 464 struct nilfs_cpfile_header *header; 465 struct nilfs_checkpoint *cp; 466 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 467 __u64 cno; 468 size_t offset; 469 void *kaddr; 470 unsigned long tnicps; 471 int ret, ncps, nicps, nss, count, i; 472 473 if (unlikely(start == 0 || start > end)) { 474 nilfs_err(cpfile->i_sb, 475 "cannot delete checkpoints: invalid range [%llu, %llu)", 476 (unsigned long long)start, (unsigned long long)end); 477 return -EINVAL; 478 } 479 480 down_write(&NILFS_MDT(cpfile)->mi_sem); 481 482 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 483 if (ret < 0) 484 goto out_sem; 485 tnicps = 0; 486 nss = 0; 487 488 for (cno = start; cno < end; cno += ncps) { 489 ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, end); 490 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 491 if (ret < 0) { 492 if (ret != -ENOENT) 493 break; 494 /* skip hole */ 495 ret = 0; 496 continue; 497 } 498 499 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 500 cp = kaddr = kmap_local_folio(cp_bh->b_folio, offset); 501 nicps = 0; 502 for (i = 0; i < ncps; i++, cp = (void *)cp + cpsz) { 503 if (nilfs_checkpoint_snapshot(cp)) { 504 nss++; 505 } else if (!nilfs_checkpoint_invalid(cp)) { 506 nilfs_checkpoint_set_invalid(cp); 507 nicps++; 508 } 509 } 510 kunmap_local(kaddr); 511 512 if (nicps <= 0) { 513 brelse(cp_bh); 514 continue; 515 } 516 517 tnicps += nicps; 518 mark_buffer_dirty(cp_bh); 519 nilfs_mdt_mark_dirty(cpfile); 520 if (nilfs_cpfile_is_in_first(cpfile, cno)) { 521 brelse(cp_bh); 522 continue; 523 } 524 525 count = nilfs_cpfile_block_sub_valid_checkpoints(cpfile, cp_bh, 526 nicps); 527 brelse(cp_bh); 528 if (count) 529 continue; 530 531 /* Delete the block if there are no more valid checkpoints */ 532 ret = nilfs_cpfile_delete_checkpoint_block(cpfile, cno); 533 if (unlikely(ret)) { 534 nilfs_err(cpfile->i_sb, 535 "error %d deleting checkpoint block", ret); 536 break; 537 } 538 } 539 540 if (tnicps > 0) { 541 header = kmap_local_folio(header_bh->b_folio, 0); 542 le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps); 543 mark_buffer_dirty(header_bh); 544 nilfs_mdt_mark_dirty(cpfile); 545 kunmap_local(header); 546 } 547 548 brelse(header_bh); 549 if (nss > 0) 550 ret = -EBUSY; 551 552 out_sem: 553 up_write(&NILFS_MDT(cpfile)->mi_sem); 554 return ret; 555 } 556 557 static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile, 558 struct nilfs_checkpoint *cp, 559 struct nilfs_cpinfo *ci) 560 { 561 ci->ci_flags = le32_to_cpu(cp->cp_flags); 562 ci->ci_cno = le64_to_cpu(cp->cp_cno); 563 ci->ci_create = le64_to_cpu(cp->cp_create); 564 ci->ci_nblk_inc = le64_to_cpu(cp->cp_nblk_inc); 565 ci->ci_inodes_count = le64_to_cpu(cp->cp_inodes_count); 566 ci->ci_blocks_count = le64_to_cpu(cp->cp_blocks_count); 567 ci->ci_next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 568 } 569 570 static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, 571 void *buf, unsigned int cisz, 572 size_t nci) 573 { 574 struct nilfs_checkpoint *cp; 575 struct nilfs_cpinfo *ci = buf; 576 struct buffer_head *bh; 577 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 578 __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop; 579 size_t offset; 580 void *kaddr; 581 int n, ret; 582 int ncps, i; 583 584 if (cno == 0) 585 return -ENOENT; /* checkpoint number 0 is invalid */ 586 down_read(&NILFS_MDT(cpfile)->mi_sem); 587 588 for (n = 0; n < nci; cno += ncps) { 589 ret = nilfs_cpfile_find_checkpoint_block( 590 cpfile, cno, cur_cno - 1, &cno, &bh); 591 if (ret < 0) { 592 if (likely(ret == -ENOENT)) 593 break; 594 goto out; 595 } 596 ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno); 597 598 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, bh); 599 cp = kaddr = kmap_local_folio(bh->b_folio, offset); 600 for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) { 601 if (!nilfs_checkpoint_invalid(cp)) { 602 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, 603 ci); 604 ci = (void *)ci + cisz; 605 n++; 606 } 607 } 608 kunmap_local(kaddr); 609 brelse(bh); 610 } 611 612 ret = n; 613 if (n > 0) { 614 ci = (void *)ci - cisz; 615 *cnop = ci->ci_cno + 1; 616 } 617 618 out: 619 up_read(&NILFS_MDT(cpfile)->mi_sem); 620 return ret; 621 } 622 623 static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, 624 void *buf, unsigned int cisz, 625 size_t nci) 626 { 627 struct buffer_head *bh; 628 struct nilfs_cpfile_header *header; 629 struct nilfs_checkpoint *cp; 630 struct nilfs_cpinfo *ci = buf; 631 __u64 curr = *cnop, next; 632 unsigned long curr_blkoff, next_blkoff; 633 size_t offset; 634 int n = 0, ret; 635 636 down_read(&NILFS_MDT(cpfile)->mi_sem); 637 638 if (curr == 0) { 639 ret = nilfs_cpfile_get_header_block(cpfile, &bh); 640 if (ret < 0) 641 goto out; 642 header = kmap_local_folio(bh->b_folio, 0); 643 curr = le64_to_cpu(header->ch_snapshot_list.ssl_next); 644 kunmap_local(header); 645 brelse(bh); 646 if (curr == 0) { 647 ret = 0; 648 goto out; 649 } 650 } else if (unlikely(curr == ~(__u64)0)) { 651 ret = 0; 652 goto out; 653 } 654 655 curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr); 656 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh); 657 if (unlikely(ret < 0)) { 658 if (ret == -ENOENT) 659 ret = 0; /* No snapshots (started from a hole block) */ 660 goto out; 661 } 662 offset = nilfs_cpfile_checkpoint_offset(cpfile, curr, bh); 663 cp = kmap_local_folio(bh->b_folio, offset); 664 while (n < nci) { 665 curr = ~(__u64)0; /* Terminator */ 666 if (unlikely(nilfs_checkpoint_invalid(cp) || 667 !nilfs_checkpoint_snapshot(cp))) 668 break; 669 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, ci); 670 ci = (void *)ci + cisz; 671 n++; 672 next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 673 if (next == 0) 674 break; /* reach end of the snapshot list */ 675 676 kunmap_local(cp); 677 next_blkoff = nilfs_cpfile_get_blkoff(cpfile, next); 678 if (curr_blkoff != next_blkoff) { 679 brelse(bh); 680 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 681 0, &bh); 682 if (unlikely(ret < 0)) { 683 WARN_ON(ret == -ENOENT); 684 goto out; 685 } 686 } 687 offset = nilfs_cpfile_checkpoint_offset(cpfile, next, bh); 688 cp = kmap_local_folio(bh->b_folio, offset); 689 curr = next; 690 curr_blkoff = next_blkoff; 691 } 692 kunmap_local(cp); 693 brelse(bh); 694 *cnop = curr; 695 ret = n; 696 697 out: 698 up_read(&NILFS_MDT(cpfile)->mi_sem); 699 return ret; 700 } 701 702 /** 703 * nilfs_cpfile_get_cpinfo - get information on checkpoints 704 * @cpfile: checkpoint file inode 705 * @cnop: place to pass a starting checkpoint number and receive a 706 * checkpoint number to continue the search 707 * @mode: mode of checkpoints that the caller wants to retrieve 708 * @buf: buffer for storing checkpoints' information 709 * @cisz: byte size of one checkpoint info item in array 710 * @nci: number of checkpoint info items to retrieve 711 * 712 * nilfs_cpfile_get_cpinfo() searches for checkpoints in @mode state 713 * starting from the checkpoint number stored in @cnop, and stores 714 * information about found checkpoints in @buf. 715 * The buffer pointed to by @buf must be large enough to store information 716 * for @nci checkpoints. If at least one checkpoint information is 717 * successfully retrieved, @cnop is updated to point to the checkpoint 718 * number to continue searching. 719 * 720 * Return: Count of checkpoint info items stored in the output buffer on 721 * success, or the following negative error code on failure. 722 * * %-EINVAL - Invalid checkpoint mode. 723 * * %-ENOMEM - Insufficient memory available. 724 * * %-EIO - I/O error (including metadata corruption). 725 * * %-ENOENT - Invalid checkpoint number specified. 726 */ 727 728 ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode, 729 void *buf, unsigned int cisz, size_t nci) 730 { 731 switch (mode) { 732 case NILFS_CHECKPOINT: 733 return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, buf, cisz, nci); 734 case NILFS_SNAPSHOT: 735 return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, buf, cisz, nci); 736 default: 737 return -EINVAL; 738 } 739 } 740 741 /** 742 * nilfs_cpfile_delete_checkpoint - delete a checkpoint 743 * @cpfile: checkpoint file inode 744 * @cno: checkpoint number to delete 745 * 746 * Return: 0 on success, or the following negative error code on failure. 747 * * %-EBUSY - Checkpoint in use (snapshot specified). 748 * * %-EIO - I/O error (including metadata corruption). 749 * * %-ENOENT - No valid checkpoint found. 750 * * %-ENOMEM - Insufficient memory available. 751 */ 752 int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno) 753 { 754 struct nilfs_cpinfo ci; 755 __u64 tcno = cno; 756 ssize_t nci; 757 758 nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, sizeof(ci), 1); 759 if (nci < 0) 760 return nci; 761 else if (nci == 0 || ci.ci_cno != cno) 762 return -ENOENT; 763 else if (nilfs_cpinfo_snapshot(&ci)) 764 return -EBUSY; 765 766 return nilfs_cpfile_delete_checkpoints(cpfile, cno, cno + 1); 767 } 768 769 static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno) 770 { 771 struct buffer_head *header_bh, *curr_bh, *prev_bh, *cp_bh; 772 struct nilfs_cpfile_header *header; 773 struct nilfs_checkpoint *cp; 774 struct nilfs_snapshot_list *list; 775 __u64 curr, prev; 776 unsigned long curr_blkoff, prev_blkoff; 777 size_t offset, curr_list_offset, prev_list_offset; 778 int ret; 779 780 if (cno == 0) 781 return -ENOENT; /* checkpoint number 0 is invalid */ 782 down_write(&NILFS_MDT(cpfile)->mi_sem); 783 784 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 785 if (unlikely(ret < 0)) 786 goto out_sem; 787 788 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 789 if (ret < 0) 790 goto out_header; 791 792 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 793 cp = kmap_local_folio(cp_bh->b_folio, offset); 794 if (nilfs_checkpoint_invalid(cp)) { 795 ret = -ENOENT; 796 kunmap_local(cp); 797 goto out_cp; 798 } 799 if (nilfs_checkpoint_snapshot(cp)) { 800 ret = 0; 801 kunmap_local(cp); 802 goto out_cp; 803 } 804 kunmap_local(cp); 805 806 /* 807 * Find the last snapshot before the checkpoint being changed to 808 * snapshot mode by going backwards through the snapshot list. 809 * Set "prev" to its checkpoint number, or 0 if not found. 810 */ 811 header = kmap_local_folio(header_bh->b_folio, 0); 812 list = &header->ch_snapshot_list; 813 curr_bh = header_bh; 814 get_bh(curr_bh); 815 curr = 0; 816 curr_blkoff = 0; 817 curr_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 818 prev = le64_to_cpu(list->ssl_prev); 819 while (prev > cno) { 820 prev_blkoff = nilfs_cpfile_get_blkoff(cpfile, prev); 821 curr = prev; 822 kunmap_local(list); 823 if (curr_blkoff != prev_blkoff) { 824 brelse(curr_bh); 825 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 826 0, &curr_bh); 827 if (unlikely(ret < 0)) 828 goto out_cp; 829 } 830 curr_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 831 cpfile, curr, curr_bh); 832 list = kmap_local_folio(curr_bh->b_folio, curr_list_offset); 833 curr_blkoff = prev_blkoff; 834 prev = le64_to_cpu(list->ssl_prev); 835 } 836 kunmap_local(list); 837 838 if (prev != 0) { 839 ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0, 840 &prev_bh); 841 if (ret < 0) 842 goto out_curr; 843 844 prev_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 845 cpfile, prev, prev_bh); 846 } else { 847 prev_bh = header_bh; 848 get_bh(prev_bh); 849 prev_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 850 } 851 852 /* Update the list entry for the next snapshot */ 853 list = kmap_local_folio(curr_bh->b_folio, curr_list_offset); 854 list->ssl_prev = cpu_to_le64(cno); 855 kunmap_local(list); 856 857 /* Update the checkpoint being changed to a snapshot */ 858 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 859 cp = kmap_local_folio(cp_bh->b_folio, offset); 860 cp->cp_snapshot_list.ssl_next = cpu_to_le64(curr); 861 cp->cp_snapshot_list.ssl_prev = cpu_to_le64(prev); 862 nilfs_checkpoint_set_snapshot(cp); 863 kunmap_local(cp); 864 865 /* Update the list entry for the previous snapshot */ 866 list = kmap_local_folio(prev_bh->b_folio, prev_list_offset); 867 list->ssl_next = cpu_to_le64(cno); 868 kunmap_local(list); 869 870 /* Update the statistics in the header */ 871 header = kmap_local_folio(header_bh->b_folio, 0); 872 le64_add_cpu(&header->ch_nsnapshots, 1); 873 kunmap_local(header); 874 875 mark_buffer_dirty(prev_bh); 876 mark_buffer_dirty(curr_bh); 877 mark_buffer_dirty(cp_bh); 878 mark_buffer_dirty(header_bh); 879 nilfs_mdt_mark_dirty(cpfile); 880 881 brelse(prev_bh); 882 883 out_curr: 884 brelse(curr_bh); 885 886 out_cp: 887 brelse(cp_bh); 888 889 out_header: 890 brelse(header_bh); 891 892 out_sem: 893 up_write(&NILFS_MDT(cpfile)->mi_sem); 894 return ret; 895 } 896 897 static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno) 898 { 899 struct buffer_head *header_bh, *next_bh, *prev_bh, *cp_bh; 900 struct nilfs_cpfile_header *header; 901 struct nilfs_checkpoint *cp; 902 struct nilfs_snapshot_list *list; 903 __u64 next, prev; 904 size_t offset, next_list_offset, prev_list_offset; 905 int ret; 906 907 if (cno == 0) 908 return -ENOENT; /* checkpoint number 0 is invalid */ 909 down_write(&NILFS_MDT(cpfile)->mi_sem); 910 911 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 912 if (unlikely(ret < 0)) 913 goto out_sem; 914 915 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 916 if (ret < 0) 917 goto out_header; 918 919 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, cp_bh); 920 cp = kmap_local_folio(cp_bh->b_folio, offset); 921 if (nilfs_checkpoint_invalid(cp)) { 922 ret = -ENOENT; 923 kunmap_local(cp); 924 goto out_cp; 925 } 926 if (!nilfs_checkpoint_snapshot(cp)) { 927 ret = 0; 928 kunmap_local(cp); 929 goto out_cp; 930 } 931 932 list = &cp->cp_snapshot_list; 933 next = le64_to_cpu(list->ssl_next); 934 prev = le64_to_cpu(list->ssl_prev); 935 kunmap_local(cp); 936 937 if (next != 0) { 938 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 0, 939 &next_bh); 940 if (ret < 0) 941 goto out_cp; 942 943 next_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 944 cpfile, next, next_bh); 945 } else { 946 next_bh = header_bh; 947 get_bh(next_bh); 948 next_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 949 } 950 if (prev != 0) { 951 ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0, 952 &prev_bh); 953 if (ret < 0) 954 goto out_next; 955 956 prev_list_offset = nilfs_cpfile_cp_snapshot_list_offset( 957 cpfile, prev, prev_bh); 958 } else { 959 prev_bh = header_bh; 960 get_bh(prev_bh); 961 prev_list_offset = nilfs_cpfile_ch_snapshot_list_offset(); 962 } 963 964 /* Update the list entry for the next snapshot */ 965 list = kmap_local_folio(next_bh->b_folio, next_list_offset); 966 list->ssl_prev = cpu_to_le64(prev); 967 kunmap_local(list); 968 969 /* Update the list entry for the previous snapshot */ 970 list = kmap_local_folio(prev_bh->b_folio, prev_list_offset); 971 list->ssl_next = cpu_to_le64(next); 972 kunmap_local(list); 973 974 /* Update the snapshot being changed back to a plain checkpoint */ 975 cp = kmap_local_folio(cp_bh->b_folio, offset); 976 cp->cp_snapshot_list.ssl_next = cpu_to_le64(0); 977 cp->cp_snapshot_list.ssl_prev = cpu_to_le64(0); 978 nilfs_checkpoint_clear_snapshot(cp); 979 kunmap_local(cp); 980 981 /* Update the statistics in the header */ 982 header = kmap_local_folio(header_bh->b_folio, 0); 983 le64_add_cpu(&header->ch_nsnapshots, -1); 984 kunmap_local(header); 985 986 mark_buffer_dirty(next_bh); 987 mark_buffer_dirty(prev_bh); 988 mark_buffer_dirty(cp_bh); 989 mark_buffer_dirty(header_bh); 990 nilfs_mdt_mark_dirty(cpfile); 991 992 brelse(prev_bh); 993 994 out_next: 995 brelse(next_bh); 996 997 out_cp: 998 brelse(cp_bh); 999 1000 out_header: 1001 brelse(header_bh); 1002 1003 out_sem: 1004 up_write(&NILFS_MDT(cpfile)->mi_sem); 1005 return ret; 1006 } 1007 1008 /** 1009 * nilfs_cpfile_is_snapshot - determine if checkpoint is a snapshot 1010 * @cpfile: inode of checkpoint file 1011 * @cno: checkpoint number 1012 * 1013 * Return: 1 if the checkpoint specified by @cno is a snapshot, 0 if not, or 1014 * the following negative error code on failure. 1015 * * %-EIO - I/O error (including metadata corruption). 1016 * * %-ENOENT - No such checkpoint. 1017 * * %-ENOMEM - Insufficient memory available. 1018 */ 1019 int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno) 1020 { 1021 struct buffer_head *bh; 1022 struct nilfs_checkpoint *cp; 1023 size_t offset; 1024 int ret; 1025 1026 /* 1027 * CP number is invalid if it's zero or larger than the 1028 * largest existing one. 1029 */ 1030 if (cno == 0 || cno >= nilfs_mdt_cno(cpfile)) 1031 return -ENOENT; 1032 down_read(&NILFS_MDT(cpfile)->mi_sem); 1033 1034 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh); 1035 if (ret < 0) 1036 goto out; 1037 1038 offset = nilfs_cpfile_checkpoint_offset(cpfile, cno, bh); 1039 cp = kmap_local_folio(bh->b_folio, offset); 1040 if (nilfs_checkpoint_invalid(cp)) 1041 ret = -ENOENT; 1042 else 1043 ret = nilfs_checkpoint_snapshot(cp); 1044 kunmap_local(cp); 1045 brelse(bh); 1046 1047 out: 1048 up_read(&NILFS_MDT(cpfile)->mi_sem); 1049 return ret; 1050 } 1051 1052 /** 1053 * nilfs_cpfile_change_cpmode - change checkpoint mode 1054 * @cpfile: inode of checkpoint file 1055 * @cno: checkpoint number 1056 * @mode: mode of checkpoint 1057 * 1058 * Description: nilfs_change_cpmode() changes the mode of the checkpoint 1059 * specified by @cno. The mode @mode is NILFS_CHECKPOINT or NILFS_SNAPSHOT. 1060 * 1061 * Return Value: On success, 0 is returned. On error, one of the following 1062 * negative error codes is returned. 1063 * 1064 * %-EIO - I/O error. 1065 * 1066 * %-ENOMEM - Insufficient amount of memory available. 1067 * 1068 * %-ENOENT - No such checkpoint. 1069 */ 1070 int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode) 1071 { 1072 int ret; 1073 1074 switch (mode) { 1075 case NILFS_CHECKPOINT: 1076 if (nilfs_checkpoint_is_mounted(cpfile->i_sb, cno)) 1077 /* 1078 * Current implementation does not have to protect 1079 * plain read-only mounts since they are exclusive 1080 * with a read/write mount and are protected from the 1081 * cleaner. 1082 */ 1083 ret = -EBUSY; 1084 else 1085 ret = nilfs_cpfile_clear_snapshot(cpfile, cno); 1086 return ret; 1087 case NILFS_SNAPSHOT: 1088 return nilfs_cpfile_set_snapshot(cpfile, cno); 1089 default: 1090 return -EINVAL; 1091 } 1092 } 1093 1094 /** 1095 * nilfs_cpfile_get_stat - get checkpoint statistics 1096 * @cpfile: inode of checkpoint file 1097 * @cpstat: pointer to a structure of checkpoint statistics 1098 * 1099 * Description: nilfs_cpfile_get_stat() returns information about checkpoints. 1100 * 1101 * Return Value: On success, 0 is returned, and checkpoints information is 1102 * stored in the place pointed by @cpstat. On error, one of the following 1103 * negative error codes is returned. 1104 * 1105 * %-EIO - I/O error. 1106 * 1107 * %-ENOMEM - Insufficient amount of memory available. 1108 */ 1109 int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat) 1110 { 1111 struct buffer_head *bh; 1112 struct nilfs_cpfile_header *header; 1113 int ret; 1114 1115 down_read(&NILFS_MDT(cpfile)->mi_sem); 1116 1117 ret = nilfs_cpfile_get_header_block(cpfile, &bh); 1118 if (ret < 0) 1119 goto out_sem; 1120 header = kmap_local_folio(bh->b_folio, 0); 1121 cpstat->cs_cno = nilfs_mdt_cno(cpfile); 1122 cpstat->cs_ncps = le64_to_cpu(header->ch_ncheckpoints); 1123 cpstat->cs_nsss = le64_to_cpu(header->ch_nsnapshots); 1124 kunmap_local(header); 1125 brelse(bh); 1126 1127 out_sem: 1128 up_read(&NILFS_MDT(cpfile)->mi_sem); 1129 return ret; 1130 } 1131 1132 /** 1133 * nilfs_cpfile_read - read or get cpfile inode 1134 * @sb: super block instance 1135 * @cpsize: size of a checkpoint entry 1136 * @raw_inode: on-disk cpfile inode 1137 * @inodep: buffer to store the inode 1138 */ 1139 int nilfs_cpfile_read(struct super_block *sb, size_t cpsize, 1140 struct nilfs_inode *raw_inode, struct inode **inodep) 1141 { 1142 struct inode *cpfile; 1143 int err; 1144 1145 if (cpsize > sb->s_blocksize) { 1146 nilfs_err(sb, "too large checkpoint size: %zu bytes", cpsize); 1147 return -EINVAL; 1148 } else if (cpsize < NILFS_MIN_CHECKPOINT_SIZE) { 1149 nilfs_err(sb, "too small checkpoint size: %zu bytes", cpsize); 1150 return -EINVAL; 1151 } 1152 1153 cpfile = nilfs_iget_locked(sb, NULL, NILFS_CPFILE_INO); 1154 if (unlikely(!cpfile)) 1155 return -ENOMEM; 1156 if (!(cpfile->i_state & I_NEW)) 1157 goto out; 1158 1159 err = nilfs_mdt_init(cpfile, NILFS_MDT_GFP, 0); 1160 if (err) 1161 goto failed; 1162 1163 nilfs_mdt_set_entry_size(cpfile, cpsize, 1164 sizeof(struct nilfs_cpfile_header)); 1165 1166 err = nilfs_read_inode_common(cpfile, raw_inode); 1167 if (err) 1168 goto failed; 1169 1170 unlock_new_inode(cpfile); 1171 out: 1172 *inodep = cpfile; 1173 return 0; 1174 failed: 1175 iget_failed(cpfile); 1176 return err; 1177 } 1178