at v3.8 28 kB view raw
1/* FS-Cache object state machine handler 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * See Documentation/filesystems/caching/object.txt for a description of the 12 * object state machine and the in-kernel representations. 13 */ 14 15#define FSCACHE_DEBUG_LEVEL COOKIE 16#include <linux/module.h> 17#include <linux/slab.h> 18#include "internal.h" 19 20const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = { 21 [FSCACHE_OBJECT_INIT] = "OBJECT_INIT", 22 [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP", 23 [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", 24 [FSCACHE_OBJECT_AVAILABLE] = "OBJECT_AVAILABLE", 25 [FSCACHE_OBJECT_ACTIVE] = "OBJECT_ACTIVE", 26 [FSCACHE_OBJECT_INVALIDATING] = "OBJECT_INVALIDATING", 27 [FSCACHE_OBJECT_UPDATING] = "OBJECT_UPDATING", 28 [FSCACHE_OBJECT_DYING] = "OBJECT_DYING", 29 [FSCACHE_OBJECT_LC_DYING] = "OBJECT_LC_DYING", 30 [FSCACHE_OBJECT_ABORT_INIT] = "OBJECT_ABORT_INIT", 31 [FSCACHE_OBJECT_RELEASING] = "OBJECT_RELEASING", 32 [FSCACHE_OBJECT_RECYCLING] = "OBJECT_RECYCLING", 33 [FSCACHE_OBJECT_WITHDRAWING] = "OBJECT_WITHDRAWING", 34 [FSCACHE_OBJECT_DEAD] = "OBJECT_DEAD", 35}; 36EXPORT_SYMBOL(fscache_object_states); 37 38const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = { 39 [FSCACHE_OBJECT_INIT] = "INIT", 40 [FSCACHE_OBJECT_LOOKING_UP] = "LOOK", 41 [FSCACHE_OBJECT_CREATING] = "CRTN", 42 [FSCACHE_OBJECT_AVAILABLE] = "AVBL", 43 [FSCACHE_OBJECT_ACTIVE] = "ACTV", 44 [FSCACHE_OBJECT_INVALIDATING] = "INVL", 45 [FSCACHE_OBJECT_UPDATING] = "UPDT", 46 [FSCACHE_OBJECT_DYING] = "DYNG", 47 [FSCACHE_OBJECT_LC_DYING] = "LCDY", 48 [FSCACHE_OBJECT_ABORT_INIT] = "ABTI", 49 [FSCACHE_OBJECT_RELEASING] = "RELS", 50 [FSCACHE_OBJECT_RECYCLING] = "RCYC", 51 [FSCACHE_OBJECT_WITHDRAWING] = "WTHD", 52 [FSCACHE_OBJECT_DEAD] = "DEAD", 53}; 54 55static int fscache_get_object(struct fscache_object *); 56static void fscache_put_object(struct fscache_object *); 57static void fscache_initialise_object(struct fscache_object *); 58static void fscache_lookup_object(struct fscache_object *); 59static void fscache_object_available(struct fscache_object *); 60static void fscache_invalidate_object(struct fscache_object *); 61static void fscache_release_object(struct fscache_object *); 62static void fscache_withdraw_object(struct fscache_object *); 63static void fscache_enqueue_dependents(struct fscache_object *); 64static void fscache_dequeue_object(struct fscache_object *); 65 66/* 67 * we need to notify the parent when an op completes that we had outstanding 68 * upon it 69 */ 70static inline void fscache_done_parent_op(struct fscache_object *object) 71{ 72 struct fscache_object *parent = object->parent; 73 74 _enter("OBJ%x {OBJ%x,%x}", 75 object->debug_id, parent->debug_id, parent->n_ops); 76 77 spin_lock_nested(&parent->lock, 1); 78 parent->n_ops--; 79 parent->n_obj_ops--; 80 if (parent->n_ops == 0) 81 fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED); 82 spin_unlock(&parent->lock); 83} 84 85/* 86 * Notify netfs of invalidation completion. 87 */ 88static inline void fscache_invalidation_complete(struct fscache_cookie *cookie) 89{ 90 if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags)) 91 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING); 92} 93 94/* 95 * process events that have been sent to an object's state machine 96 * - initiates parent lookup 97 * - does object lookup 98 * - does object creation 99 * - does object recycling and retirement 100 * - does object withdrawal 101 */ 102static void fscache_object_state_machine(struct fscache_object *object) 103{ 104 enum fscache_object_state new_state; 105 struct fscache_cookie *cookie; 106 int event; 107 108 ASSERT(object != NULL); 109 110 _enter("{OBJ%x,%s,%lx}", 111 object->debug_id, fscache_object_states[object->state], 112 object->events); 113 114 switch (object->state) { 115 /* wait for the parent object to become ready */ 116 case FSCACHE_OBJECT_INIT: 117 object->event_mask = 118 FSCACHE_OBJECT_EVENTS_MASK & 119 ~(1 << FSCACHE_OBJECT_EV_CLEARED); 120 fscache_initialise_object(object); 121 goto done; 122 123 /* look up the object metadata on disk */ 124 case FSCACHE_OBJECT_LOOKING_UP: 125 fscache_lookup_object(object); 126 goto lookup_transit; 127 128 /* create the object metadata on disk */ 129 case FSCACHE_OBJECT_CREATING: 130 fscache_lookup_object(object); 131 goto lookup_transit; 132 133 /* handle an object becoming available; start pending 134 * operations and queue dependent operations for processing */ 135 case FSCACHE_OBJECT_AVAILABLE: 136 fscache_object_available(object); 137 goto active_transit; 138 139 /* normal running state */ 140 case FSCACHE_OBJECT_ACTIVE: 141 goto active_transit; 142 143 /* Invalidate an object on disk */ 144 case FSCACHE_OBJECT_INVALIDATING: 145 clear_bit(FSCACHE_OBJECT_EV_INVALIDATE, &object->events); 146 fscache_stat(&fscache_n_invalidates_run); 147 fscache_stat(&fscache_n_cop_invalidate_object); 148 fscache_invalidate_object(object); 149 fscache_stat_d(&fscache_n_cop_invalidate_object); 150 fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE); 151 goto active_transit; 152 153 /* update the object metadata on disk */ 154 case FSCACHE_OBJECT_UPDATING: 155 clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events); 156 fscache_stat(&fscache_n_updates_run); 157 fscache_stat(&fscache_n_cop_update_object); 158 object->cache->ops->update_object(object); 159 fscache_stat_d(&fscache_n_cop_update_object); 160 goto active_transit; 161 162 /* handle an object dying during lookup or creation */ 163 case FSCACHE_OBJECT_LC_DYING: 164 object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE); 165 fscache_stat(&fscache_n_cop_lookup_complete); 166 object->cache->ops->lookup_complete(object); 167 fscache_stat_d(&fscache_n_cop_lookup_complete); 168 169 spin_lock(&object->lock); 170 object->state = FSCACHE_OBJECT_DYING; 171 cookie = object->cookie; 172 if (cookie) { 173 if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, 174 &cookie->flags)) 175 wake_up_bit(&cookie->flags, 176 FSCACHE_COOKIE_LOOKING_UP); 177 if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, 178 &cookie->flags)) 179 wake_up_bit(&cookie->flags, 180 FSCACHE_COOKIE_CREATING); 181 } 182 spin_unlock(&object->lock); 183 184 fscache_done_parent_op(object); 185 186 /* wait for completion of all active operations on this object 187 * and the death of all child objects of this object */ 188 case FSCACHE_OBJECT_DYING: 189 dying: 190 clear_bit(FSCACHE_OBJECT_EV_CLEARED, &object->events); 191 spin_lock(&object->lock); 192 _debug("dying OBJ%x {%d,%d}", 193 object->debug_id, object->n_ops, object->n_children); 194 if (object->n_ops == 0 && object->n_children == 0) { 195 object->event_mask &= 196 ~(1 << FSCACHE_OBJECT_EV_CLEARED); 197 object->event_mask |= 198 (1 << FSCACHE_OBJECT_EV_WITHDRAW) | 199 (1 << FSCACHE_OBJECT_EV_RETIRE) | 200 (1 << FSCACHE_OBJECT_EV_RELEASE) | 201 (1 << FSCACHE_OBJECT_EV_ERROR); 202 } else { 203 object->event_mask &= 204 ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) | 205 (1 << FSCACHE_OBJECT_EV_RETIRE) | 206 (1 << FSCACHE_OBJECT_EV_RELEASE) | 207 (1 << FSCACHE_OBJECT_EV_ERROR)); 208 object->event_mask |= 209 1 << FSCACHE_OBJECT_EV_CLEARED; 210 } 211 spin_unlock(&object->lock); 212 fscache_enqueue_dependents(object); 213 fscache_start_operations(object); 214 goto terminal_transit; 215 216 /* handle an abort during initialisation */ 217 case FSCACHE_OBJECT_ABORT_INIT: 218 _debug("handle abort init %lx", object->events); 219 object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE); 220 221 spin_lock(&object->lock); 222 fscache_dequeue_object(object); 223 224 object->state = FSCACHE_OBJECT_DYING; 225 if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, 226 &object->cookie->flags)) 227 wake_up_bit(&object->cookie->flags, 228 FSCACHE_COOKIE_CREATING); 229 spin_unlock(&object->lock); 230 goto dying; 231 232 /* handle the netfs releasing an object and possibly marking it 233 * obsolete too */ 234 case FSCACHE_OBJECT_RELEASING: 235 case FSCACHE_OBJECT_RECYCLING: 236 object->event_mask &= 237 ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) | 238 (1 << FSCACHE_OBJECT_EV_RETIRE) | 239 (1 << FSCACHE_OBJECT_EV_RELEASE) | 240 (1 << FSCACHE_OBJECT_EV_ERROR)); 241 fscache_release_object(object); 242 spin_lock(&object->lock); 243 object->state = FSCACHE_OBJECT_DEAD; 244 spin_unlock(&object->lock); 245 fscache_stat(&fscache_n_object_dead); 246 goto terminal_transit; 247 248 /* handle the parent cache of this object being withdrawn from 249 * active service */ 250 case FSCACHE_OBJECT_WITHDRAWING: 251 object->event_mask &= 252 ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) | 253 (1 << FSCACHE_OBJECT_EV_RETIRE) | 254 (1 << FSCACHE_OBJECT_EV_RELEASE) | 255 (1 << FSCACHE_OBJECT_EV_ERROR)); 256 fscache_withdraw_object(object); 257 spin_lock(&object->lock); 258 object->state = FSCACHE_OBJECT_DEAD; 259 spin_unlock(&object->lock); 260 fscache_stat(&fscache_n_object_dead); 261 goto terminal_transit; 262 263 /* complain about the object being woken up once it is 264 * deceased */ 265 case FSCACHE_OBJECT_DEAD: 266 printk(KERN_ERR "FS-Cache:" 267 " Unexpected event in dead state %lx\n", 268 object->events & object->event_mask); 269 BUG(); 270 271 default: 272 printk(KERN_ERR "FS-Cache: Unknown object state %u\n", 273 object->state); 274 BUG(); 275 } 276 277 /* determine the transition from a lookup state */ 278lookup_transit: 279 event = fls(object->events & object->event_mask) - 1; 280 switch (event) { 281 case FSCACHE_OBJECT_EV_WITHDRAW: 282 case FSCACHE_OBJECT_EV_RETIRE: 283 case FSCACHE_OBJECT_EV_RELEASE: 284 case FSCACHE_OBJECT_EV_ERROR: 285 new_state = FSCACHE_OBJECT_LC_DYING; 286 goto change_state; 287 case FSCACHE_OBJECT_EV_INVALIDATE: 288 new_state = FSCACHE_OBJECT_INVALIDATING; 289 goto change_state; 290 case FSCACHE_OBJECT_EV_REQUEUE: 291 goto done; 292 case -1: 293 goto done; /* sleep until event */ 294 default: 295 goto unsupported_event; 296 } 297 298 /* determine the transition from an active state */ 299active_transit: 300 event = fls(object->events & object->event_mask) - 1; 301 switch (event) { 302 case FSCACHE_OBJECT_EV_WITHDRAW: 303 case FSCACHE_OBJECT_EV_RETIRE: 304 case FSCACHE_OBJECT_EV_RELEASE: 305 case FSCACHE_OBJECT_EV_ERROR: 306 new_state = FSCACHE_OBJECT_DYING; 307 goto change_state; 308 case FSCACHE_OBJECT_EV_INVALIDATE: 309 new_state = FSCACHE_OBJECT_INVALIDATING; 310 goto change_state; 311 case FSCACHE_OBJECT_EV_UPDATE: 312 new_state = FSCACHE_OBJECT_UPDATING; 313 goto change_state; 314 case -1: 315 new_state = FSCACHE_OBJECT_ACTIVE; 316 goto change_state; /* sleep until event */ 317 default: 318 goto unsupported_event; 319 } 320 321 /* determine the transition from a terminal state */ 322terminal_transit: 323 event = fls(object->events & object->event_mask) - 1; 324 switch (event) { 325 case FSCACHE_OBJECT_EV_WITHDRAW: 326 new_state = FSCACHE_OBJECT_WITHDRAWING; 327 goto change_state; 328 case FSCACHE_OBJECT_EV_RETIRE: 329 new_state = FSCACHE_OBJECT_RECYCLING; 330 goto change_state; 331 case FSCACHE_OBJECT_EV_RELEASE: 332 new_state = FSCACHE_OBJECT_RELEASING; 333 goto change_state; 334 case FSCACHE_OBJECT_EV_ERROR: 335 new_state = FSCACHE_OBJECT_WITHDRAWING; 336 goto change_state; 337 case FSCACHE_OBJECT_EV_CLEARED: 338 new_state = FSCACHE_OBJECT_DYING; 339 goto change_state; 340 case -1: 341 goto done; /* sleep until event */ 342 default: 343 goto unsupported_event; 344 } 345 346change_state: 347 spin_lock(&object->lock); 348 object->state = new_state; 349 spin_unlock(&object->lock); 350 351done: 352 _leave(" [->%s]", fscache_object_states[object->state]); 353 return; 354 355unsupported_event: 356 printk(KERN_ERR "FS-Cache:" 357 " Unsupported event %d [%lx/%lx] in state %s\n", 358 event, object->events, object->event_mask, 359 fscache_object_states[object->state]); 360 BUG(); 361} 362 363/* 364 * execute an object 365 */ 366void fscache_object_work_func(struct work_struct *work) 367{ 368 struct fscache_object *object = 369 container_of(work, struct fscache_object, work); 370 unsigned long start; 371 372 _enter("{OBJ%x}", object->debug_id); 373 374 start = jiffies; 375 fscache_object_state_machine(object); 376 fscache_hist(fscache_objs_histogram, start); 377 if (object->events & object->event_mask) 378 fscache_enqueue_object(object); 379 clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); 380 fscache_put_object(object); 381} 382EXPORT_SYMBOL(fscache_object_work_func); 383 384/* 385 * initialise an object 386 * - check the specified object's parent to see if we can make use of it 387 * immediately to do a creation 388 * - we may need to start the process of creating a parent and we need to wait 389 * for the parent's lookup and creation to complete if it's not there yet 390 * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the 391 * leaf-most cookies of the object and all its children 392 */ 393static void fscache_initialise_object(struct fscache_object *object) 394{ 395 struct fscache_object *parent; 396 397 _enter(""); 398 ASSERT(object->cookie != NULL); 399 ASSERT(object->cookie->parent != NULL); 400 401 if (object->events & ((1 << FSCACHE_OBJECT_EV_ERROR) | 402 (1 << FSCACHE_OBJECT_EV_RELEASE) | 403 (1 << FSCACHE_OBJECT_EV_RETIRE) | 404 (1 << FSCACHE_OBJECT_EV_WITHDRAW))) { 405 _debug("abort init %lx", object->events); 406 spin_lock(&object->lock); 407 object->state = FSCACHE_OBJECT_ABORT_INIT; 408 spin_unlock(&object->lock); 409 return; 410 } 411 412 spin_lock(&object->cookie->lock); 413 spin_lock_nested(&object->cookie->parent->lock, 1); 414 415 parent = object->parent; 416 if (!parent) { 417 _debug("no parent"); 418 set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events); 419 } else { 420 spin_lock(&object->lock); 421 spin_lock_nested(&parent->lock, 1); 422 _debug("parent %s", fscache_object_states[parent->state]); 423 424 if (parent->state >= FSCACHE_OBJECT_DYING) { 425 _debug("bad parent"); 426 set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events); 427 } else if (parent->state < FSCACHE_OBJECT_AVAILABLE) { 428 _debug("wait"); 429 430 /* we may get woken up in this state by child objects 431 * binding on to us, so we need to make sure we don't 432 * add ourself to the list multiple times */ 433 if (list_empty(&object->dep_link)) { 434 fscache_stat(&fscache_n_cop_grab_object); 435 object->cache->ops->grab_object(object); 436 fscache_stat_d(&fscache_n_cop_grab_object); 437 list_add(&object->dep_link, 438 &parent->dependents); 439 440 /* fscache_acquire_non_index_cookie() uses this 441 * to wake the chain up */ 442 if (parent->state == FSCACHE_OBJECT_INIT) 443 fscache_enqueue_object(parent); 444 } 445 } else { 446 _debug("go"); 447 parent->n_ops++; 448 parent->n_obj_ops++; 449 object->lookup_jif = jiffies; 450 object->state = FSCACHE_OBJECT_LOOKING_UP; 451 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); 452 } 453 454 spin_unlock(&parent->lock); 455 spin_unlock(&object->lock); 456 } 457 458 spin_unlock(&object->cookie->parent->lock); 459 spin_unlock(&object->cookie->lock); 460 _leave(""); 461} 462 463/* 464 * look an object up in the cache from which it was allocated 465 * - we hold an "access lock" on the parent object, so the parent object cannot 466 * be withdrawn by either party till we've finished 467 * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the 468 * leaf-most cookies of the object and all its children 469 */ 470static void fscache_lookup_object(struct fscache_object *object) 471{ 472 struct fscache_cookie *cookie = object->cookie; 473 struct fscache_object *parent; 474 int ret; 475 476 _enter(""); 477 478 parent = object->parent; 479 ASSERT(parent != NULL); 480 ASSERTCMP(parent->n_ops, >, 0); 481 ASSERTCMP(parent->n_obj_ops, >, 0); 482 483 /* make sure the parent is still available */ 484 ASSERTCMP(parent->state, >=, FSCACHE_OBJECT_AVAILABLE); 485 486 if (parent->state >= FSCACHE_OBJECT_DYING || 487 test_bit(FSCACHE_IOERROR, &object->cache->flags)) { 488 _debug("unavailable"); 489 set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events); 490 _leave(""); 491 return; 492 } 493 494 _debug("LOOKUP \"%s/%s\" in \"%s\"", 495 parent->cookie->def->name, cookie->def->name, 496 object->cache->tag->name); 497 498 fscache_stat(&fscache_n_object_lookups); 499 fscache_stat(&fscache_n_cop_lookup_object); 500 ret = object->cache->ops->lookup_object(object); 501 fscache_stat_d(&fscache_n_cop_lookup_object); 502 503 if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events)) 504 set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); 505 506 if (ret == -ETIMEDOUT) { 507 /* probably stuck behind another object, so move this one to 508 * the back of the queue */ 509 fscache_stat(&fscache_n_object_lookups_timed_out); 510 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); 511 } 512 513 _leave(""); 514} 515 516/** 517 * fscache_object_lookup_negative - Note negative cookie lookup 518 * @object: Object pointing to cookie to mark 519 * 520 * Note negative lookup, permitting those waiting to read data from an already 521 * existing backing object to continue as there's no data for them to read. 522 */ 523void fscache_object_lookup_negative(struct fscache_object *object) 524{ 525 struct fscache_cookie *cookie = object->cookie; 526 527 _enter("{OBJ%x,%s}", 528 object->debug_id, fscache_object_states[object->state]); 529 530 spin_lock(&object->lock); 531 if (object->state == FSCACHE_OBJECT_LOOKING_UP) { 532 fscache_stat(&fscache_n_object_lookups_negative); 533 534 /* transit here to allow write requests to begin stacking up 535 * and read requests to begin returning ENODATA */ 536 object->state = FSCACHE_OBJECT_CREATING; 537 spin_unlock(&object->lock); 538 539 set_bit(FSCACHE_COOKIE_PENDING_FILL, &cookie->flags); 540 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 541 542 _debug("wake up lookup %p", &cookie->flags); 543 smp_mb__before_clear_bit(); 544 clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags); 545 smp_mb__after_clear_bit(); 546 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP); 547 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); 548 } else { 549 ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING); 550 spin_unlock(&object->lock); 551 } 552 553 _leave(""); 554} 555EXPORT_SYMBOL(fscache_object_lookup_negative); 556 557/** 558 * fscache_obtained_object - Note successful object lookup or creation 559 * @object: Object pointing to cookie to mark 560 * 561 * Note successful lookup and/or creation, permitting those waiting to write 562 * data to a backing object to continue. 563 * 564 * Note that after calling this, an object's cookie may be relinquished by the 565 * netfs, and so must be accessed with object lock held. 566 */ 567void fscache_obtained_object(struct fscache_object *object) 568{ 569 struct fscache_cookie *cookie = object->cookie; 570 571 _enter("{OBJ%x,%s}", 572 object->debug_id, fscache_object_states[object->state]); 573 574 /* if we were still looking up, then we must have a positive lookup 575 * result, in which case there may be data available */ 576 spin_lock(&object->lock); 577 if (object->state == FSCACHE_OBJECT_LOOKING_UP) { 578 fscache_stat(&fscache_n_object_lookups_positive); 579 580 clear_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 581 582 object->state = FSCACHE_OBJECT_AVAILABLE; 583 spin_unlock(&object->lock); 584 585 smp_mb__before_clear_bit(); 586 clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags); 587 smp_mb__after_clear_bit(); 588 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP); 589 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); 590 } else { 591 ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING); 592 fscache_stat(&fscache_n_object_created); 593 594 object->state = FSCACHE_OBJECT_AVAILABLE; 595 spin_unlock(&object->lock); 596 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); 597 smp_wmb(); 598 } 599 600 if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &cookie->flags)) 601 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_CREATING); 602 603 _leave(""); 604} 605EXPORT_SYMBOL(fscache_obtained_object); 606 607/* 608 * handle an object that has just become available 609 */ 610static void fscache_object_available(struct fscache_object *object) 611{ 612 _enter("{OBJ%x}", object->debug_id); 613 614 spin_lock(&object->lock); 615 616 if (object->cookie && 617 test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags)) 618 wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING); 619 620 fscache_done_parent_op(object); 621 if (object->n_in_progress == 0) { 622 if (object->n_ops > 0) { 623 ASSERTCMP(object->n_ops, >=, object->n_obj_ops); 624 fscache_start_operations(object); 625 } else { 626 ASSERT(list_empty(&object->pending_ops)); 627 } 628 } 629 spin_unlock(&object->lock); 630 631 fscache_stat(&fscache_n_cop_lookup_complete); 632 object->cache->ops->lookup_complete(object); 633 fscache_stat_d(&fscache_n_cop_lookup_complete); 634 fscache_enqueue_dependents(object); 635 636 fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif); 637 fscache_stat(&fscache_n_object_avail); 638 639 _leave(""); 640} 641 642/* 643 * drop an object's attachments 644 */ 645static void fscache_drop_object(struct fscache_object *object) 646{ 647 struct fscache_object *parent = object->parent; 648 struct fscache_cache *cache = object->cache; 649 650 _enter("{OBJ%x,%d}", object->debug_id, object->n_children); 651 652 ASSERTCMP(object->cookie, ==, NULL); 653 ASSERT(hlist_unhashed(&object->cookie_link)); 654 655 spin_lock(&cache->object_list_lock); 656 list_del_init(&object->cache_link); 657 spin_unlock(&cache->object_list_lock); 658 659 fscache_stat(&fscache_n_cop_drop_object); 660 cache->ops->drop_object(object); 661 fscache_stat_d(&fscache_n_cop_drop_object); 662 663 if (parent) { 664 _debug("release parent OBJ%x {%d}", 665 parent->debug_id, parent->n_children); 666 667 spin_lock(&parent->lock); 668 parent->n_children--; 669 if (parent->n_children == 0) 670 fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED); 671 spin_unlock(&parent->lock); 672 object->parent = NULL; 673 } 674 675 /* this just shifts the object release to the work processor */ 676 fscache_put_object(object); 677 678 _leave(""); 679} 680 681/* 682 * release or recycle an object that the netfs has discarded 683 */ 684static void fscache_release_object(struct fscache_object *object) 685{ 686 _enter(""); 687 688 fscache_drop_object(object); 689} 690 691/* 692 * withdraw an object from active service 693 */ 694static void fscache_withdraw_object(struct fscache_object *object) 695{ 696 struct fscache_cookie *cookie; 697 bool detached; 698 699 _enter(""); 700 701 spin_lock(&object->lock); 702 cookie = object->cookie; 703 if (cookie) { 704 /* need to get the cookie lock before the object lock, starting 705 * from the object pointer */ 706 atomic_inc(&cookie->usage); 707 spin_unlock(&object->lock); 708 709 detached = false; 710 spin_lock(&cookie->lock); 711 spin_lock(&object->lock); 712 713 if (object->cookie == cookie) { 714 hlist_del_init(&object->cookie_link); 715 object->cookie = NULL; 716 fscache_invalidation_complete(cookie); 717 detached = true; 718 } 719 spin_unlock(&cookie->lock); 720 fscache_cookie_put(cookie); 721 if (detached) 722 fscache_cookie_put(cookie); 723 } 724 725 spin_unlock(&object->lock); 726 727 fscache_drop_object(object); 728} 729 730/* 731 * withdraw an object from active service at the behest of the cache 732 * - need break the links to a cached object cookie 733 * - called under two situations: 734 * (1) recycler decides to reclaim an in-use object 735 * (2) a cache is unmounted 736 * - have to take care as the cookie can be being relinquished by the netfs 737 * simultaneously 738 * - the object is pinned by the caller holding a refcount on it 739 */ 740void fscache_withdrawing_object(struct fscache_cache *cache, 741 struct fscache_object *object) 742{ 743 bool enqueue = false; 744 745 _enter(",OBJ%x", object->debug_id); 746 747 spin_lock(&object->lock); 748 if (object->state < FSCACHE_OBJECT_WITHDRAWING) { 749 object->state = FSCACHE_OBJECT_WITHDRAWING; 750 enqueue = true; 751 } 752 spin_unlock(&object->lock); 753 754 if (enqueue) 755 fscache_enqueue_object(object); 756 757 _leave(""); 758} 759 760/* 761 * get a ref on an object 762 */ 763static int fscache_get_object(struct fscache_object *object) 764{ 765 int ret; 766 767 fscache_stat(&fscache_n_cop_grab_object); 768 ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN; 769 fscache_stat_d(&fscache_n_cop_grab_object); 770 return ret; 771} 772 773/* 774 * discard a ref on a work item 775 */ 776static void fscache_put_object(struct fscache_object *object) 777{ 778 fscache_stat(&fscache_n_cop_put_object); 779 object->cache->ops->put_object(object); 780 fscache_stat_d(&fscache_n_cop_put_object); 781} 782 783/* 784 * enqueue an object for metadata-type processing 785 */ 786void fscache_enqueue_object(struct fscache_object *object) 787{ 788 _enter("{OBJ%x}", object->debug_id); 789 790 if (fscache_get_object(object) >= 0) { 791 wait_queue_head_t *cong_wq = 792 &get_cpu_var(fscache_object_cong_wait); 793 794 if (queue_work(fscache_object_wq, &object->work)) { 795 if (fscache_object_congested()) 796 wake_up(cong_wq); 797 } else 798 fscache_put_object(object); 799 800 put_cpu_var(fscache_object_cong_wait); 801 } 802} 803 804/** 805 * fscache_object_sleep_till_congested - Sleep until object wq is congested 806 * @timoutp: Scheduler sleep timeout 807 * 808 * Allow an object handler to sleep until the object workqueue is congested. 809 * 810 * The caller must set up a wake up event before calling this and must have set 811 * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own 812 * condition before calling this function as no test is made here. 813 * 814 * %true is returned if the object wq is congested, %false otherwise. 815 */ 816bool fscache_object_sleep_till_congested(signed long *timeoutp) 817{ 818 wait_queue_head_t *cong_wq = &__get_cpu_var(fscache_object_cong_wait); 819 DEFINE_WAIT(wait); 820 821 if (fscache_object_congested()) 822 return true; 823 824 add_wait_queue_exclusive(cong_wq, &wait); 825 if (!fscache_object_congested()) 826 *timeoutp = schedule_timeout(*timeoutp); 827 finish_wait(cong_wq, &wait); 828 829 return fscache_object_congested(); 830} 831EXPORT_SYMBOL_GPL(fscache_object_sleep_till_congested); 832 833/* 834 * enqueue the dependents of an object for metadata-type processing 835 * - the caller must hold the object's lock 836 * - this may cause an already locked object to wind up being processed again 837 */ 838static void fscache_enqueue_dependents(struct fscache_object *object) 839{ 840 struct fscache_object *dep; 841 842 _enter("{OBJ%x}", object->debug_id); 843 844 if (list_empty(&object->dependents)) 845 return; 846 847 spin_lock(&object->lock); 848 849 while (!list_empty(&object->dependents)) { 850 dep = list_entry(object->dependents.next, 851 struct fscache_object, dep_link); 852 list_del_init(&dep->dep_link); 853 854 855 /* sort onto appropriate lists */ 856 fscache_enqueue_object(dep); 857 fscache_put_object(dep); 858 859 if (!list_empty(&object->dependents)) 860 cond_resched_lock(&object->lock); 861 } 862 863 spin_unlock(&object->lock); 864} 865 866/* 867 * remove an object from whatever queue it's waiting on 868 * - the caller must hold object->lock 869 */ 870void fscache_dequeue_object(struct fscache_object *object) 871{ 872 _enter("{OBJ%x}", object->debug_id); 873 874 if (!list_empty(&object->dep_link)) { 875 spin_lock(&object->parent->lock); 876 list_del_init(&object->dep_link); 877 spin_unlock(&object->parent->lock); 878 } 879 880 _leave(""); 881} 882 883/** 884 * fscache_check_aux - Ask the netfs whether an object on disk is still valid 885 * @object: The object to ask about 886 * @data: The auxiliary data for the object 887 * @datalen: The size of the auxiliary data 888 * 889 * This function consults the netfs about the coherency state of an object 890 */ 891enum fscache_checkaux fscache_check_aux(struct fscache_object *object, 892 const void *data, uint16_t datalen) 893{ 894 enum fscache_checkaux result; 895 896 if (!object->cookie->def->check_aux) { 897 fscache_stat(&fscache_n_checkaux_none); 898 return FSCACHE_CHECKAUX_OKAY; 899 } 900 901 result = object->cookie->def->check_aux(object->cookie->netfs_data, 902 data, datalen); 903 switch (result) { 904 /* entry okay as is */ 905 case FSCACHE_CHECKAUX_OKAY: 906 fscache_stat(&fscache_n_checkaux_okay); 907 break; 908 909 /* entry requires update */ 910 case FSCACHE_CHECKAUX_NEEDS_UPDATE: 911 fscache_stat(&fscache_n_checkaux_update); 912 break; 913 914 /* entry requires deletion */ 915 case FSCACHE_CHECKAUX_OBSOLETE: 916 fscache_stat(&fscache_n_checkaux_obsolete); 917 break; 918 919 default: 920 BUG(); 921 } 922 923 return result; 924} 925EXPORT_SYMBOL(fscache_check_aux); 926 927/* 928 * Asynchronously invalidate an object. 929 */ 930static void fscache_invalidate_object(struct fscache_object *object) 931{ 932 struct fscache_operation *op; 933 struct fscache_cookie *cookie = object->cookie; 934 935 _enter("{OBJ%x}", object->debug_id); 936 937 /* Reject any new read/write ops and abort any that are pending. */ 938 fscache_invalidate_writes(cookie); 939 clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); 940 fscache_cancel_all_ops(object); 941 942 /* Now we have to wait for in-progress reads and writes */ 943 op = kzalloc(sizeof(*op), GFP_KERNEL); 944 if (!op) { 945 fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR); 946 _leave(" [ENOMEM]"); 947 return; 948 } 949 950 fscache_operation_init(op, object->cache->ops->invalidate_object, NULL); 951 op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE); 952 953 spin_lock(&cookie->lock); 954 if (fscache_submit_exclusive_op(object, op) < 0) 955 goto submit_op_failed; 956 spin_unlock(&cookie->lock); 957 fscache_put_operation(op); 958 959 /* Once we've completed the invalidation, we know there will be no data 960 * stored in the cache and thus we can reinstate the data-check-skip 961 * optimisation. 962 */ 963 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 964 965 /* We can allow read and write requests to come in once again. They'll 966 * queue up behind our exclusive invalidation operation. 967 */ 968 fscache_invalidation_complete(cookie); 969 _leave(""); 970 return; 971 972submit_op_failed: 973 spin_unlock(&cookie->lock); 974 kfree(op); 975 fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR); 976 _leave(" [EIO]"); 977}