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;
75u16 cl_inode_fini_refcheck;
76
77
78
79
80
81static DEFINE_MUTEX(cl_inode_fini_guard);
82
83int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr,
84 unsigned int attr_flags)
85{
86 struct lu_env *env;
87 struct cl_io *io;
88 int result;
89 u16 refcheck;
90
91 env = cl_env_get(&refcheck);
92 if (IS_ERR(env))
93 return PTR_ERR(env);
94
95 io = vvp_env_thread_io(env);
96 io->ci_obj = obj;
97 io->ci_verify_layout = 1;
98
99 io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime);
100 io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime);
101 io->u.ci_setattr.sa_attr.lvb_ctime = LTIME_S(attr->ia_ctime);
102 io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size;
103 io->u.ci_setattr.sa_attr_flags = attr_flags;
104 io->u.ci_setattr.sa_valid = attr->ia_valid;
105 io->u.ci_setattr.sa_parent_fid = lu_object_fid(&obj->co_lu);
106
107again:
108 if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
109 struct vvp_io *vio = vvp_env_io(env);
110
111 if (attr->ia_valid & ATTR_FILE)
112
113
114
115 vio->vui_fd = LUSTRE_FPRIVATE(attr->ia_file);
116
117 result = cl_io_loop(env, io);
118 } else {
119 result = io->ci_result;
120 }
121 cl_io_fini(env, io);
122 if (unlikely(io->ci_need_restart))
123 goto again;
124
125 cl_env_put(env, &refcheck);
126 return result;
127}
128
129
130
131
132
133
134
135
136
137
138int cl_file_inode_init(struct inode *inode, struct lustre_md *md)
139{
140 struct lu_env *env;
141 struct ll_inode_info *lli;
142 struct cl_object *clob;
143 struct lu_site *site;
144 struct lu_fid *fid;
145 struct cl_object_conf conf = {
146 .coc_inode = inode,
147 .u = {
148 .coc_layout = md->layout,
149 }
150 };
151 int result = 0;
152 u16 refcheck;
153
154 LASSERT(md->body->mbo_valid & OBD_MD_FLID);
155 LASSERT(S_ISREG(inode->i_mode));
156
157 env = cl_env_get(&refcheck);
158 if (IS_ERR(env))
159 return PTR_ERR(env);
160
161 site = ll_i2sbi(inode)->ll_site;
162 lli = ll_i2info(inode);
163 fid = &lli->lli_fid;
164 LASSERT(fid_is_sane(fid));
165
166 if (!lli->lli_clob) {
167
168
169
170
171
172 LASSERT(inode->i_state & I_NEW);
173 conf.coc_lu.loc_flags = LOC_F_NEW;
174 clob = cl_object_find(env, lu2cl_dev(site->ls_top_dev),
175 fid, &conf);
176 if (!IS_ERR(clob)) {
177
178
179
180
181 lli->lli_clob = clob;
182 lu_object_ref_add(&clob->co_lu, "inode", inode);
183 } else {
184 result = PTR_ERR(clob);
185 }
186 } else {
187 result = cl_conf_set(env, lli->lli_clob, &conf);
188 }
189
190 cl_env_put(env, &refcheck);
191
192 if (result != 0)
193 CERROR("Failure to initialize cl object " DFID ": %d\n",
194 PFID(fid), result);
195 return result;
196}
197
198
199
200
201
202
203
204
205
206
207static void cl_object_put_last(struct lu_env *env, struct cl_object *obj)
208{
209 struct lu_object_header *header = obj->co_lu.lo_header;
210 wait_queue_entry_t waiter;
211
212 if (unlikely(atomic_read(&header->loh_ref) != 1)) {
213 struct lu_site *site = obj->co_lu.lo_dev->ld_site;
214 struct lu_site_bkt_data *bkt;
215
216 bkt = lu_site_bkt_from_fid(site, &header->loh_fid);
217
218 init_waitqueue_entry(&waiter, current);
219 add_wait_queue(&bkt->lsb_marche_funebre, &waiter);
220
221 while (1) {
222 set_current_state(TASK_UNINTERRUPTIBLE);
223 if (atomic_read(&header->loh_ref) == 1)
224 break;
225 schedule();
226 }
227
228 set_current_state(TASK_RUNNING);
229 remove_wait_queue(&bkt->lsb_marche_funebre, &waiter);
230 }
231
232 cl_object_put(env, obj);
233}
234
235void cl_inode_fini(struct inode *inode)
236{
237 struct lu_env *env;
238 struct ll_inode_info *lli = ll_i2info(inode);
239 struct cl_object *clob = lli->lli_clob;
240 u16 refcheck;
241 int emergency;
242
243 if (clob) {
244 env = cl_env_get(&refcheck);
245 emergency = IS_ERR(env);
246 if (emergency) {
247 mutex_lock(&cl_inode_fini_guard);
248 LASSERT(cl_inode_fini_env);
249 env = cl_inode_fini_env;
250 }
251
252
253
254
255
256 cl_object_kill(env, clob);
257 lu_object_ref_del(&clob->co_lu, "inode", inode);
258 cl_object_put_last(env, clob);
259 lli->lli_clob = NULL;
260 if (emergency)
261 mutex_unlock(&cl_inode_fini_guard);
262 else
263 cl_env_put(env, &refcheck);
264 }
265}
266
267
268
269
270__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32)
271{
272 if (BITS_PER_LONG == 32 || api32)
273 return fid_flatten32(fid);
274 else
275 return fid_flatten(fid);
276}
277
278
279
280
281
282__u32 cl_fid_build_gen(const struct lu_fid *fid)
283{
284 __u32 gen;
285
286 if (fid_is_igif(fid)) {
287 gen = lu_igif_gen(fid);
288 return gen;
289 }
290
291 gen = fid_flatten(fid) >> 32;
292 return gen;
293}
294