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#define DEBUG_SUBSYSTEM S_LLITE
39
40#include "../../include/linux/libcfs/libcfs.h"
41# include <linux/fs.h>
42# include <linux/sched.h>
43# include <linux/mm.h>
44# include <linux/quotaops.h>
45# include <linux/highmem.h>
46# include <linux/pagemap.h>
47# include <linux/rbtree.h>
48
49#include "../include/obd.h"
50#include "../include/obd_support.h"
51#include "../include/lustre_fid.h"
52#include "../include/lustre_dlm.h"
53#include "../include/lustre_ver.h"
54#include "../include/lustre_mdc.h"
55#include "../include/cl_object.h"
56
57#include "../llite/llite_internal.h"
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74struct lu_env *cl_inode_fini_env;
75int cl_inode_fini_refcheck;
76
77
78
79
80
81static DEFINE_MUTEX(cl_inode_fini_guard);
82
83int cl_setattr_ost(struct inode *inode, const struct iattr *attr)
84{
85 struct lu_env *env;
86 struct cl_io *io;
87 int result;
88 int refcheck;
89
90 env = cl_env_get(&refcheck);
91 if (IS_ERR(env))
92 return PTR_ERR(env);
93
94 io = vvp_env_thread_io(env);
95 io->ci_obj = ll_i2info(inode)->lli_clob;
96
97 io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime);
98 io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime);
99 io->u.ci_setattr.sa_attr.lvb_ctime = LTIME_S(attr->ia_ctime);
100 io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size;
101 io->u.ci_setattr.sa_valid = attr->ia_valid;
102 io->u.ci_setattr.sa_parent_fid = ll_inode2fid(inode);
103
104again:
105 if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
106 struct vvp_io *vio = vvp_env_io(env);
107
108 if (attr->ia_valid & ATTR_FILE)
109
110
111
112 vio->vui_fd = LUSTRE_FPRIVATE(attr->ia_file);
113
114 result = cl_io_loop(env, io);
115 } else {
116 result = io->ci_result;
117 }
118 cl_io_fini(env, io);
119 if (unlikely(io->ci_need_restart))
120 goto again;
121
122
123
124
125 if (result == -ENODATA && io->ci_restore_needed &&
126 io->ci_result != -ENODATA)
127 result = 0;
128 cl_env_put(env, &refcheck);
129 return result;
130}
131
132
133
134
135
136
137
138
139
140
141int cl_file_inode_init(struct inode *inode, struct lustre_md *md)
142{
143 struct lu_env *env;
144 struct ll_inode_info *lli;
145 struct cl_object *clob;
146 struct lu_site *site;
147 struct lu_fid *fid;
148 struct cl_object_conf conf = {
149 .coc_inode = inode,
150 .u = {
151 .coc_md = md
152 }
153 };
154 int result = 0;
155 int refcheck;
156
157 LASSERT(md->body->mbo_valid & OBD_MD_FLID);
158 LASSERT(S_ISREG(inode->i_mode));
159
160 env = cl_env_get(&refcheck);
161 if (IS_ERR(env))
162 return PTR_ERR(env);
163
164 site = ll_i2sbi(inode)->ll_site;
165 lli = ll_i2info(inode);
166 fid = &lli->lli_fid;
167 LASSERT(fid_is_sane(fid));
168
169 if (!lli->lli_clob) {
170
171
172
173
174
175 LASSERT(inode->i_state & I_NEW);
176 conf.coc_lu.loc_flags = LOC_F_NEW;
177 clob = cl_object_find(env, lu2cl_dev(site->ls_top_dev),
178 fid, &conf);
179 if (!IS_ERR(clob)) {
180
181
182
183
184 lli->lli_clob = clob;
185 lli->lli_has_smd = lsm_has_objects(md->lsm);
186 lu_object_ref_add(&clob->co_lu, "inode", inode);
187 } else {
188 result = PTR_ERR(clob);
189 }
190 } else {
191 result = cl_conf_set(env, lli->lli_clob, &conf);
192 }
193
194 cl_env_put(env, &refcheck);
195
196 if (result != 0)
197 CERROR("Failure to initialize cl object " DFID ": %d\n",
198 PFID(fid), result);
199 return result;
200}
201
202
203
204
205
206
207
208
209
210
211static void cl_object_put_last(struct lu_env *env, struct cl_object *obj)
212{
213 struct lu_object_header *header = obj->co_lu.lo_header;
214 wait_queue_t waiter;
215
216 if (unlikely(atomic_read(&header->loh_ref) != 1)) {
217 struct lu_site *site = obj->co_lu.lo_dev->ld_site;
218 struct lu_site_bkt_data *bkt;
219
220 bkt = lu_site_bkt_from_fid(site, &header->loh_fid);
221
222 init_waitqueue_entry(&waiter, current);
223 add_wait_queue(&bkt->lsb_marche_funebre, &waiter);
224
225 while (1) {
226 set_current_state(TASK_UNINTERRUPTIBLE);
227 if (atomic_read(&header->loh_ref) == 1)
228 break;
229 schedule();
230 }
231
232 set_current_state(TASK_RUNNING);
233 remove_wait_queue(&bkt->lsb_marche_funebre, &waiter);
234 }
235
236 cl_object_put(env, obj);
237}
238
239void cl_inode_fini(struct inode *inode)
240{
241 struct lu_env *env;
242 struct ll_inode_info *lli = ll_i2info(inode);
243 struct cl_object *clob = lli->lli_clob;
244 int refcheck;
245 int emergency;
246
247 if (clob) {
248 void *cookie;
249
250 cookie = cl_env_reenter();
251 env = cl_env_get(&refcheck);
252 emergency = IS_ERR(env);
253 if (emergency) {
254 mutex_lock(&cl_inode_fini_guard);
255 LASSERT(cl_inode_fini_env);
256 cl_env_implant(cl_inode_fini_env, &refcheck);
257 env = cl_inode_fini_env;
258 }
259
260
261
262
263
264 cl_object_kill(env, clob);
265 lu_object_ref_del(&clob->co_lu, "inode", inode);
266 cl_object_put_last(env, clob);
267 lli->lli_clob = NULL;
268 if (emergency) {
269 cl_env_unplant(cl_inode_fini_env, &refcheck);
270 mutex_unlock(&cl_inode_fini_guard);
271 } else {
272 cl_env_put(env, &refcheck);
273 }
274 cl_env_reexit(cookie);
275 }
276}
277
278
279
280
281__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32)
282{
283 if (BITS_PER_LONG == 32 || api32)
284 return fid_flatten32(fid);
285 else
286 return fid_flatten(fid);
287}
288
289
290
291
292
293__u32 cl_fid_build_gen(const struct lu_fid *fid)
294{
295 __u32 gen;
296
297 if (fid_is_igif(fid)) {
298 gen = lu_igif_gen(fid);
299 return gen;
300 }
301
302 gen = fid_flatten(fid) >> 32;
303 return gen;
304}
305
306
307
308
309
310
311
312
313
314
315struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode)
316{
317 return lov_lsm_get(ll_i2info(inode)->lli_clob);
318}
319
320inline void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm)
321{
322 lov_lsm_put(ll_i2info(inode)->lli_clob, lsm);
323}
324