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