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 "super.h"
41#include "ocfs2_trace.h"
42
43void ocfs2_dentry_attach_gen(struct dentry *dentry)
44{
45 unsigned long gen =
46 OCFS2_I(dentry->d_parent->d_inode)->ip_dir_lock_gen;
47 BUG_ON(dentry->d_inode);
48 dentry->d_fsdata = (void *)gen;
49}
50
51
52static int ocfs2_dentry_revalidate(struct dentry *dentry,
53 struct nameidata *nd)
54{
55 struct inode *inode;
56 int ret = 0;
57 struct ocfs2_super *osb;
58
59 if (nd && nd->flags & LOOKUP_RCU)
60 return -ECHILD;
61
62 inode = dentry->d_inode;
63 osb = OCFS2_SB(dentry->d_sb);
64
65 trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len,
66 dentry->d_name.name);
67
68
69
70
71
72 if (inode == NULL) {
73 unsigned long gen = (unsigned long) dentry->d_fsdata;
74 unsigned long pgen =
75 OCFS2_I(dentry->d_parent->d_inode)->ip_dir_lock_gen;
76
77 trace_ocfs2_dentry_revalidate_negative(dentry->d_name.len,
78 dentry->d_name.name,
79 pgen, gen);
80 if (gen != pgen)
81 goto bail;
82 goto valid;
83 }
84
85 BUG_ON(!osb);
86
87 if (inode == osb->root_inode || is_bad_inode(inode))
88 goto bail;
89
90 spin_lock(&OCFS2_I(inode)->ip_lock);
91
92 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
93 spin_unlock(&OCFS2_I(inode)->ip_lock);
94 trace_ocfs2_dentry_revalidate_delete(
95 (unsigned long long)OCFS2_I(inode)->ip_blkno);
96 goto bail;
97 }
98 spin_unlock(&OCFS2_I(inode)->ip_lock);
99
100
101
102
103
104 if (inode->i_nlink == 0) {
105 trace_ocfs2_dentry_revalidate_orphaned(
106 (unsigned long long)OCFS2_I(inode)->ip_blkno,
107 S_ISDIR(inode->i_mode));
108 goto bail;
109 }
110
111
112
113
114
115 if (!dentry->d_fsdata) {
116 trace_ocfs2_dentry_revalidate_nofsdata(
117 (unsigned long long)OCFS2_I(inode)->ip_blkno);
118 goto bail;
119 }
120
121valid:
122 ret = 1;
123
124bail:
125 trace_ocfs2_dentry_revalidate_ret(ret);
126 return ret;
127}
128
129static int ocfs2_match_dentry(struct dentry *dentry,
130 u64 parent_blkno,
131 int skip_unhashed)
132{
133 struct inode *parent;
134
135
136
137
138
139
140
141 if (!dentry->d_fsdata)
142 return 0;
143
144 if (!dentry->d_parent)
145 return 0;
146
147 if (skip_unhashed && d_unhashed(dentry))
148 return 0;
149
150 parent = dentry->d_parent->d_inode;
151
152 if (!parent)
153 return 0;
154
155
156 if (OCFS2_I(parent)->ip_blkno != parent_blkno)
157 return 0;
158
159 return 1;
160}
161
162
163
164
165
166
167
168
169struct dentry *ocfs2_find_local_alias(struct inode *inode,
170 u64 parent_blkno,
171 int skip_unhashed)
172{
173 struct list_head *p;
174 struct dentry *dentry = NULL;
175
176 spin_lock(&inode->i_lock);
177 list_for_each(p, &inode->i_dentry) {
178 dentry = list_entry(p, struct dentry, d_alias);
179
180 spin_lock(&dentry->d_lock);
181 if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
182 trace_ocfs2_find_local_alias(dentry->d_name.len,
183 dentry->d_name.name);
184
185 dget_dlock(dentry);
186 spin_unlock(&dentry->d_lock);
187 break;
188 }
189 spin_unlock(&dentry->d_lock);
190
191 dentry = NULL;
192 }
193
194 spin_unlock(&inode->i_lock);
195
196 return dentry;
197}
198
199DEFINE_SPINLOCK(dentry_attach_lock);
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
226
227
228
229
230
231
232
233int ocfs2_dentry_attach_lock(struct dentry *dentry,
234 struct inode *inode,
235 u64 parent_blkno)
236{
237 int ret;
238 struct dentry *alias;
239 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
240
241 trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
242 (unsigned long long)parent_blkno, dl);
243
244
245
246
247
248
249
250 if (!inode)
251 return 0;
252
253 if (!dentry->d_inode && dentry->d_fsdata) {
254
255
256 dentry->d_fsdata = dl = NULL;
257 }
258
259 if (dl) {
260 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
261 " \"%.*s\": old parent: %llu, new: %llu\n",
262 dentry->d_name.len, dentry->d_name.name,
263 (unsigned long long)parent_blkno,
264 (unsigned long long)dl->dl_parent_blkno);
265 return 0;
266 }
267
268 alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
269 if (alias) {
270
271
272
273
274
275
276
277
278
279
280
281 dl = alias->d_fsdata;
282 mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
283 (unsigned long long)parent_blkno,
284 (unsigned long long)OCFS2_I(inode)->ip_blkno);
285
286 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
287 " \"%.*s\": old parent: %llu, new: %llu\n",
288 dentry->d_name.len, dentry->d_name.name,
289 (unsigned long long)parent_blkno,
290 (unsigned long long)dl->dl_parent_blkno);
291
292 trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
293 (unsigned long long)parent_blkno,
294 (unsigned long long)OCFS2_I(inode)->ip_blkno);
295
296 goto out_attach;
297 }
298
299
300
301
302 dl = kmalloc(sizeof(*dl), GFP_NOFS);
303 if (!dl) {
304 ret = -ENOMEM;
305 mlog_errno(ret);
306 return ret;
307 }
308
309 dl->dl_count = 0;
310
311
312
313
314 dl->dl_inode = igrab(inode);
315 dl->dl_parent_blkno = parent_blkno;
316 ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
317
318out_attach:
319 spin_lock(&dentry_attach_lock);
320 dentry->d_fsdata = dl;
321 dl->dl_count++;
322 spin_unlock(&dentry_attach_lock);
323
324
325
326
327
328
329 ret = ocfs2_dentry_lock(dentry, 0);
330 if (!ret)
331 ocfs2_dentry_unlock(dentry, 0);
332 else
333 mlog_errno(ret);
334
335
336
337
338
339
340 if (ret < 0 && !alias) {
341 ocfs2_lock_res_free(&dl->dl_lockres);
342 BUG_ON(dl->dl_count != 1);
343 spin_lock(&dentry_attach_lock);
344 dentry->d_fsdata = NULL;
345 spin_unlock(&dentry_attach_lock);
346 kfree(dl);
347 iput(inode);
348 }
349
350 dput(alias);
351
352 return ret;
353}
354
355DEFINE_SPINLOCK(dentry_list_lock);
356
357
358
359#define DL_INODE_DROP_COUNT 64
360
361
362static void __ocfs2_drop_dl_inodes(struct ocfs2_super *osb, int drop_count)
363{
364 struct ocfs2_dentry_lock *dl;
365
366 spin_lock(&dentry_list_lock);
367 while (osb->dentry_lock_list && (drop_count < 0 || drop_count--)) {
368 dl = osb->dentry_lock_list;
369 osb->dentry_lock_list = dl->dl_next;
370 spin_unlock(&dentry_list_lock);
371 iput(dl->dl_inode);
372 kfree(dl);
373 spin_lock(&dentry_list_lock);
374 }
375 spin_unlock(&dentry_list_lock);
376}
377
378void ocfs2_drop_dl_inodes(struct work_struct *work)
379{
380 struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
381 dentry_lock_work);
382
383 __ocfs2_drop_dl_inodes(osb, DL_INODE_DROP_COUNT);
384
385
386
387
388 spin_lock(&dentry_list_lock);
389 if (osb->dentry_lock_list &&
390 !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
391 queue_work(ocfs2_wq, &osb->dentry_lock_work);
392 spin_unlock(&dentry_list_lock);
393}
394
395
396void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb)
397{
398 __ocfs2_drop_dl_inodes(osb, -1);
399}
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
423 struct ocfs2_dentry_lock *dl)
424{
425 ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
426 ocfs2_lock_res_free(&dl->dl_lockres);
427
428
429
430 spin_lock(&dentry_list_lock);
431 if (!osb->dentry_lock_list &&
432 !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
433 queue_work(ocfs2_wq, &osb->dentry_lock_work);
434 dl->dl_next = osb->dentry_lock_list;
435 osb->dentry_lock_list = dl;
436 spin_unlock(&dentry_list_lock);
437}
438
439void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
440 struct ocfs2_dentry_lock *dl)
441{
442 int unlock;
443
444 BUG_ON(dl->dl_count == 0);
445
446 spin_lock(&dentry_attach_lock);
447 dl->dl_count--;
448 unlock = !dl->dl_count;
449 spin_unlock(&dentry_attach_lock);
450
451 if (unlock)
452 ocfs2_drop_dentry_lock(osb, dl);
453}
454
455static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
456{
457 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
458
459 if (!dl) {
460
461
462
463
464 if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
465 !d_unhashed(dentry)) {
466 unsigned long long ino = 0ULL;
467 if (inode)
468 ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
469 mlog(ML_ERROR, "Dentry is missing cluster lock. "
470 "inode: %llu, d_flags: 0x%x, d_name: %.*s\n",
471 ino, dentry->d_flags, dentry->d_name.len,
472 dentry->d_name.name);
473 }
474
475 goto out;
476 }
477
478 mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u\n",
479 dentry->d_name.len, dentry->d_name.name,
480 dl->dl_count);
481
482 ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
483
484out:
485 iput(inode);
486}
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
508 struct inode *old_dir, struct inode *new_dir)
509{
510 int ret;
511 struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
512 struct inode *inode = dentry->d_inode;
513
514
515
516
517
518
519
520 if (old_dir == new_dir)
521 goto out_move;
522
523 ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
524
525 dentry->d_fsdata = NULL;
526 ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
527 if (ret)
528 mlog_errno(ret);
529
530out_move:
531 d_move(dentry, target);
532}
533
534const struct dentry_operations ocfs2_dentry_ops = {
535 .d_revalidate = ocfs2_dentry_revalidate,
536 .d_iput = ocfs2_dentry_iput,
537};
538