Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef46ed88 authored by David Howells's avatar David Howells
Browse files

FS-Cache: Make cookie relinquishment wait for outstanding reads



Make fscache_relinquish_cookie() log a warning and wait if there are any
outstanding reads left on the cookie it was given.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 37491a13
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -442,22 +442,32 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)

	event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;

try_again:
	spin_lock(&cookie->lock);

	/* break links with all the active objects */
	while (!hlist_empty(&cookie->backing_objects)) {
		int n_reads;
		object = hlist_entry(cookie->backing_objects.first,
				     struct fscache_object,
				     cookie_link);

		_debug("RELEASE OBJ%x", object->debug_id);

		if (atomic_read(&object->n_reads)) {
		set_bit(FSCACHE_COOKIE_WAITING_ON_READS, &cookie->flags);
		n_reads = atomic_read(&object->n_reads);
		if (n_reads) {
			int n_ops = object->n_ops;
			int n_in_progress = object->n_in_progress;
			spin_unlock(&cookie->lock);
			printk(KERN_ERR "FS-Cache:"
			       " Cookie '%s' still has %d outstanding reads\n",
			       cookie->def->name, atomic_read(&object->n_reads));
			BUG();
			       " Cookie '%s' still has %d outstanding reads (%d,%d)\n",
			       cookie->def->name,
			       n_reads, n_ops, n_in_progress);
			wait_on_bit(&cookie->flags, FSCACHE_COOKIE_WAITING_ON_READS,
				    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
			printk("Wait finished\n");
			goto try_again;
		}

		/* detach each cache object from the object cookie */
+8 −2
Original line number Diff line number Diff line
@@ -340,8 +340,14 @@ void fscache_put_operation(struct fscache_operation *op)

	object = op->object;

	if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags))
		atomic_dec(&object->n_reads);
	if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) {
		if (atomic_dec_and_test(&object->n_reads)) {
			clear_bit(FSCACHE_COOKIE_WAITING_ON_READS,
				  &object->cookie->flags);
			wake_up_bit(&object->cookie->flags,
				    FSCACHE_COOKIE_WAITING_ON_READS);
		}
	}

	/* now... we may get called with the object spinlock held, so we
	 * complete the cleanup here only if we can immediately acquire the
+1 −0
Original line number Diff line number Diff line
@@ -301,6 +301,7 @@ struct fscache_cookie {
#define FSCACHE_COOKIE_PENDING_FILL	3	/* T if pending initial fill on object */
#define FSCACHE_COOKIE_FILLING		4	/* T if filling object incrementally */
#define FSCACHE_COOKIE_UNAVAILABLE	5	/* T if cookie is unavailable (error, etc) */
#define FSCACHE_COOKIE_WAITING_ON_READS	6	/* T if cookie is waiting on reads */
};

extern struct fscache_cookie fscache_fsdef_index;