1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#include "../../include/linux/libcfs/libcfs.h"
40#include "../include/obd_class.h"
41#include "../include/obd_support.h"
42#include "../include/obd.h"
43
44#include "../include/lustre_dlm.h"
45#include "../include/lustre_mdc.h"
46#include <linux/pagemap.h>
47#include <linux/file.h>
48
49#include "../include/cl_object.h"
50#include "../llite/llite_internal.h"
51
52static const struct cl_lock_descr whole_file = {
53 .cld_start = 0,
54 .cld_end = CL_PAGE_EOF,
55 .cld_mode = CLM_READ
56};
57
58
59
60
61
62
63
64blkcnt_t dirty_cnt(struct inode *inode)
65{
66 blkcnt_t cnt = 0;
67 struct vvp_object *vob = cl_inode2vvp(inode);
68 void *results[1];
69
70 if (inode->i_mapping)
71 cnt += radix_tree_gang_lookup_tag(&inode->i_mapping->page_tree,
72 results, 0, 1,
73 PAGECACHE_TAG_DIRTY);
74 if (cnt == 0 && atomic_read(&vob->vob_mmap_cnt) > 0)
75 cnt = 1;
76
77 return (cnt > 0) ? 1 : 0;
78}
79
80int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
81 struct inode *inode, struct cl_object *clob, int agl)
82{
83 const struct lu_fid *fid = lu_object_fid(&clob->co_lu);
84 struct cl_lock *lock = vvp_env_lock(env);
85 struct cl_lock_descr *descr = &lock->cll_descr;
86 int result = 0;
87
88 CDEBUG(D_DLMTRACE, "Glimpsing inode " DFID "\n", PFID(fid));
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 *descr = whole_file;
105 descr->cld_obj = clob;
106 descr->cld_mode = CLM_READ;
107 descr->cld_enq_flags = CEF_ASYNC | CEF_MUST;
108 if (agl)
109 descr->cld_enq_flags |= CEF_AGL;
110
111
112
113
114
115
116
117
118 result = cl_lock_request(env, io, lock);
119 if (result < 0)
120 return result;
121
122 if (!agl) {
123 ll_merge_attr(env, inode);
124 if (i_size_read(inode) > 0 && !inode->i_blocks) {
125
126
127
128
129
130
131 inode->i_blocks = dirty_cnt(inode);
132 }
133 }
134
135 cl_lock_release(env, lock);
136
137 return result;
138}
139
140static int cl_io_get(struct inode *inode, struct lu_env **envout,
141 struct cl_io **ioout, u16 *refcheck)
142{
143 struct lu_env *env;
144 struct cl_io *io;
145 struct ll_inode_info *lli = ll_i2info(inode);
146 struct cl_object *clob = lli->lli_clob;
147 int result;
148
149 if (S_ISREG(inode->i_mode)) {
150 env = cl_env_get(refcheck);
151 if (!IS_ERR(env)) {
152 io = vvp_env_thread_io(env);
153 io->ci_obj = clob;
154 *envout = env;
155 *ioout = io;
156 result = 1;
157 } else {
158 result = PTR_ERR(env);
159 }
160 } else {
161 result = 0;
162 }
163 return result;
164}
165
166int cl_glimpse_size0(struct inode *inode, int agl)
167{
168
169
170
171
172
173
174
175
176
177
178 struct lu_env *env = NULL;
179 struct cl_io *io = NULL;
180 int result;
181 u16 refcheck;
182
183 result = cl_io_get(inode, &env, &io, &refcheck);
184 if (result > 0) {
185again:
186 io->ci_verify_layout = 1;
187 result = cl_io_init(env, io, CIT_MISC, io->ci_obj);
188 if (result > 0)
189
190
191
192
193 result = io->ci_result;
194 else if (result == 0)
195 result = cl_glimpse_lock(env, io, inode, io->ci_obj,
196 agl);
197
198 OBD_FAIL_TIMEOUT(OBD_FAIL_GLIMPSE_DELAY, 2);
199 cl_io_fini(env, io);
200 if (unlikely(io->ci_need_restart))
201 goto again;
202 cl_env_put(env, &refcheck);
203 }
204 return result;
205}
206