1 /* 2 * cpfile.c - NILFS checkpoint file. 3 * 4 * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * Written by Koji Sato. 17 */ 18 19 #include <linux/kernel.h> 20 #include <linux/fs.h> 21 #include <linux/string.h> 22 #include <linux/buffer_head.h> 23 #include <linux/errno.h> 24 #include <linux/nilfs2_fs.h> 25 #include "mdt.h" 26 #include "cpfile.h" 27 28 29 static inline unsigned long 30 nilfs_cpfile_checkpoints_per_block(const struct inode *cpfile) 31 { 32 return NILFS_MDT(cpfile)->mi_entries_per_block; 33 } 34 35 /* block number from the beginning of the file */ 36 static unsigned long 37 nilfs_cpfile_get_blkoff(const struct inode *cpfile, __u64 cno) 38 { 39 __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; 40 41 do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); 42 return (unsigned long)tcno; 43 } 44 45 /* offset in block */ 46 static unsigned long 47 nilfs_cpfile_get_offset(const struct inode *cpfile, __u64 cno) 48 { 49 __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1; 50 51 return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); 52 } 53 54 static __u64 nilfs_cpfile_first_checkpoint_in_block(const struct inode *cpfile, 55 unsigned long blkoff) 56 { 57 return (__u64)nilfs_cpfile_checkpoints_per_block(cpfile) * blkoff 58 + 1 - NILFS_MDT(cpfile)->mi_first_entry_offset; 59 } 60 61 static unsigned long 62 nilfs_cpfile_checkpoints_in_block(const struct inode *cpfile, 63 __u64 curr, 64 __u64 max) 65 { 66 return min_t(__u64, 67 nilfs_cpfile_checkpoints_per_block(cpfile) - 68 nilfs_cpfile_get_offset(cpfile, curr), 69 max - curr); 70 } 71 72 static inline int nilfs_cpfile_is_in_first(const struct inode *cpfile, 73 __u64 cno) 74 { 75 return nilfs_cpfile_get_blkoff(cpfile, cno) == 0; 76 } 77 78 static unsigned int 79 nilfs_cpfile_block_add_valid_checkpoints(const struct inode *cpfile, 80 struct buffer_head *bh, 81 void *kaddr, 82 unsigned int n) 83 { 84 struct nilfs_checkpoint *cp = kaddr + bh_offset(bh); 85 unsigned int count; 86 87 count = le32_to_cpu(cp->cp_checkpoints_count) + n; 88 cp->cp_checkpoints_count = cpu_to_le32(count); 89 return count; 90 } 91 92 static unsigned int 93 nilfs_cpfile_block_sub_valid_checkpoints(const struct inode *cpfile, 94 struct buffer_head *bh, 95 void *kaddr, 96 unsigned int n) 97 { 98 struct nilfs_checkpoint *cp = kaddr + bh_offset(bh); 99 unsigned int count; 100 101 WARN_ON(le32_to_cpu(cp->cp_checkpoints_count) < n); 102 count = le32_to_cpu(cp->cp_checkpoints_count) - n; 103 cp->cp_checkpoints_count = cpu_to_le32(count); 104 return count; 105 } 106 107 static inline struct nilfs_cpfile_header * 108 nilfs_cpfile_block_get_header(const struct inode *cpfile, 109 struct buffer_head *bh, 110 void *kaddr) 111 { 112 return kaddr + bh_offset(bh); 113 } 114 115 static struct nilfs_checkpoint * 116 nilfs_cpfile_block_get_checkpoint(const struct inode *cpfile, __u64 cno, 117 struct buffer_head *bh, 118 void *kaddr) 119 { 120 return kaddr + bh_offset(bh) + nilfs_cpfile_get_offset(cpfile, cno) * 121 NILFS_MDT(cpfile)->mi_entry_size; 122 } 123 124 static void nilfs_cpfile_block_init(struct inode *cpfile, 125 struct buffer_head *bh, 126 void *kaddr) 127 { 128 struct nilfs_checkpoint *cp = kaddr + bh_offset(bh); 129 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 130 int n = nilfs_cpfile_checkpoints_per_block(cpfile); 131 132 while (n-- > 0) { 133 nilfs_checkpoint_set_invalid(cp); 134 cp = (void *)cp + cpsz; 135 } 136 } 137 138 static inline int nilfs_cpfile_get_header_block(struct inode *cpfile, 139 struct buffer_head **bhp) 140 { 141 return nilfs_mdt_get_block(cpfile, 0, 0, NULL, bhp); 142 } 143 144 static inline int nilfs_cpfile_get_checkpoint_block(struct inode *cpfile, 145 __u64 cno, 146 int create, 147 struct buffer_head **bhp) 148 { 149 return nilfs_mdt_get_block(cpfile, 150 nilfs_cpfile_get_blkoff(cpfile, cno), 151 create, nilfs_cpfile_block_init, bhp); 152 } 153 154 /** 155 * nilfs_cpfile_find_checkpoint_block - find and get a buffer on cpfile 156 * @cpfile: inode of cpfile 157 * @start_cno: start checkpoint number (inclusive) 158 * @end_cno: end checkpoint number (inclusive) 159 * @cnop: place to store the next checkpoint number 160 * @bhp: place to store a pointer to buffer_head struct 161 * 162 * Return Value: On success, it returns 0. On error, the following negative 163 * error code is returned. 164 * 165 * %-ENOMEM - Insufficient memory available. 166 * 167 * %-EIO - I/O error 168 * 169 * %-ENOENT - no block exists in the range. 170 */ 171 static int nilfs_cpfile_find_checkpoint_block(struct inode *cpfile, 172 __u64 start_cno, __u64 end_cno, 173 __u64 *cnop, 174 struct buffer_head **bhp) 175 { 176 unsigned long start, end, blkoff; 177 int ret; 178 179 if (unlikely(start_cno > end_cno)) 180 return -ENOENT; 181 182 start = nilfs_cpfile_get_blkoff(cpfile, start_cno); 183 end = nilfs_cpfile_get_blkoff(cpfile, end_cno); 184 185 ret = nilfs_mdt_find_block(cpfile, start, end, &blkoff, bhp); 186 if (!ret) 187 *cnop = (blkoff == start) ? start_cno : 188 nilfs_cpfile_first_checkpoint_in_block(cpfile, blkoff); 189 return ret; 190 } 191 192 static inline int nilfs_cpfile_delete_checkpoint_block(struct inode *cpfile, 193 __u64 cno) 194 { 195 return nilfs_mdt_delete_block(cpfile, 196 nilfs_cpfile_get_blkoff(cpfile, cno)); 197 } 198 199 /** 200 * nilfs_cpfile_get_checkpoint - get a checkpoint 201 * @cpfile: inode of checkpoint file 202 * @cno: checkpoint number 203 * @create: create flag 204 * @cpp: pointer to a checkpoint 205 * @bhp: pointer to a buffer head 206 * 207 * Description: nilfs_cpfile_get_checkpoint() acquires the checkpoint 208 * specified by @cno. A new checkpoint will be created if @cno is the current 209 * checkpoint number and @create is nonzero. 210 * 211 * Return Value: On success, 0 is returned, and the checkpoint and the 212 * buffer head of the buffer on which the checkpoint is located are stored in 213 * the place pointed by @cpp and @bhp, respectively. On error, one of the 214 * following negative error codes is returned. 215 * 216 * %-EIO - I/O error. 217 * 218 * %-ENOMEM - Insufficient amount of memory available. 219 * 220 * %-ENOENT - No such checkpoint. 221 * 222 * %-EINVAL - invalid checkpoint. 223 */ 224 int nilfs_cpfile_get_checkpoint(struct inode *cpfile, 225 __u64 cno, 226 int create, 227 struct nilfs_checkpoint **cpp, 228 struct buffer_head **bhp) 229 { 230 struct buffer_head *header_bh, *cp_bh; 231 struct nilfs_cpfile_header *header; 232 struct nilfs_checkpoint *cp; 233 void *kaddr; 234 int ret; 235 236 if (unlikely(cno < 1 || cno > nilfs_mdt_cno(cpfile) || 237 (cno < nilfs_mdt_cno(cpfile) && create))) 238 return -EINVAL; 239 240 down_write(&NILFS_MDT(cpfile)->mi_sem); 241 242 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 243 if (ret < 0) 244 goto out_sem; 245 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, create, &cp_bh); 246 if (ret < 0) 247 goto out_header; 248 kaddr = kmap(cp_bh->b_page); 249 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr); 250 if (nilfs_checkpoint_invalid(cp)) { 251 if (!create) { 252 kunmap(cp_bh->b_page); 253 brelse(cp_bh); 254 ret = -ENOENT; 255 goto out_header; 256 } 257 /* a newly-created checkpoint */ 258 nilfs_checkpoint_clear_invalid(cp); 259 if (!nilfs_cpfile_is_in_first(cpfile, cno)) 260 nilfs_cpfile_block_add_valid_checkpoints(cpfile, cp_bh, 261 kaddr, 1); 262 mark_buffer_dirty(cp_bh); 263 264 kaddr = kmap_atomic(header_bh->b_page); 265 header = nilfs_cpfile_block_get_header(cpfile, header_bh, 266 kaddr); 267 le64_add_cpu(&header->ch_ncheckpoints, 1); 268 kunmap_atomic(kaddr); 269 mark_buffer_dirty(header_bh); 270 nilfs_mdt_mark_dirty(cpfile); 271 } 272 273 if (cpp != NULL) 274 *cpp = cp; 275 *bhp = cp_bh; 276 277 out_header: 278 brelse(header_bh); 279 280 out_sem: 281 up_write(&NILFS_MDT(cpfile)->mi_sem); 282 return ret; 283 } 284 285 /** 286 * nilfs_cpfile_put_checkpoint - put a checkpoint 287 * @cpfile: inode of checkpoint file 288 * @cno: checkpoint number 289 * @bh: buffer head 290 * 291 * Description: nilfs_cpfile_put_checkpoint() releases the checkpoint 292 * specified by @cno. @bh must be the buffer head which has been returned by 293 * a previous call to nilfs_cpfile_get_checkpoint() with @cno. 294 */ 295 void nilfs_cpfile_put_checkpoint(struct inode *cpfile, __u64 cno, 296 struct buffer_head *bh) 297 { 298 kunmap(bh->b_page); 299 brelse(bh); 300 } 301 302 /** 303 * nilfs_cpfile_delete_checkpoints - delete checkpoints 304 * @cpfile: inode of checkpoint file 305 * @start: start checkpoint number 306 * @end: end checkpoint numer 307 * 308 * Description: nilfs_cpfile_delete_checkpoints() deletes the checkpoints in 309 * the period from @start to @end, excluding @end itself. The checkpoints 310 * which have been already deleted are ignored. 311 * 312 * Return Value: On success, 0 is returned. On error, one of the following 313 * negative error codes is returned. 314 * 315 * %-EIO - I/O error. 316 * 317 * %-ENOMEM - Insufficient amount of memory available. 318 * 319 * %-EINVAL - invalid checkpoints. 320 */ 321 int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, 322 __u64 start, 323 __u64 end) 324 { 325 struct buffer_head *header_bh, *cp_bh; 326 struct nilfs_cpfile_header *header; 327 struct nilfs_checkpoint *cp; 328 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 329 __u64 cno; 330 void *kaddr; 331 unsigned long tnicps; 332 int ret, ncps, nicps, nss, count, i; 333 334 if (unlikely(start == 0 || start > end)) { 335 printk(KERN_ERR "%s: invalid range of checkpoint numbers: " 336 "[%llu, %llu)\n", __func__, 337 (unsigned long long)start, (unsigned long long)end); 338 return -EINVAL; 339 } 340 341 down_write(&NILFS_MDT(cpfile)->mi_sem); 342 343 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 344 if (ret < 0) 345 goto out_sem; 346 tnicps = 0; 347 nss = 0; 348 349 for (cno = start; cno < end; cno += ncps) { 350 ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, end); 351 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 352 if (ret < 0) { 353 if (ret != -ENOENT) 354 break; 355 /* skip hole */ 356 ret = 0; 357 continue; 358 } 359 360 kaddr = kmap_atomic(cp_bh->b_page); 361 cp = nilfs_cpfile_block_get_checkpoint( 362 cpfile, cno, cp_bh, kaddr); 363 nicps = 0; 364 for (i = 0; i < ncps; i++, cp = (void *)cp + cpsz) { 365 if (nilfs_checkpoint_snapshot(cp)) { 366 nss++; 367 } else if (!nilfs_checkpoint_invalid(cp)) { 368 nilfs_checkpoint_set_invalid(cp); 369 nicps++; 370 } 371 } 372 if (nicps > 0) { 373 tnicps += nicps; 374 mark_buffer_dirty(cp_bh); 375 nilfs_mdt_mark_dirty(cpfile); 376 if (!nilfs_cpfile_is_in_first(cpfile, cno)) { 377 count = 378 nilfs_cpfile_block_sub_valid_checkpoints( 379 cpfile, cp_bh, kaddr, nicps); 380 if (count == 0) { 381 /* make hole */ 382 kunmap_atomic(kaddr); 383 brelse(cp_bh); 384 ret = 385 nilfs_cpfile_delete_checkpoint_block( 386 cpfile, cno); 387 if (ret == 0) 388 continue; 389 printk(KERN_ERR 390 "%s: cannot delete block\n", 391 __func__); 392 break; 393 } 394 } 395 } 396 397 kunmap_atomic(kaddr); 398 brelse(cp_bh); 399 } 400 401 if (tnicps > 0) { 402 kaddr = kmap_atomic(header_bh->b_page); 403 header = nilfs_cpfile_block_get_header(cpfile, header_bh, 404 kaddr); 405 le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps); 406 mark_buffer_dirty(header_bh); 407 nilfs_mdt_mark_dirty(cpfile); 408 kunmap_atomic(kaddr); 409 } 410 411 brelse(header_bh); 412 if (nss > 0) 413 ret = -EBUSY; 414 415 out_sem: 416 up_write(&NILFS_MDT(cpfile)->mi_sem); 417 return ret; 418 } 419 420 static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile, 421 struct nilfs_checkpoint *cp, 422 struct nilfs_cpinfo *ci) 423 { 424 ci->ci_flags = le32_to_cpu(cp->cp_flags); 425 ci->ci_cno = le64_to_cpu(cp->cp_cno); 426 ci->ci_create = le64_to_cpu(cp->cp_create); 427 ci->ci_nblk_inc = le64_to_cpu(cp->cp_nblk_inc); 428 ci->ci_inodes_count = le64_to_cpu(cp->cp_inodes_count); 429 ci->ci_blocks_count = le64_to_cpu(cp->cp_blocks_count); 430 ci->ci_next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 431 } 432 433 static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, 434 void *buf, unsigned int cisz, 435 size_t nci) 436 { 437 struct nilfs_checkpoint *cp; 438 struct nilfs_cpinfo *ci = buf; 439 struct buffer_head *bh; 440 size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size; 441 __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop; 442 void *kaddr; 443 int n, ret; 444 int ncps, i; 445 446 if (cno == 0) 447 return -ENOENT; /* checkpoint number 0 is invalid */ 448 down_read(&NILFS_MDT(cpfile)->mi_sem); 449 450 for (n = 0; n < nci; cno += ncps) { 451 ret = nilfs_cpfile_find_checkpoint_block( 452 cpfile, cno, cur_cno - 1, &cno, &bh); 453 if (ret < 0) { 454 if (likely(ret == -ENOENT)) 455 break; 456 goto out; 457 } 458 ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno); 459 460 kaddr = kmap_atomic(bh->b_page); 461 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); 462 for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) { 463 if (!nilfs_checkpoint_invalid(cp)) { 464 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, 465 ci); 466 ci = (void *)ci + cisz; 467 n++; 468 } 469 } 470 kunmap_atomic(kaddr); 471 brelse(bh); 472 } 473 474 ret = n; 475 if (n > 0) { 476 ci = (void *)ci - cisz; 477 *cnop = ci->ci_cno + 1; 478 } 479 480 out: 481 up_read(&NILFS_MDT(cpfile)->mi_sem); 482 return ret; 483 } 484 485 static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop, 486 void *buf, unsigned int cisz, 487 size_t nci) 488 { 489 struct buffer_head *bh; 490 struct nilfs_cpfile_header *header; 491 struct nilfs_checkpoint *cp; 492 struct nilfs_cpinfo *ci = buf; 493 __u64 curr = *cnop, next; 494 unsigned long curr_blkoff, next_blkoff; 495 void *kaddr; 496 int n = 0, ret; 497 498 down_read(&NILFS_MDT(cpfile)->mi_sem); 499 500 if (curr == 0) { 501 ret = nilfs_cpfile_get_header_block(cpfile, &bh); 502 if (ret < 0) 503 goto out; 504 kaddr = kmap_atomic(bh->b_page); 505 header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr); 506 curr = le64_to_cpu(header->ch_snapshot_list.ssl_next); 507 kunmap_atomic(kaddr); 508 brelse(bh); 509 if (curr == 0) { 510 ret = 0; 511 goto out; 512 } 513 } else if (unlikely(curr == ~(__u64)0)) { 514 ret = 0; 515 goto out; 516 } 517 518 curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr); 519 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh); 520 if (unlikely(ret < 0)) { 521 if (ret == -ENOENT) 522 ret = 0; /* No snapshots (started from a hole block) */ 523 goto out; 524 } 525 kaddr = kmap_atomic(bh->b_page); 526 while (n < nci) { 527 cp = nilfs_cpfile_block_get_checkpoint(cpfile, curr, bh, kaddr); 528 curr = ~(__u64)0; /* Terminator */ 529 if (unlikely(nilfs_checkpoint_invalid(cp) || 530 !nilfs_checkpoint_snapshot(cp))) 531 break; 532 nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, ci); 533 ci = (void *)ci + cisz; 534 n++; 535 next = le64_to_cpu(cp->cp_snapshot_list.ssl_next); 536 if (next == 0) 537 break; /* reach end of the snapshot list */ 538 539 next_blkoff = nilfs_cpfile_get_blkoff(cpfile, next); 540 if (curr_blkoff != next_blkoff) { 541 kunmap_atomic(kaddr); 542 brelse(bh); 543 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 544 0, &bh); 545 if (unlikely(ret < 0)) { 546 WARN_ON(ret == -ENOENT); 547 goto out; 548 } 549 kaddr = kmap_atomic(bh->b_page); 550 } 551 curr = next; 552 curr_blkoff = next_blkoff; 553 } 554 kunmap_atomic(kaddr); 555 brelse(bh); 556 *cnop = curr; 557 ret = n; 558 559 out: 560 up_read(&NILFS_MDT(cpfile)->mi_sem); 561 return ret; 562 } 563 564 /** 565 * nilfs_cpfile_get_cpinfo - 566 * @cpfile: 567 * @cno: 568 * @ci: 569 * @nci: 570 */ 571 572 ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode, 573 void *buf, unsigned int cisz, size_t nci) 574 { 575 switch (mode) { 576 case NILFS_CHECKPOINT: 577 return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, buf, cisz, nci); 578 case NILFS_SNAPSHOT: 579 return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, buf, cisz, nci); 580 default: 581 return -EINVAL; 582 } 583 } 584 585 /** 586 * nilfs_cpfile_delete_checkpoint - 587 * @cpfile: 588 * @cno: 589 */ 590 int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno) 591 { 592 struct nilfs_cpinfo ci; 593 __u64 tcno = cno; 594 ssize_t nci; 595 596 nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, sizeof(ci), 1); 597 if (nci < 0) 598 return nci; 599 else if (nci == 0 || ci.ci_cno != cno) 600 return -ENOENT; 601 else if (nilfs_cpinfo_snapshot(&ci)) 602 return -EBUSY; 603 604 return nilfs_cpfile_delete_checkpoints(cpfile, cno, cno + 1); 605 } 606 607 static struct nilfs_snapshot_list * 608 nilfs_cpfile_block_get_snapshot_list(const struct inode *cpfile, 609 __u64 cno, 610 struct buffer_head *bh, 611 void *kaddr) 612 { 613 struct nilfs_cpfile_header *header; 614 struct nilfs_checkpoint *cp; 615 struct nilfs_snapshot_list *list; 616 617 if (cno != 0) { 618 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); 619 list = &cp->cp_snapshot_list; 620 } else { 621 header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr); 622 list = &header->ch_snapshot_list; 623 } 624 return list; 625 } 626 627 static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno) 628 { 629 struct buffer_head *header_bh, *curr_bh, *prev_bh, *cp_bh; 630 struct nilfs_cpfile_header *header; 631 struct nilfs_checkpoint *cp; 632 struct nilfs_snapshot_list *list; 633 __u64 curr, prev; 634 unsigned long curr_blkoff, prev_blkoff; 635 void *kaddr; 636 int ret; 637 638 if (cno == 0) 639 return -ENOENT; /* checkpoint number 0 is invalid */ 640 down_write(&NILFS_MDT(cpfile)->mi_sem); 641 642 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 643 if (ret < 0) 644 goto out_sem; 645 kaddr = kmap_atomic(cp_bh->b_page); 646 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr); 647 if (nilfs_checkpoint_invalid(cp)) { 648 ret = -ENOENT; 649 kunmap_atomic(kaddr); 650 goto out_cp; 651 } 652 if (nilfs_checkpoint_snapshot(cp)) { 653 ret = 0; 654 kunmap_atomic(kaddr); 655 goto out_cp; 656 } 657 kunmap_atomic(kaddr); 658 659 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 660 if (ret < 0) 661 goto out_cp; 662 kaddr = kmap_atomic(header_bh->b_page); 663 header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr); 664 list = &header->ch_snapshot_list; 665 curr_bh = header_bh; 666 get_bh(curr_bh); 667 curr = 0; 668 curr_blkoff = 0; 669 prev = le64_to_cpu(list->ssl_prev); 670 while (prev > cno) { 671 prev_blkoff = nilfs_cpfile_get_blkoff(cpfile, prev); 672 curr = prev; 673 if (curr_blkoff != prev_blkoff) { 674 kunmap_atomic(kaddr); 675 brelse(curr_bh); 676 ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 677 0, &curr_bh); 678 if (ret < 0) 679 goto out_header; 680 kaddr = kmap_atomic(curr_bh->b_page); 681 } 682 curr_blkoff = prev_blkoff; 683 cp = nilfs_cpfile_block_get_checkpoint( 684 cpfile, curr, curr_bh, kaddr); 685 list = &cp->cp_snapshot_list; 686 prev = le64_to_cpu(list->ssl_prev); 687 } 688 kunmap_atomic(kaddr); 689 690 if (prev != 0) { 691 ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0, 692 &prev_bh); 693 if (ret < 0) 694 goto out_curr; 695 } else { 696 prev_bh = header_bh; 697 get_bh(prev_bh); 698 } 699 700 kaddr = kmap_atomic(curr_bh->b_page); 701 list = nilfs_cpfile_block_get_snapshot_list( 702 cpfile, curr, curr_bh, kaddr); 703 list->ssl_prev = cpu_to_le64(cno); 704 kunmap_atomic(kaddr); 705 706 kaddr = kmap_atomic(cp_bh->b_page); 707 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr); 708 cp->cp_snapshot_list.ssl_next = cpu_to_le64(curr); 709 cp->cp_snapshot_list.ssl_prev = cpu_to_le64(prev); 710 nilfs_checkpoint_set_snapshot(cp); 711 kunmap_atomic(kaddr); 712 713 kaddr = kmap_atomic(prev_bh->b_page); 714 list = nilfs_cpfile_block_get_snapshot_list( 715 cpfile, prev, prev_bh, kaddr); 716 list->ssl_next = cpu_to_le64(cno); 717 kunmap_atomic(kaddr); 718 719 kaddr = kmap_atomic(header_bh->b_page); 720 header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr); 721 le64_add_cpu(&header->ch_nsnapshots, 1); 722 kunmap_atomic(kaddr); 723 724 mark_buffer_dirty(prev_bh); 725 mark_buffer_dirty(curr_bh); 726 mark_buffer_dirty(cp_bh); 727 mark_buffer_dirty(header_bh); 728 nilfs_mdt_mark_dirty(cpfile); 729 730 brelse(prev_bh); 731 732 out_curr: 733 brelse(curr_bh); 734 735 out_header: 736 brelse(header_bh); 737 738 out_cp: 739 brelse(cp_bh); 740 741 out_sem: 742 up_write(&NILFS_MDT(cpfile)->mi_sem); 743 return ret; 744 } 745 746 static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno) 747 { 748 struct buffer_head *header_bh, *next_bh, *prev_bh, *cp_bh; 749 struct nilfs_cpfile_header *header; 750 struct nilfs_checkpoint *cp; 751 struct nilfs_snapshot_list *list; 752 __u64 next, prev; 753 void *kaddr; 754 int ret; 755 756 if (cno == 0) 757 return -ENOENT; /* checkpoint number 0 is invalid */ 758 down_write(&NILFS_MDT(cpfile)->mi_sem); 759 760 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); 761 if (ret < 0) 762 goto out_sem; 763 kaddr = kmap_atomic(cp_bh->b_page); 764 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr); 765 if (nilfs_checkpoint_invalid(cp)) { 766 ret = -ENOENT; 767 kunmap_atomic(kaddr); 768 goto out_cp; 769 } 770 if (!nilfs_checkpoint_snapshot(cp)) { 771 ret = 0; 772 kunmap_atomic(kaddr); 773 goto out_cp; 774 } 775 776 list = &cp->cp_snapshot_list; 777 next = le64_to_cpu(list->ssl_next); 778 prev = le64_to_cpu(list->ssl_prev); 779 kunmap_atomic(kaddr); 780 781 ret = nilfs_cpfile_get_header_block(cpfile, &header_bh); 782 if (ret < 0) 783 goto out_cp; 784 if (next != 0) { 785 ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 0, 786 &next_bh); 787 if (ret < 0) 788 goto out_header; 789 } else { 790 next_bh = header_bh; 791 get_bh(next_bh); 792 } 793 if (prev != 0) { 794 ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0, 795 &prev_bh); 796 if (ret < 0) 797 goto out_next; 798 } else { 799 prev_bh = header_bh; 800 get_bh(prev_bh); 801 } 802 803 kaddr = kmap_atomic(next_bh->b_page); 804 list = nilfs_cpfile_block_get_snapshot_list( 805 cpfile, next, next_bh, kaddr); 806 list->ssl_prev = cpu_to_le64(prev); 807 kunmap_atomic(kaddr); 808 809 kaddr = kmap_atomic(prev_bh->b_page); 810 list = nilfs_cpfile_block_get_snapshot_list( 811 cpfile, prev, prev_bh, kaddr); 812 list->ssl_next = cpu_to_le64(next); 813 kunmap_atomic(kaddr); 814 815 kaddr = kmap_atomic(cp_bh->b_page); 816 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr); 817 cp->cp_snapshot_list.ssl_next = cpu_to_le64(0); 818 cp->cp_snapshot_list.ssl_prev = cpu_to_le64(0); 819 nilfs_checkpoint_clear_snapshot(cp); 820 kunmap_atomic(kaddr); 821 822 kaddr = kmap_atomic(header_bh->b_page); 823 header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr); 824 le64_add_cpu(&header->ch_nsnapshots, -1); 825 kunmap_atomic(kaddr); 826 827 mark_buffer_dirty(next_bh); 828 mark_buffer_dirty(prev_bh); 829 mark_buffer_dirty(cp_bh); 830 mark_buffer_dirty(header_bh); 831 nilfs_mdt_mark_dirty(cpfile); 832 833 brelse(prev_bh); 834 835 out_next: 836 brelse(next_bh); 837 838 out_header: 839 brelse(header_bh); 840 841 out_cp: 842 brelse(cp_bh); 843 844 out_sem: 845 up_write(&NILFS_MDT(cpfile)->mi_sem); 846 return ret; 847 } 848 849 /** 850 * nilfs_cpfile_is_snapshot - 851 * @cpfile: inode of checkpoint file 852 * @cno: checkpoint number 853 * 854 * Description: 855 * 856 * Return Value: On success, 1 is returned if the checkpoint specified by 857 * @cno is a snapshot, or 0 if not. On error, one of the following negative 858 * error codes is returned. 859 * 860 * %-EIO - I/O error. 861 * 862 * %-ENOMEM - Insufficient amount of memory available. 863 * 864 * %-ENOENT - No such checkpoint. 865 */ 866 int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno) 867 { 868 struct buffer_head *bh; 869 struct nilfs_checkpoint *cp; 870 void *kaddr; 871 int ret; 872 873 /* 874 * CP number is invalid if it's zero or larger than the 875 * largest existing one. 876 */ 877 if (cno == 0 || cno >= nilfs_mdt_cno(cpfile)) 878 return -ENOENT; 879 down_read(&NILFS_MDT(cpfile)->mi_sem); 880 881 ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh); 882 if (ret < 0) 883 goto out; 884 kaddr = kmap_atomic(bh->b_page); 885 cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); 886 if (nilfs_checkpoint_invalid(cp)) 887 ret = -ENOENT; 888 else 889 ret = nilfs_checkpoint_snapshot(cp); 890 kunmap_atomic(kaddr); 891 brelse(bh); 892 893 out: 894 up_read(&NILFS_MDT(cpfile)->mi_sem); 895 return ret; 896 } 897 898 /** 899 * nilfs_cpfile_change_cpmode - change checkpoint mode 900 * @cpfile: inode of checkpoint file 901 * @cno: checkpoint number 902 * @status: mode of checkpoint 903 * 904 * Description: nilfs_change_cpmode() changes the mode of the checkpoint 905 * specified by @cno. The mode @mode is NILFS_CHECKPOINT or NILFS_SNAPSHOT. 906 * 907 * Return Value: On success, 0 is returned. On error, one of the following 908 * negative error codes is returned. 909 * 910 * %-EIO - I/O error. 911 * 912 * %-ENOMEM - Insufficient amount of memory available. 913 * 914 * %-ENOENT - No such checkpoint. 915 */ 916 int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode) 917 { 918 int ret; 919 920 switch (mode) { 921 case NILFS_CHECKPOINT: 922 if (nilfs_checkpoint_is_mounted(cpfile->i_sb, cno)) 923 /* 924 * Current implementation does not have to protect 925 * plain read-only mounts since they are exclusive 926 * with a read/write mount and are protected from the 927 * cleaner. 928 */ 929 ret = -EBUSY; 930 else 931 ret = nilfs_cpfile_clear_snapshot(cpfile, cno); 932 return ret; 933 case NILFS_SNAPSHOT: 934 return nilfs_cpfile_set_snapshot(cpfile, cno); 935 default: 936 return -EINVAL; 937 } 938 } 939 940 /** 941 * nilfs_cpfile_get_stat - get checkpoint statistics 942 * @cpfile: inode of checkpoint file 943 * @stat: pointer to a structure of checkpoint statistics 944 * 945 * Description: nilfs_cpfile_get_stat() returns information about checkpoints. 946 * 947 * Return Value: On success, 0 is returned, and checkpoints information is 948 * stored in the place pointed by @stat. On error, one of the following 949 * negative error codes is returned. 950 * 951 * %-EIO - I/O error. 952 * 953 * %-ENOMEM - Insufficient amount of memory available. 954 */ 955 int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat) 956 { 957 struct buffer_head *bh; 958 struct nilfs_cpfile_header *header; 959 void *kaddr; 960 int ret; 961 962 down_read(&NILFS_MDT(cpfile)->mi_sem); 963 964 ret = nilfs_cpfile_get_header_block(cpfile, &bh); 965 if (ret < 0) 966 goto out_sem; 967 kaddr = kmap_atomic(bh->b_page); 968 header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr); 969 cpstat->cs_cno = nilfs_mdt_cno(cpfile); 970 cpstat->cs_ncps = le64_to_cpu(header->ch_ncheckpoints); 971 cpstat->cs_nsss = le64_to_cpu(header->ch_nsnapshots); 972 kunmap_atomic(kaddr); 973 brelse(bh); 974 975 out_sem: 976 up_read(&NILFS_MDT(cpfile)->mi_sem); 977 return ret; 978 } 979 980 /** 981 * nilfs_cpfile_read - read or get cpfile inode 982 * @sb: super block instance 983 * @cpsize: size of a checkpoint entry 984 * @raw_inode: on-disk cpfile inode 985 * @inodep: buffer to store the inode 986 */ 987 int nilfs_cpfile_read(struct super_block *sb, size_t cpsize, 988 struct nilfs_inode *raw_inode, struct inode **inodep) 989 { 990 struct inode *cpfile; 991 int err; 992 993 if (cpsize > sb->s_blocksize) { 994 printk(KERN_ERR 995 "NILFS: too large checkpoint size: %zu bytes.\n", 996 cpsize); 997 return -EINVAL; 998 } else if (cpsize < NILFS_MIN_CHECKPOINT_SIZE) { 999 printk(KERN_ERR 1000 "NILFS: too small checkpoint size: %zu bytes.\n", 1001 cpsize); 1002 return -EINVAL; 1003 } 1004 1005 cpfile = nilfs_iget_locked(sb, NULL, NILFS_CPFILE_INO); 1006 if (unlikely(!cpfile)) 1007 return -ENOMEM; 1008 if (!(cpfile->i_state & I_NEW)) 1009 goto out; 1010 1011 err = nilfs_mdt_init(cpfile, NILFS_MDT_GFP, 0); 1012 if (err) 1013 goto failed; 1014 1015 nilfs_mdt_set_entry_size(cpfile, cpsize, 1016 sizeof(struct nilfs_cpfile_header)); 1017 1018 err = nilfs_read_inode_common(cpfile, raw_inode); 1019 if (err) 1020 goto failed; 1021 1022 unlock_new_inode(cpfile); 1023 out: 1024 *inodep = cpfile; 1025 return 0; 1026 failed: 1027 iget_failed(cpfile); 1028 return err; 1029 } 1030