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