1
2
3
4
5
6
7
8
9
10#include <linux/fs.h>
11#include <linux/types.h>
12#include <linux/slab.h>
13#include <linux/namei.h>
14
15#include <cluster/masklog.h>
16
17#include "ocfs2.h"
18
19#include "alloc.h"
20#include "dcache.h"
21#include "dlmglue.h"
22#include "file.h"
23#include "inode.h"
24#include "ocfs2_trace.h"
25
26void ocfs2_dentry_attach_gen(struct dentry *dentry)
27{
28 unsigned long gen =
29 OCFS2_I(d_inode(dentry->d_parent))->ip_dir_lock_gen;
30 BUG_ON(d_inode(dentry));
31 dentry->d_fsdata = (void *)gen;
32}
33
34
35static int ocfs2_dentry_revalidate(struct dentry *dentry, unsigned int flags)
36{
37 struct inode *inode;
38 int ret = 0;
39 struct ocfs2_super *osb;
40
41 if (flags & LOOKUP_RCU)
42 return -ECHILD;
43
44 inode = d_inode(dentry);
45 osb = OCFS2_SB(dentry->d_sb);
46
47 trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len,
48 dentry->d_name.name);
49
50
51
52
53
54 if (inode == NULL) {
55 unsigned long gen = (unsigned long) dentry->d_fsdata;
56 unsigned long pgen;
57 spin_lock(&dentry->d_lock);
58 pgen = OCFS2_I(d_inode(dentry->d_parent))->ip_dir_lock_gen;
59 spin_unlock(&dentry->d_lock);
60 trace_ocfs2_dentry_revalidate_negative(dentry->d_name.len,
61 dentry->d_name.name,
62 pgen, gen);
63 if (gen != pgen)
64 goto bail;
65 goto valid;
66 }
67
68 BUG_ON(!osb);
69
70 if (inode == osb->root_inode || is_bad_inode(inode))
71 goto bail;
72
73 spin_lock(&OCFS2_I(inode)->ip_lock);
74
75 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
76 spin_unlock(&OCFS2_I(inode)->ip_lock);
77 trace_ocfs2_dentry_revalidate_delete(
78 (unsigned long long)OCFS2_I(inode)->ip_blkno);
79 goto bail;
80 }
81 spin_unlock(&OCFS2_I(inode)->ip_lock);
82
83
84
85
86
87 if (inode->i_nlink == 0) {
88 trace_ocfs2_dentry_revalidate_orphaned(
89 (unsigned long long)OCFS2_I(inode)->ip_blkno,
90 S_ISDIR(inode->i_mode));
91 goto bail;
92 }
93
94
95
96
97
98 if (!dentry->d_fsdata) {
99 trace_ocfs2_dentry_revalidate_nofsdata(
100 (unsigned long long)OCFS2_I(inode)->ip_blkno);
101 goto bail;
102 }
103
104valid:
105 ret = 1;
106
107bail:
108 trace_ocfs2_dentry_revalidate_ret(ret);
109 return ret;
110}
111
112static int ocfs2_match_dentry(struct dentry *dentry,
113 u64 parent_blkno,
114 int skip_unhashed)
115{
116 struct inode *parent;
117
118
119
120
121
122
123
124 if (!dentry->d_fsdata)
125 return 0;
126
127 if (!dentry->d_parent)
128 return 0;
129
130 if (skip_unhashed && d_unhashed(dentry))
131 return 0;
132
133 parent = d_inode(dentry->d_parent);
134
135 if (!parent)
136 return 0;
137
138
139 if (OCFS2_I(parent)->ip_blkno != parent_blkno)
140 return 0;
141
142 return 1;
143}
144
145
146
147
148
149
150
151
152struct dentry *ocfs2_find_local_alias(struct inode *inode,
153 u64 parent_blkno,
154 int skip_unhashed)
155{
156 struct dentry *dentry;
157
158 spin_lock(&inode->i_lock);
159 hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
160 spin_lock(&dentry->d_lock);
161 if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
162 trace_ocfs2_find_local_alias(dentry->d_name.len,
163 dentry->d_name.name);
164
165 dget_dlock(dentry);
166 spin_unlock(&dentry->d_lock);
167 spin_unlock(&inode->i_lock);
168 return dentry;
169 }
170 spin_unlock(&dentry->d_lock);
171 }
172 spin_unlock(&inode->i_lock);
173 return NULL;
174}
175
176DEFINE_SPINLOCK(dentry_attach_lock);
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210int ocfs2_dentry_attach_lock(struct dentry *dentry,
211 struct inode *inode,
212 u64 parent_blkno)
213{
214 int ret;
215 struct dentry *alias;
216 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
217
218 trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
219 (unsigned long long)parent_blkno, dl);
220
221
222
223
224
225
226
227 if (!inode)
228 return 0;
229
230 if (d_really_is_negative(dentry) && dentry->d_fsdata) {
231
232
233 dentry->d_fsdata = dl = NULL;
234 }
235
236 if (dl) {
237 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
238 " \"%pd\": old parent: %llu, new: %llu\n",
239 dentry,
240 (unsigned long long)parent_blkno,
241 (unsigned long long)dl->dl_parent_blkno);
242 return 0;
243 }
244
245 alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
246 if (alias) {
247
248
249
250
251
252
253
254
255
256
257
258 dl = alias->d_fsdata;
259 mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
260 (unsigned long long)parent_blkno,
261 (unsigned long long)OCFS2_I(inode)->ip_blkno);
262
263 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
264 " \"%pd\": old parent: %llu, new: %llu\n",
265 dentry,
266 (unsigned long long)parent_blkno,
267 (unsigned long long)dl->dl_parent_blkno);
268
269 trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
270 (unsigned long long)parent_blkno,
271 (unsigned long long)OCFS2_I(inode)->ip_blkno);
272
273 goto out_attach;
274 }
275
276
277
278
279 dl = kmalloc(sizeof(*dl), GFP_NOFS);
280 if (!dl) {
281 ret = -ENOMEM;
282 mlog_errno(ret);
283 return ret;
284 }
285
286 dl->dl_count = 0;
287
288
289
290
291 dl->dl_inode = igrab(inode);
292 dl->dl_parent_blkno = parent_blkno;
293 ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
294
295out_attach:
296 spin_lock(&dentry_attach_lock);
297 if (unlikely(dentry->d_fsdata && !alias)) {
298
299
300
301
302 spin_unlock(&dentry_attach_lock);
303 iput(dl->dl_inode);
304 ocfs2_lock_res_free(&dl->dl_lockres);
305 kfree(dl);
306 return 0;
307 }
308
309 dentry->d_fsdata = dl;
310 dl->dl_count++;
311 spin_unlock(&dentry_attach_lock);
312
313
314
315
316
317
318 ret = ocfs2_dentry_lock(dentry, 0);
319 if (!ret)
320 ocfs2_dentry_unlock(dentry, 0);
321 else
322 mlog_errno(ret);
323
324
325
326
327
328
329 if (ret < 0 && !alias) {
330 ocfs2_lock_res_free(&dl->dl_lockres);
331 BUG_ON(dl->dl_count != 1);
332 spin_lock(&dentry_attach_lock);
333 dentry->d_fsdata = NULL;
334 spin_unlock(&dentry_attach_lock);
335 kfree(dl);
336 iput(inode);
337 }
338
339 dput(alias);
340
341 return ret;
342}
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
366 struct ocfs2_dentry_lock *dl)
367{
368 iput(dl->dl_inode);
369 ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
370 ocfs2_lock_res_free(&dl->dl_lockres);
371 kfree(dl);
372}
373
374void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
375 struct ocfs2_dentry_lock *dl)
376{
377 int unlock = 0;
378
379 BUG_ON(dl->dl_count == 0);
380
381 spin_lock(&dentry_attach_lock);
382 dl->dl_count--;
383 unlock = !dl->dl_count;
384 spin_unlock(&dentry_attach_lock);
385
386 if (unlock)
387 ocfs2_drop_dentry_lock(osb, dl);
388}
389
390static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
391{
392 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
393
394 if (!dl) {
395
396
397
398
399 if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
400 !d_unhashed(dentry)) {
401 unsigned long long ino = 0ULL;
402 if (inode)
403 ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
404 mlog(ML_ERROR, "Dentry is missing cluster lock. "
405 "inode: %llu, d_flags: 0x%x, d_name: %pd\n",
406 ino, dentry->d_flags, dentry);
407 }
408
409 goto out;
410 }
411
412 mlog_bug_on_msg(dl->dl_count == 0, "dentry: %pd, count: %u\n",
413 dentry, dl->dl_count);
414
415 ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
416
417out:
418 iput(inode);
419}
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
441 struct inode *old_dir, struct inode *new_dir)
442{
443 int ret;
444 struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
445 struct inode *inode = d_inode(dentry);
446
447
448
449
450
451
452
453 if (old_dir == new_dir)
454 goto out_move;
455
456 ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
457
458 dentry->d_fsdata = NULL;
459 ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
460 if (ret)
461 mlog_errno(ret);
462
463out_move:
464 d_move(dentry, target);
465}
466
467const struct dentry_operations ocfs2_dentry_ops = {
468 .d_revalidate = ocfs2_dentry_revalidate,
469 .d_iput = ocfs2_dentry_iput,
470};
471