1
2
3
4
5
6
7
8#define FSCACHE_DEBUG_LEVEL PAGE
9#include <linux/module.h>
10#define FSCACHE_USE_NEW_IO_API
11#include <linux/fscache-cache.h>
12#include <linux/slab.h>
13#include <linux/netfs.h>
14#include "internal.h"
15
16
17
18
19
20
21
22
23
24
25
26
27int __fscache_begin_read_operation(struct netfs_read_request *rreq,
28 struct fscache_cookie *cookie)
29{
30 struct fscache_retrieval *op;
31 struct fscache_object *object;
32 bool wake_cookie = false;
33 int ret;
34
35 _enter("rr=%08x", rreq->debug_id);
36
37 fscache_stat(&fscache_n_retrievals);
38
39 if (hlist_empty(&cookie->backing_objects))
40 goto nobufs;
41
42 if (test_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags)) {
43 _leave(" = -ENOBUFS [invalidating]");
44 return -ENOBUFS;
45 }
46
47 ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
48
49 if (fscache_wait_for_deferred_lookup(cookie) < 0)
50 return -ERESTARTSYS;
51
52 op = fscache_alloc_retrieval(cookie, NULL, NULL, NULL);
53 if (!op)
54 return -ENOMEM;
55 trace_fscache_page_op(cookie, NULL, &op->op, fscache_page_op_retr_multi);
56
57 spin_lock(&cookie->lock);
58
59 if (!fscache_cookie_enabled(cookie) ||
60 hlist_empty(&cookie->backing_objects))
61 goto nobufs_unlock;
62 object = hlist_entry(cookie->backing_objects.first,
63 struct fscache_object, cookie_link);
64
65 __fscache_use_cookie(cookie);
66 atomic_inc(&object->n_reads);
67 __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
68
69 if (fscache_submit_op(object, &op->op) < 0)
70 goto nobufs_unlock_dec;
71 spin_unlock(&cookie->lock);
72
73 fscache_stat(&fscache_n_retrieval_ops);
74
75
76
77 ret = fscache_wait_for_operation_activation(
78 object, &op->op,
79 __fscache_stat(&fscache_n_retrieval_op_waits),
80 __fscache_stat(&fscache_n_retrievals_object_dead));
81 if (ret < 0)
82 goto error;
83
84
85 ret = object->cache->ops->begin_read_operation(rreq, op);
86
87error:
88 if (ret == -ENOMEM)
89 fscache_stat(&fscache_n_retrievals_nomem);
90 else if (ret == -ERESTARTSYS)
91 fscache_stat(&fscache_n_retrievals_intr);
92 else if (ret == -ENODATA)
93 fscache_stat(&fscache_n_retrievals_nodata);
94 else if (ret < 0)
95 fscache_stat(&fscache_n_retrievals_nobufs);
96 else
97 fscache_stat(&fscache_n_retrievals_ok);
98
99 fscache_put_retrieval(op);
100 _leave(" = %d", ret);
101 return ret;
102
103nobufs_unlock_dec:
104 atomic_dec(&object->n_reads);
105 wake_cookie = __fscache_unuse_cookie(cookie);
106nobufs_unlock:
107 spin_unlock(&cookie->lock);
108 fscache_put_retrieval(op);
109 if (wake_cookie)
110 __fscache_wake_unused_cookie(cookie);
111nobufs:
112 fscache_stat(&fscache_n_retrievals_nobufs);
113 _leave(" = -ENOBUFS");
114 return -ENOBUFS;
115}
116EXPORT_SYMBOL(__fscache_begin_read_operation);
117