1/* 2 * Copyright 2016, NICTA 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(NICTA_GPL) 9 */ 10 11#include <bilbyfs.h> 12 13int ostore_init(struct bilbyfs_info *bi) 14{ 15 struct bilbyfs_wbuf *wbuf = &bi->wbuf; 16 int err; 17 18 wbuf->buf = vmalloc(bi->super.leb_size); 19 if (!wbuf->buf) 20 return -ENOMEM; 21 bi->sup_wbuf.buf = vmalloc(bi->super.leb_size); 22 if (!bi->sup_wbuf.buf) { 23 vfree(wbuf->buf); 24 return -ENOMEM; 25 } 26 bi->summary = vmalloc(bi->super.leb_size); 27 if (!bi->summary) { 28 vfree(wbuf->buf); 29 vfree(bi->sup_wbuf.buf); 30 return -ENOMEM; 31 } 32 bi->summary->nb_sum_entry = 0; 33 wbuf->size = bi->super.leb_size; 34 bi->sup_wbuf.size = bi->super.leb_size; 35 err = allocpool_init(&bi->node_pool); 36 if (!err) { 37 err = idx_init(bi); 38 if (!err) { 39 err = fsm_init(bi); 40 if (!err) { 41 err = wbuf_init(bi); 42 if (!err) { 43 err = gim_init(bi); 44 if (!err) { 45 err = gc_init(bi); 46 if (!err) 47 return 0; 48 gim_clean(bi); 49 } 50 wbuf_clean(bi); 51 } 52 fsm_clean(bi); 53 } 54 idx_clean(bi); 55 } 56 allocpool_destroy(&bi->node_pool); 57 } 58 vfree(wbuf->buf); 59 vfree(bi->sup_wbuf.buf); 60 vfree(bi->summary); 61 return err; 62} 63 64void ostore_clean(struct bilbyfs_info *bi) 65{ 66 struct bilbyfs_wbuf *wbuf = &bi->wbuf; 67 68 vfree(wbuf->buf); 69 memset(wbuf, 0, sizeof(*wbuf)); 70 vfree(bi->sup_wbuf.buf); 71 memset(&bi->sup_wbuf, 0, sizeof(*wbuf)); 72 vfree(bi->summary); 73 idx_clean(bi); 74 fsm_clean(bi); 75 wbuf_clean(bi); 76 gim_clean(bi); 77 gc_clean(bi); 78 allocpool_destroy(&bi->node_pool); 79} 80 81int ostore_get_obj_size(struct bilbyfs_info *bi, obj_id id) 82{ 83 struct obj_addr addr; 84 int err; 85 86 err = idx_get_obj_addr(bi, id, &addr); 87 if (err) 88 return err; 89 return addr.len; 90} 91 92int ostore_read_obj(struct bilbyfs_info *bi, obj_id id, void *buf, u32 len) 93{ 94 struct obj_addr addr; 95 int err; 96 97 err = idx_get_obj_addr(bi, id, &addr); 98 if (err) 99 return err; 100 101 if (len < addr.len) { 102 bilbyfs_err("ostore_read_obj: buf too small\n"); 103 return -EINVAL; /* please try again with a larger buffer */ 104 } 105 106 if (addr.lnum == fsm_get_lnum(bi)) { /* Read from write-buffer */ 107 bilbyfs_debug("read_obj(oid=%llx) from buffer\n", id); 108 memcpy(buf, bi->wbuf.buf + addr.offs, addr.len); 109 return 0; 110 } 111 err = wbuf_read_obj(bi, buf, &addr); 112 { 113 struct obj_ch *obj = buf; 114 bilbyfs_debug("read_obj({%s,oid=%llx}, {lnum=%d,offs=%d,len=%d}) = %d\n", 115 (obj->type == BILBYFS_INODE_OBJ ? "inode" : 116 (obj->type == BILBYFS_DENTARR_OBJ ? "dentarr": 117 (obj->type == BILBYFS_DATA_OBJ ? "data" : 118 (obj->type == BILBYFS_DEL_OBJ ? "del" : "unknown")))), 119 id, 120 addr.lnum, addr.offs, addr.len, err); 121 bilbyfs_assert(get_obj_id(obj) == id); 122 (void)obj; 123 } 124 return err; 125} 126 127obj_id ostore_next_obj_id(struct bilbyfs_info *bi, obj_id id) 128{ 129 obj_id nxt = idx_next_obj_id(bi, id); 130 if (inum_from_id(id) == inum_from_id(nxt)) 131 return nxt; 132 return NIL_ID; 133} 134 135/** 136 * proc_obj - process an object 137 * 138 * @bi: global fs info 139 * @type: type of the object 140 * @id: ID of the object 141 * @addr: address of the object on disk 142 * 143 * This function will update: 144 * - Index: if the object is newer, update the index with the object 145 * - FSM: older version (if exist) of an object is marked as dirty 146 * 147 * Returns negative error code if unsuccessful or zero otherwise 148 */ 149static int proc_obj(struct bilbyfs_info *bi, u8 type, obj_id id, struct obj_addr *addr) 150{ 151 obj_id curr_id; 152 struct obj_addr old_addr; 153 struct idx_node *idx_node; 154 struct gim_node *gnode; 155 int err = 0; 156 157 switch (type) { 158 case BILBYFS_PAD_OBJ: 159 fsm_mark_dirty(bi, addr); 160 break; 161 case BILBYFS_INODE_OBJ: 162 case BILBYFS_DENTARR_OBJ: 163 case BILBYFS_DATA_OBJ: 164 /* Valid object */ 165 idx_node = idx_get_or_create_obj_addr_node(bi, id); 166 if (!idx_node->addr.sqnum) { /* If we just created this node */ 167 idx_node->addr = *addr; 168 } else { 169 if (idx_node->addr.sqnum < addr->sqnum) { 170 /* idx_set_obj_addr(bi, id, addr, NULL); */ 171 idx_node->addr = *addr; 172 gim_mark_garbage(bi, id, &idx_node->addr, NULL); 173 fsm_mark_dirty(bi, &idx_node->addr); 174 } else { 175 gim_mark_garbage(bi, id, addr, NULL); 176 fsm_mark_dirty(bi, addr); 177 } 178 } 179 break; 180 case BILBYFS_DEL_OBJ: 181 /* Delete object */ 182 switch (type_from_id(id)) { 183 case BILBYFS_DENTARR_OBJ: 184 /* Deletion object that cover single object */ 185 err = idx_get_obj_addr(bi, id, &old_addr); 186 if (!err) { /* Obj found in index */ 187 if (old_addr.sqnum < addr->sqnum) { 188 gnode = idx_del_obj_addr(bi, id); 189 gim_mark_garbage(bi, id, &old_addr, gnode); 190 fsm_mark_dirty(bi, &old_addr); 191 } 192 } 193 194 break; 195 case BILBYFS_INODE_OBJ: 196 case BILBYFS_DATA_OBJ: 197 /* Deletion object that cover a range of objects */ 198 for (curr_id = id; curr_id != NIL_ID; curr_id = idx_next_obj_id(bi, curr_id)) { 199 err = idx_get_obj_addr(bi, curr_id, &old_addr); 200 if (!err) { 201 if (old_addr.sqnum < addr->sqnum) { 202 gnode = idx_del_obj_addr(bi, curr_id); 203 gim_mark_garbage(bi, curr_id, &old_addr, gnode); 204 fsm_mark_dirty(bi, &old_addr); 205 } 206 } 207 } 208 break; 209 default: 210 bilbyfs_assert(0); 211 } 212 /* Mark the deletion object itself as dirty */ 213 gim_mark_garbage(bi, id, addr, NULL); 214 fsm_mark_dirty(bi, addr); 215 break; 216 default: 217 bilbyfs_assert(0); 218 } 219 220 return 0; 221} 222 223static u8 get_obj_trans(int count, int i) 224{ 225 if (count == 1) 226 return BILBYFS_TRANS_ATOM; 227 else if (i == 0) 228 return BILBYFS_TRANS_ST; 229 else if (i == count - 1) 230 return BILBYFS_TRANS_END; 231 return BILBYFS_TRANS_IN; 232} 233 234#define NOBJ BILBYFS_MAX_OBJ_PER_TRANS 235int obj_has_id(struct obj_ch *obj) 236{ 237 return (obj->type == BILBYFS_INODE_OBJ || 238 obj->type == BILBYFS_DENTARR_OBJ || 239 obj->type == BILBYFS_DATA_OBJ || 240 obj->type == BILBYFS_DEL_OBJ); 241} 242 243static inline int debug_print_objs(struct bilbyfs_info *bi, u32 lnum) 244{ 245 struct obj_ch **olist, **olist2; 246 struct obj_addr addr; 247 int err; 248 int i; 249 struct obj_ch *obj; 250 struct bilbyfs_rbuf rbuf; 251 int nbo, nbo2; 252 253 bilbyfs_debug("ostore_scan_obj() : alloc = %lu\n", (unsigned long)(sizeof(*olist) * NOBJ)); 254 olist = kmalloc(sizeof(*olist) * NOBJ); 255 if (!olist) 256 return -ENOMEM; 257 rbuf.buf = bi->wbuf.buf; 258 rbuf.size = bi->wbuf.size; 259 rbuf.offs = 0; 260 err = ostore_scan_obj(bi, &rbuf, lnum, (void **)olist, NOBJ); 261 bilbyfs_debug("ostore_scan_obj() = %d\n", err); 262 if (err < 0) { 263 kfree(olist); 264 return err; 265 } 266 addr.lnum = lnum; 267 addr.offs = 0; 268 addr.len = 0; 269 nbo = err; 270 for (i = 0; i < nbo; i++) { 271 obj = olist[i]; 272 addr.len = obj->len; 273 bilbyfs_debug("scan_obj({%s,oid=%llx}, {lnum=%d,offs=%d,len=%d})\n", 274 (obj->type == BILBYFS_INODE_OBJ ? "inode" : 275 (obj->type == BILBYFS_DENTARR_OBJ ? "dentarr": 276 (obj->type == BILBYFS_DATA_OBJ ? "data" : 277 (obj->type == BILBYFS_DEL_OBJ ? "del" : 278 (obj->type == BILBYFS_SUP_OBJ ? "super" : 279 (obj->type == BILBYFS_PAD_OBJ ? "pad" : "unknown")))))), 280 (!obj_has_id(obj) ? 0 : get_obj_id(obj)), 281 addr.lnum, addr.offs, addr.len); 282 addr.offs += addr.len; 283 } 284 bilbyfs_debug("ostore_scan_obj() = %d\n", err); 285 olist2 = kmalloc(sizeof(*olist) * NOBJ); 286 if (!olist2) 287 return -ENOMEM; 288 err = ostore_scan_leb_obj(bi, &bi->rbuf, lnum, (void **)olist2, NOBJ); 289 if (err < 0) { 290 kfree(olist); 291 kfree(olist2); 292 return err; 293 } 294 addr.lnum = lnum; 295 addr.offs = 0; 296 addr.len = 0; 297 nbo2 = err; 298 for (i = 0; i < nbo2; i++) { 299 obj = olist2[i]; 300 addr.len = obj->len; 301 bilbyfs_debug("scan_obj({%s,oid=%llx}, {lnum=%d,offs=%d,len=%d})\n", 302 (obj->type == BILBYFS_INODE_OBJ ? "inode" : 303 (obj->type == BILBYFS_DENTARR_OBJ ? "dentarr": 304 (obj->type == BILBYFS_DATA_OBJ ? "data" : 305 (obj->type == BILBYFS_DEL_OBJ ? "del" : 306 (obj->type == BILBYFS_SUP_OBJ ? "super" : 307 (obj->type == BILBYFS_PAD_OBJ ? "pad" : "unknown")))))), 308 (!obj_has_id(obj) ? 0 : get_obj_id(obj)), 309 addr.lnum, addr.offs, addr.len); 310 err = memcmp(obj, olist[i], obj->len); 311 bilbyfs_assert(!err); 312 addr.offs += addr.len; 313 } 314 if (nbo != nbo2) { 315 print_hex_dump(KERN_ERR, "wbuf: ", DUMP_PREFIX_ADDRESS, 32, 8, rbuf.buf, rbuf.size, true); 316 print_hex_dump(KERN_ERR, "rbuf: ", DUMP_PREFIX_ADDRESS, 32, 8, bi->rbuf.buf, bi->rbuf.size, true); 317 } 318 kfree(olist2); 319 kfree(olist); 320 return 0; 321} 322 323int obj_sum_size_with_extra(struct obj_sum *sum, u32 nb_extra_entries) 324{ 325 return ALIGN(obj_sum_size(sum) + nb_extra_entries * BILBYFS_SUM_ENTRY_SZ, BILBYFS_OBJ_PADDING); 326} 327 328int ostore_write_summary(struct bilbyfs_info *bi, u32 *padding_sz) 329{ 330 struct bilbyfs_wbuf *wbuf = &bi->wbuf; 331 struct obj_ch *ch; 332 int err; 333 u32 len; 334 u32 pad_sz; 335 336 len = obj_sum_size(bi->summary); 337 bilbyfs_assert(wbuf->avail >= len); 338 339 /* wbuf summary aware padding */ 340 pad_sz = wbuf->avail - len; 341 if (pad_sz < BILBYFS_CH_SZ) { 342 memset(wbuf->buf + wbuf->used, BILBYFS_PAD_BYTE, pad_sz); 343 } else { 344 ch = wbuf->buf + wbuf->used; 345 pack_obj_pad(ch, pad_sz); 346 pack_obj_header(ch, next_sqnum(bi), BILBYFS_TRANS_ATOM); 347 } 348 if (padding_sz) 349 *padding_sz = pad_sz; 350 wbuf->avail -= pad_sz; 351 wbuf->used += pad_sz; 352 pack_obj_sum(bi->summary, wbuf->used); 353 pack_obj_header(&bi->summary->ch, next_sqnum(bi), BILBYFS_TRANS_ATOM); 354 err = wbuf_write_obj(bi, bi->summary, len, wbuf); 355 bilbyfs_debug("ostore_write_summary(offset=%u) = %d\n", wbuf->used, err); 356 if (!err) 357 bi->summary->nb_sum_entry = 0; 358 bilbyfs_assert(wbuf->avail == 0); 359 return err; 360} 361 362void sum_obj(struct bilbyfs_info *bi, struct obj_ch *obj, struct obj_addr *addr) 363{ 364 struct obj_sum *sum = bi->summary; 365 struct obj_sum_entry *entry; 366 obj_id oid, eoid; 367 u8 oid_type; 368 u32 nb_sum_entry = le32_to_cpu(sum->nb_sum_entry); 369 bool is_del; 370 int i; 371 372 oid = get_obj_id(obj); 373 oid_type = type_from_id(oid); 374 is_del = obj->type == BILBYFS_DEL_OBJ; 375 376 /* If we have a deletion object, we can only replace younger deletion 377 * objects that have the exact same oid in case of dentarr deletion or 378 * objects that have a higher oid for inode and data deletion objects. 379 * Summary of non-deletion objects can only replace objects with 380 * the exact same oid. 381 */ 382 if (is_del) { 383 for (i = 0; i < nb_sum_entry; i++) { 384 entry = &sum->entries[i]; 385 eoid = le64_to_cpu(entry->id); 386 387 if (oid_type == BILBYFS_DENTARR_OBJ) { 388 if (eoid == oid) { 389 if (le64_to_cpu(entry->sqnum) > addr->sqnum) { 390 return; 391 } 392 break; 393 } 394 } else if (inum_from_id(eoid) == inum_from_id(oid) && eoid > oid) { 395 if (le64_to_cpu(entry->sqnum) < addr->sqnum) 396 break; 397 } 398 } 399 } else { 400 for (i = 0; i < nb_sum_entry; i++) { 401 entry = &sum->entries[i]; 402 /* We cannot replace a del object with an new object */ 403 if (obj_sum_entry_is_del(entry) && oid_type != BILBYFS_DENTARR_OBJ) 404 continue; 405 eoid = le64_to_cpu(entry->id); 406 if (eoid == oid) { 407 if (le64_to_cpu(entry->sqnum) > addr->sqnum) 408 return; 409 break; 410 } 411 } 412 } 413 /* Not that the whole if/else above is an optimisation to 414 * reuse a sum_entry, we could safely replace it with 415 * i = nb_sum_entry; 416 */ 417 entry = &sum->entries[i]; 418 entry->id = oid; 419 entry->len = cpu_to_le32(addr->len); 420 entry->sqnum = cpu_to_le64(addr->sqnum); 421 entry->del_flag_and_offs = cpu_to_le32(addr->offs | (is_del ? BILBYFS_SUM_ENTRY_DEL_FLAG_MASK : 0)); 422 if (i == nb_sum_entry) { 423 sum->nb_sum_entry = cpu_to_le32(nb_sum_entry + 1); 424 entry->count = 0; 425 } else 426 entry->count = cpu_to_le32(le32_to_cpu(entry->count) + 1); 427} 428 429int ostore_sync(struct bilbyfs_info *bi, int force_summary) 430{ 431 struct bilbyfs_wbuf *wbuf = &bi->wbuf; 432 int err = 0; 433 u32 padding_size; 434 struct obj_addr curr_addr; 435 u32 sum_sz; 436 437 bilbyfs_debug("ostore_sync()\n"); 438 if (bi->no_summary) 439 force_summary = 0; 440 if (wbuf->sync_offs == wbuf->used && !force_summary) 441 return 0; 442 if (!wbuf->avail) 443 return 0; 444 bilbyfs_assert(!!fsm_get_lnum(bi)); 445 curr_addr.lnum = fsm_get_lnum(bi); 446 curr_addr.offs = wbuf->used; 447 /* Pad buffer to min_io_size */ 448 /* 449 * We want to pad with a obj_pad only if that leaves enough space to 450 * write at least one more object (remember we also need to count space 451 * for the summary). 452 */ 453 sum_sz = obj_sum_size_with_extra(bi->summary, 1); 454 if (!bi->no_summary && (force_summary || ALIGN(wbuf->used, bi->super.min_io_size) + sum_sz + BILBYFS_MIN_OBJ_SZ > bi->super.leb_size)) { 455 err = ostore_write_summary(bi, &padding_size); 456 if (err) 457 return err; 458 } else 459 wbuf_prepare_commit(bi, &padding_size, wbuf); 460 461 if (padding_size > 0) { 462 curr_addr.len = padding_size; 463 fsm_mark_dirty(bi, &curr_addr); 464 } 465 err = wbuf_commit(bi, fsm_get_lnum(bi), wbuf); 466 /* bilbyfs_debug("debug_print_obj(%u) = %d\n", fsm_get_lnum(bi), debug_print_objs(bi, fsm_get_lnum(bi))); */ 467 return err; 468} 469 470u32 obj_list_serial_size(struct obj_ch **obj_list, int count) 471{ 472 u32 sz = 0; 473 int i; 474 475 for (i = 0; i < count; i++) { 476 sz += obj_list[i]->len; 477 } 478 return sz; 479} 480 481int ostore_write_obj_list(struct bilbyfs_info *bi, void **obj_list, int count, int osw_flag) 482{ 483 int i; 484 int err = 0; 485 struct obj_ch *obj; 486 struct obj_addr curr_addr; 487 struct bilbyfs_wbuf *wbuf = &bi->wbuf; 488 u32 serial_sz; 489 u32 offs; 490 491 if (!fsm_get_lnum(bi) || !wbuf->avail) { 492 err = fsm_alloc_eb(bi, osw_flag); 493 if (err) 494 return err; 495 wbuf_start(bi, wbuf); 496 } 497 bilbyfs_debug("wbuf->avail = %u, obj_sum_size = %u\n", wbuf->avail , obj_sum_size(bi->summary)); 498 if (!bi->no_summary) 499 bilbyfs_assert(wbuf->avail >= obj_sum_size(bi->summary)); 500 if (osw_flag & OSW_SYNC) { 501 err = ostore_sync(bi, false); 502 if (err) 503 return err; 504 } 505 if (!bi->no_summary) 506 bilbyfs_assert(wbuf->avail >= obj_sum_size(bi->summary)); 507 bilbyfs_assert(count > 0); 508 for (i = 0; i < count; i++) { 509 obj = obj_list[i]; 510 pack_obj_header(obj, next_sqnum(bi), get_obj_trans(count, i)); 511 } 512 serial_sz = obj_list_serial_size((struct obj_ch **)obj_list, count); 513 bilbyfs_assert(serial_sz <= bi->super.leb_size); 514 if (wbuf->avail < serial_sz + (bi->no_summary ? 0 : obj_sum_size_with_extra(bi->summary, count))) { 515 err = ostore_sync(bi, true); 516 if (err) 517 return err; 518 err = fsm_alloc_eb(bi, osw_flag); 519 if (err) 520 return err; 521 wbuf_start(bi, wbuf); 522 } 523 524 offs = wbuf->used; 525 /* Write objects into wbuf */ 526 for (i = 0; i < count; i++) { 527 obj = obj_list[i]; 528 err = wbuf_write_obj(bi, obj, le32_to_cpu(obj->len), wbuf); 529 if (err) 530 return err; 531 } 532 533 if (osw_flag & OSW_SYNC) { 534 err = ostore_sync(bi, false); 535 if (err) 536 return err; 537 } 538 539 /* Preallocate new index and gim entries */ 540 err = allocpool_alloc(&bi->node_pool, count * 2, NODE_SIZE); 541 if (err) 542 return err; 543 544 /* Update index & fsm */ 545 curr_addr.lnum = fsm_get_lnum(bi); 546 curr_addr.offs = offs; 547 curr_addr.len = 0; 548 bilbyfs_debug(".\n"); 549 for (i = 0; i < count; i++) { 550 obj = obj_list[i]; 551 curr_addr.offs += curr_addr.len; 552 curr_addr.len = le32_to_cpu(obj->len); 553 curr_addr.sqnum = le64_to_cpu(obj->sqnum); 554 555 err = proc_obj(bi, obj->type, get_obj_id(obj), &curr_addr); 556 bilbyfs_debug("write_obj({%s,oid=%llx}, {lnum=%d,offs=%d,len=%d,sqnum=%llu}) = %d\n", 557 (obj->type == BILBYFS_INODE_OBJ ? "inode" : 558 (obj->type == BILBYFS_DENTARR_OBJ ? "dentarr": 559 (obj->type == BILBYFS_DATA_OBJ ? "data" : 560 (obj->type == BILBYFS_DEL_OBJ ? "del" : "unknown")))), 561 get_obj_id(obj), 562 curr_addr.lnum, curr_addr.offs, curr_addr.len, curr_addr.sqnum, err); 563 if (err) 564 bilbyfs_assert(false); 565 if (!bi->no_summary) 566 sum_obj(bi, obj, &curr_addr); 567 } 568 allocpool_empty(&bi->node_pool); 569 return 0; 570} 571 572int ostore_erase(struct bilbyfs_info *bi, int lnum) 573{ 574 int err; 575 576 err = wbuf_erase(bi, lnum); 577 if (err) 578 return err; 579 580 fsm_mark_erased(bi, lnum); 581 return 0; 582} 583 584int ostore_scan_obj(struct bilbyfs_info *bi, struct bilbyfs_rbuf *rbuf, int lnum, 585 void **list, int max_count) 586{ 587 int err; 588 struct obj_addr addr; 589 struct obj_ch *obj; 590 int count = 0; 591 592 addr.lnum = lnum; 593 addr.offs = 0; 594 addr.len = 0; 595 obj = wbuf_next_obj_addr(bi, &addr, rbuf); 596 while (!IS_ERR(obj)) { 597 if (count >= max_count) 598 return -EOVERFLOW; 599 list[count] = obj; 600 count++; 601 obj = wbuf_next_obj_addr(bi, &addr, rbuf); 602 } 603 err = PTR_ERR(obj); 604 if (err == -ENOENT) 605 if (count > 0) 606 return count; 607 return err; 608} 609 610int ostore_scan_leb_obj(struct bilbyfs_info *bi, struct bilbyfs_rbuf *rbuf, int lnum, 611 void **list, int max_count) 612{ 613 int err; 614 615 rbuf->offs = 0; 616 err = wbuf_read_leb(bi, lnum, rbuf); 617 if (err) 618 return err; 619 return ostore_scan_obj(bi, rbuf, lnum, list, max_count); 620} 621 622unsigned long long ostore_get_free_space(struct bilbyfs_info *bi) 623{ 624 return fsm_get_free_space(bi); 625} 626 627unsigned long long ostore_get_available_space(struct bilbyfs_info *bi) 628{ 629 return fsm_get_available_space(bi); 630} 631 632static struct obj_super *next_super_addr(struct bilbyfs_info *bi, 633 struct obj_addr *addr, 634 struct bilbyfs_rbuf *rbuf) 635{ 636 struct obj_ch *obj; 637 638 do { 639 obj = wbuf_next_obj_addr(bi, addr, rbuf); 640 if (IS_ERR(obj)) 641 return (struct obj_super *)obj; 642 } while (obj->type != BILBYFS_SUP_OBJ); 643 return (struct obj_super *)obj; 644} 645 646/* SuperBlock objects are sequentially stored in BILBYFS_SUP_LNUM 647 * When BILBYFS_SUP_LNUM is full we need to atomically erase the erase-block 648 * and store a new object in it. To this end we use ubi_leb_change. 649 */ 650static int mount_read_super(struct bilbyfs_info *bi) 651{ 652 struct bilbyfs_rbuf *rbuf = &bi->rbuf; 653 struct obj_super *super, *perr; 654 struct obj_addr addr; 655 int err; 656 657 err = wbuf_read_leb_fast(bi, BILBYFS_SUP_LNUM, rbuf); 658 if (err) 659 return err; 660 661 addr.lnum = BILBYFS_SUP_LNUM; 662 addr.offs = 0; 663 addr.len = 0; 664 perr = next_super_addr(bi, &addr, rbuf); 665 super = perr; 666 while (!IS_ERR(perr)) { 667 super = perr; 668 perr = next_super_addr(bi, &addr, rbuf); 669 } 670 if (IS_ERR(super)) 671 return PTR_ERR(super); 672 673 if (super->ch.type != BILBYFS_SUP_OBJ || 674 le32_to_cpu(super->ch.len) != BILBYFS_SUPER_SZ) { 675 bilbyfs_err("Invalid Super object!\n"); 676 return -EINVAL; 677 } 678 unpack_obj_super(&bi->super, super); 679 bi->super.min_io_size = bi->di.min_io_size; 680 /* FIXME: Ensure that max_io_size is only used for write accesses */ 681 bi->super.max_io_size = bi->di.max_write_size; 682 /* Go to the very last object and get the offs */ 683 while (!IS_ERR(wbuf_next_obj_addr(bi, &addr, rbuf))); 684 bi->super_offs = addr.offs + addr.len; 685 686 if (bi->next_sqnum < bi->super.sqnum) /* FIXME sanity check */ 687 bi->next_sqnum = bi->super.sqnum + 1; 688 if (bi->next_inum < bi->super.last_inum) /* FIXME sanity check */ 689 bi->next_inum = bi->super.last_inum + 1; 690 return 0; 691} 692 693int ostore_write_super(struct bilbyfs_info *bi) 694{ 695 struct bilbyfs_wbuf *wbuf = &bi->sup_wbuf; 696 struct obj_super sup; 697 int size_trans; 698 int err; 699 700 bilbyfs_debug("ostore_write_super(lnum = %d, offs = %d) = ?\n", 701 BILBYFS_SUP_LNUM, bi->super_offs); 702 703 bi->super.log_lnum = fsm_get_lnum(bi); 704 bi->super.log_offs = bi->wbuf.sync_offs; 705 bi->super.last_inum = bi->next_inum - 1; 706 wbuf_start(bi, wbuf); 707 wbuf->used = bi->super_offs; 708 wbuf->sync_offs = bi->super_offs; 709 memset(&sup, 0, sizeof(sup)); 710 pack_obj_super(&sup, &bi->super); 711 pack_obj_header(&sup, next_sqnum(bi), BILBYFS_TRANS_ATOM); 712 err = wbuf_write_obj(bi, &sup, BILBYFS_SUPER_SZ, wbuf); 713 if (!err) { 714 size_trans = wbuf_prepare_commit(bi, NULL, wbuf); 715 err = wbuf_commit(bi, BILBYFS_SUP_LNUM, wbuf); 716 if (!err) /* Obtain the next super offset */ 717 bi->super_offs = wbuf->used; 718 } else { 719 wbuf_start(bi, wbuf); 720 err = wbuf_write_obj(bi, &sup, BILBYFS_SUPER_SZ, wbuf); 721 if (!err) { 722 size_trans = wbuf_prepare_commit(bi, NULL, wbuf); 723 err = wbuf_atom_leb_commit(bi, BILBYFS_SUP_LNUM, wbuf); 724 if (!err) /* Obtain the next super offset */ 725 bi->super_offs = wbuf->used; 726 } 727 } 728 return err; 729} 730 731static int mount_check_super(struct bilbyfs_info *bi) 732{ 733 struct bilbyfs_super *sup = &bi->super; 734 735 if (sup->leb_size != bi->vi.usable_leb_size) { 736 bilbyfs_err("super.leb_size (%d) is not compatible with the" 737 "vi.usable_leb_size (%d) of the flash\n", 738 sup->leb_size, bi->vi.usable_leb_size); 739 return -EINVAL; 740 } 741 if (sup->min_io_size > sup->leb_size || 742 sup->max_io_size > sup->leb_size || 743 sup->min_io_size > sup->max_io_size || 744 (sup->max_io_size % sup->min_io_size) != 0 || 745 (sup->leb_size % sup->min_io_size) != 0 || 746 (sup->leb_size % sup->max_io_size) != 0) { 747 bilbyfs_err("Invalid leb_size/min_io_size/max_io_size " 748 "combinaison: " 749 "(leb_size = %d, max_io_sz = %d, min_io_sz = %d)", 750 sup->leb_size, sup->max_io_size, sup->min_io_size); 751 return -EINVAL; 752 } 753 if (sup->leb_cnt < sup->nb_reserved_gc + sup->nb_reserved_del + BILBYFS_MIN_USABLE_LOG_SZ) { 754 bilbyfs_err("Number of erasble-blocks too small for nb_(eb|gc|del) and min_usable_log_sz " 755 "(leb_cnt = %d, nb_gc = %d, nb_del = %d, min_usable_log_sz = %d)\n", 756 sup->leb_cnt, sup->nb_reserved_gc, sup->nb_reserved_del, BILBYFS_MIN_USABLE_LOG_SZ); 757 return -EINVAL; 758 } 759 760 return 0; 761} 762 763/** 764 * A list list to store deletion objects and their addresses at mount time 765 */ 766struct list_obj_del { 767 u8 type; 768 obj_id id; 769 struct obj_addr addr; 770 struct list_obj_del *next; 771}; 772 773static int add_to_del_list(struct list_obj_del **del_list, obj_id id, struct obj_addr *addr) 774{ 775 struct list_obj_del *node; 776 777 node = kmalloc(sizeof(*node)); 778 if (!node) 779 return -ENOMEM; 780 781 node->id = id; 782 memcpy(&node->addr, addr, sizeof(*addr)); 783 784 node->next = *del_list; 785 *del_list = node; 786 787 return 0; 788} 789 790static void clean_del_list(struct list_obj_del *del_list) 791{ 792 struct list_obj_del *curr, *next; 793 curr = del_list; 794 795 while (curr != NULL) { 796 next = curr->next; 797 kfree(curr); 798 curr = next; 799 } 800} 801 802/* check_trans_pos: Checks whether the transaction attribute @pos is 803 * valid. 804 * @trans_nb_obj: current number of elements in the transaction 805 * @pos: transaction attribute of last element read 806 * 807 * This function returns %-EINVAL if the attribute is invalid, it 808 * returns 1 if it's the last element of the transaction, 0 if more 809 * objects are expected. 810 */ 811static int check_trans_pos(int trans_nb_obj, u8 pos) 812{ 813 switch (pos) { 814 case BILBYFS_TRANS_ATOM: 815 if (trans_nb_obj) 816 return -EINVAL; 817 return 1; 818 case BILBYFS_TRANS_ST: 819 if (trans_nb_obj) 820 return -EINVAL; 821 return 0; 822 case BILBYFS_TRANS_IN: 823 if (!trans_nb_obj) 824 return -EINVAL; 825 return 0; 826 case BILBYFS_TRANS_END: 827 if (!trans_nb_obj) 828 return -EINVAL; 829 return 1; 830 default: 831 bilbyfs_err("Unknown trans pos value %x", pos); 832 return -EINVAL; 833 } 834} 835 836/* mount_scan_rbuf: Scan every object stored in a read-buffer 837 * @bi: global fs info 838 * @addr: address to start with 839 * @rbuf: read-buffer to scan 840 * @del_list: a list to store the deletion objects 841 * 842 * This function returns a negative error-code if unsuccessful. 843 */ 844static int mount_scan_rbuf(struct bilbyfs_info *bi, struct obj_addr *addr, 845 struct bilbyfs_rbuf *rbuf, struct list_obj_del **del_list) 846{ 847 struct obj_addr *addrs; 848 struct obj_ch *obj; 849 int trans_nb_obj = 0; 850 int last; 851 int err; 852 int i; 853 854 bilbyfs_assert(addr->len == 0); 855 addrs = bi->addrs; 856 if (!addrs) 857 return -ENOMEM; 858 859 for (obj = wbuf_next_obj_addr(bi, addr, rbuf); 860 !IS_ERR(obj); 861 obj = wbuf_next_obj_addr(bi, addr, rbuf)) { 862 bilbyfs_debug("mount_scan_rbuf() loop obj->type = %d nb_obj_in_trans=%d\n", obj->type, trans_nb_obj); 863 last = check_trans_pos(trans_nb_obj, obj->trans); 864 /* Invalid transaction value */ 865 if (last < 0) { 866 bilbyfs_err("Invalid trans pos value 0x%x, this may just" 867 "be because of a power-failure.", obj->trans); 868 trans_nb_obj = 0; 869 continue; 870 } 871 872 /* We enqueue all the objects of a transaction */ 873 memcpy(&addrs[trans_nb_obj], addr, sizeof(*addr)); 874 trans_nb_obj++; 875 if (!last) { 876 if (trans_nb_obj == BILBYFS_MAX_OBJ_PER_TRANS) { 877 bilbyfs_err("Invalid transaction with too many objects (%d" 878 "objects, limit=%d)", trans_nb_obj, 879 BILBYFS_MAX_OBJ_PER_TRANS); 880 trans_nb_obj = 0; 881 } 882 continue; 883 } 884 /* This was the last object of the transaction, 885 * will process all the objects. 886 * Note: deletion objects are saved in a list and will be processed later. 887 */ 888 err = allocpool_alloc(&bi->node_pool, trans_nb_obj * 2, NODE_SIZE); 889 if (err) 890 return err; 891 for (i = 0; i < trans_nb_obj; i++) { 892 obj = rbuf->buf + addrs[i].offs; 893 if (obj->type == BILBYFS_DEL_OBJ) 894 err = add_to_del_list(del_list, get_obj_id(obj), &addrs[i]); 895 else if (obj->type == BILBYFS_PAD_OBJ) 896 err = proc_obj(bi, obj->type, 0, &addrs[i]); 897 else if (obj->type != BILBYFS_SUM_OBJ) 898 err = proc_obj(bi, obj->type, get_obj_id(obj), &addrs[i]); 899 900 if (err) { 901 allocpool_empty(&bi->node_pool); 902 return err; 903 } 904 } 905 trans_nb_obj = 0; 906 allocpool_empty(&bi->node_pool); 907 } 908 909 err = PTR_ERR(obj); 910 return err; 911} 912 913int mount_proc_sum(struct bilbyfs_info *bi, u32 lnum, struct obj_sum *sum, u32 maxsz, struct list_obj_del **del_list) 914{ 915 int i; 916 int err; 917 struct obj_addr addr; 918 struct obj_sum_entry *entry; 919 obj_id id; 920 u32 tot_used = 0; 921 922 addr.lnum = lnum; 923 err = check_obj_header(&sum->ch, maxsz); 924 if (err) 925 return err; 926 if (sum->ch.type != BILBYFS_SUM_OBJ) { 927 bilbyfs_debug("Summary object expected, found %d\n", sum->ch.type); 928 return -EINVAL; 929 } 930 for (i = 0; i < le32_to_cpu(sum->nb_sum_entry); i++) { 931 entry = &sum->entries[i]; 932 addr.offs = obj_sum_entry_offs(entry); 933 addr.len = le32_to_cpu(entry->len); 934 tot_used += addr.len; 935 addr.sqnum = le64_to_cpu(entry->sqnum); 936 id = le64_to_cpu(entry->id); 937 // bilbyfs_debug("sum_entry{.offs = %u, .len = %u, .sqnum = %llu, .oid = %llu, .is_del=%u}\n", obj_sum_entry_offs(entry), le32_to_cpu(entry->len), le64_to_cpu(entry->sqnum), le64_to_cpu(entry->id), obj_sum_entry_is_del(entry)); 938 if (obj_sum_entry_is_del(entry)) { 939 err = add_to_del_list(del_list, id, &addr); 940 if (err) 941 return err; 942 } else { 943 err = proc_obj(bi, type_from_id(id), id, &addr); 944 if (err) 945 return err; 946 } 947 gim_mark_garbage_cnt(bi, id, &addr, (u32) cpu_to_le16(entry->count), NULL); 948 } 949 addr.lnum = lnum; 950 addr.len = bi->super.leb_size - tot_used; 951 fsm_mark_dirty(bi, &addr); 952 return 0; 953} 954 955static inline int mount_init_log(struct bilbyfs_info *bi, struct list_obj_del **del_list) 956{ 957 struct bilbyfs_rbuf rbuf; 958 struct obj_addr addr; 959 int err; 960 961 rbuf.buf = bi->wbuf.buf; 962 rbuf.size = bi->wbuf.size; 963 rbuf.offs = 0; 964 bi->fsm_lnum = bi->super.log_lnum; 965 fsm_mark_used(bi, bi->fsm_lnum); 966 err = wbuf_read_leb(bi, bi->super.log_lnum, &rbuf); 967 if (err) 968 return err; 969 addr.lnum = bi->fsm_lnum; 970 addr.offs = 0; 971 addr.len = 0; 972 err = mount_scan_rbuf(bi, &addr, &rbuf, del_list); 973 if (err == -ENOENT) { 974 bi->wbuf.sync_offs = addr.offs + addr.len; 975 bi->wbuf.used = addr.offs + addr.len; 976 bi->wbuf.avail = bi->super.leb_size - bi->wbuf.used; 977 } else if (err) { 978 clean_del_list(*del_list); 979 return err; 980 } else { /* mount_scan_rbuf didn't fail, erase-block is full of valid data */ 981 bi->wbuf.sync_offs = bi->super.leb_size; 982 bi->wbuf.used = bi->super.leb_size; 983 bi->wbuf.avail = 0; 984 } 985 bi->wbuf.buf = rbuf.buf; 986 if (bi->wbuf.sync_offs != bi->super.log_offs) { 987 bilbyfs_err("super.log_offs is different from the content of the erase-block %d, %d != %d\n", bi->super.log_lnum, bi->wbuf.sync_offs, bi->super.log_offs); 988 } 989 return 0; 990} 991 992static int mount_scan(struct bilbyfs_info *bi) 993{ 994 struct obj_addr addr; 995 struct list_obj_del *del_list = NULL; 996 struct list_obj_del *curr; 997 int err = 0; 998 u32 sum_offs; 999 /* struct timeval st, stp; */ 1000 1001 bilbyfs_debug("mount_scan(): Scanning each LEB\n"); 1002 /* 1003 if (bi->super.log_lnum > 0) { 1004 err = mount_init_log(bi, &del_list); 1005 if (err) 1006 return err; 1007 } 1008 */ 1009 bilbyfs_err("BilbyFs mount start\n"); 1010 bi->nb_pages = 0; 1011 bi->nb_extra_pages = 0; 1012 bi->node_pool.tot_nodes_needed = 0; 1013 bi->gim_allocated_for_nothing = 0; 1014 for (addr.lnum = BILBYFS_LOG_FST_LNUM; 1015 addr.lnum < bi->super.leb_cnt; 1016 addr.lnum++) { 1017 if (!ubi_is_mapped(bi->ubi, addr.lnum) /* || addr.lnum == bi->super.log_lnum */) 1018 continue; 1019 fsm_mark_used(bi, addr.lnum); 1020 if (!bi->no_summary) { 1021 /* 1022 do_gettimeofday(&st); 1023 */ 1024 err = wbuf_read_sum(bi, addr.lnum, &bi->rbuf, &sum_offs); 1025 /* 1026 do_gettimeofday(&stp); 1027 pr_err("timed wbuf_read_sum() : %ld sec %ld usec\n", stp.tv_sec - st.tv_sec, stp. tv_usec - st.tv_usec); 1028 */ 1029 if (!err) { 1030 /* do_gettimeofday(&st); */ 1031 err = mount_proc_sum(bi, addr.lnum, (struct obj_sum *)(bi->rbuf.buf + sum_offs), 1032 bi->super.leb_size - sum_offs, &del_list); 1033 /* 1034 do_gettimeofday(&stp); 1035 pr_err("timed mount_proc_sum() : %ld sec %ld usec\n", stp.tv_sec - st.tv_sec, stp. tv_usec - st.tv_usec); 1036 */ 1037 if (err) 1038 return err; 1039 continue; 1040 } 1041 bilbyfs_err("Failure to use the summary, fall back to scanning the erase-block (lnum=%d), err = %d\n", addr.lnum, err); 1042 if (err != -ENOENT) 1043 return err; 1044 } 1045 err = wbuf_read_leb(bi, addr.lnum, &bi->rbuf); 1046 if (err) { 1047 clean_del_list(del_list); 1048 return err; 1049 } 1050 addr.offs = 0; 1051 addr.len = 0; 1052 err = mount_scan_rbuf(bi, &addr, &bi->rbuf, &del_list); 1053 if (err == -ENOENT) { 1054 addr.offs += addr.len; 1055 addr.len = bi->super.leb_size - addr.offs; 1056 fsm_mark_dirty(bi, &addr); 1057 } else if (err) { 1058 clean_del_list(del_list); 1059 return err; 1060 } 1061 } 1062 1063 bilbyfs_debug("mount_scan(): Processing deletion objects\n"); 1064 /* do_gettimeofday(&st); */ 1065 for (curr = del_list; curr; curr = curr->next) { 1066 err = proc_obj(bi, BILBYFS_DEL_OBJ, curr->id, &curr->addr); 1067 if (err) { 1068 clean_del_list(del_list); 1069 return err; 1070 } 1071 } 1072 1073 clean_del_list(del_list); 1074 /* 1075 do_gettimeofday(&stp); 1076 pr_err("timed del_obj_proc() : %ld.%ld\n", stp.tv_sec - st.tv_sec, stp. tv_usec - st.tv_usec); 1077 */ 1078 1079 bilbyfs_err("BilbyFs mount finished pages = %d, extra_pages = %d, tot_nodes = %d, gim_allocated_for nothing = %d\n", bi->nb_pages, bi->nb_extra_pages, bi->node_pool.tot_nodes_needed, bi->gim_allocated_for_nothing); 1080 return 0; 1081} 1082 1083/* Move this to wbuf? */ 1084static int check_flash_empty(struct bilbyfs_info *bi) 1085{ 1086 int empty = 1; 1087 int lnum; 1088 int err; 1089 1090 for (lnum = 0; lnum < bi->super.leb_cnt; lnum++) { 1091 err = ubi_is_mapped(bi->ubi, lnum); 1092 if (err < 0) 1093 return err; 1094 if (err == 1) { 1095 empty = 0; 1096 break; 1097 } 1098 } 1099 return empty; 1100} 1101 1102int ostore_mount(struct bilbyfs_info *bi) 1103{ 1104 int empty; 1105 int err; 1106 1107 empty = check_flash_empty(bi); 1108 if (empty < 0) { 1109 err = empty; 1110 } else if (empty) { 1111 return -ENODATA; 1112 } else { 1113 err = mount_read_super(bi); 1114 if (!err) { 1115 err = mount_check_super(bi); 1116 if (!err) { 1117 bi->is_mounting = true; 1118 bi->addrs = kmalloc(sizeof(*(bi->addrs)) * BILBYFS_MAX_OBJ_PER_TRANS); 1119 if (!bi->addrs) 1120 return -ENOMEM; 1121 err = allocpool_alloc(&bi->node_pool, 10000, NODE_SIZE); 1122 if (err) { 1123 kfree(bi->addrs); 1124 return err; 1125 } 1126 err = mount_scan(bi); 1127 allocpool_empty(&bi->node_pool); 1128 kfree(bi->addrs); 1129 bi->is_mounting = false; 1130 if (!err) 1131 return 0; 1132 } 1133 } else if (err == -ENOENT) { 1134 bilbyfs_err("Not a BilbyFs file system!\n"); 1135 } 1136 } 1137 ostore_unmount(bi); 1138 return err; 1139} 1140 1141void ostore_unmount(struct bilbyfs_info *bi) 1142{ 1143 int err; 1144 1145 /* We write a new super object only if we have written objects to the 1146 * media since the last update. (i.e. the last written object is not 1147 * the super block). 1148 */ 1149 if (bi->super.sqnum + 1 < bi->next_sqnum) { 1150 err = ostore_sync(bi, true); 1151 if (err) { 1152 bilbyfs_err("Could not synchronize FS when unmounting.\n"); 1153 } 1154 err = ostore_write_super(bi); 1155 if (err) 1156 bilbyfs_err("Could not write the super object %d\n", err); 1157 else 1158 bilbyfs_debug("ostore_unmount(): super block written\n"); 1159 } 1160} 1161 1162