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, unsigned int flags)
53{
54 struct inode *inode;
55 int ret = 0;
56 struct ocfs2_super *osb;
57
58 if (flags & LOOKUP_RCU)
59 return -ECHILD;
60
61 inode = dentry->d_inode;
62 osb = OCFS2_SB(dentry->d_sb);
63
64 trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len,
65 dentry->d_name.name);
66
67
68
69
70
71 if (inode == NULL) {
72 unsigned long gen = (unsigned long) dentry->d_fsdata;
73 unsigned long pgen =
74 OCFS2_I(dentry->d_parent->d_inode)->ip_dir_lock_gen;
75
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 = dentry->d_parent->d_inode;
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_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 (!dentry->d_inode && 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 " \"%.*s\": old parent: %llu, new: %llu\n",
255 dentry->d_name.len, dentry->d_name.name,
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 " \"%.*s\": old parent: %llu, new: %llu\n",
281 dentry->d_name.len, dentry->d_name.name,
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
348DEFINE_SPINLOCK(dentry_list_lock);
349
350
351
352#define DL_INODE_DROP_COUNT 64
353
354
355static void __ocfs2_drop_dl_inodes(struct ocfs2_super *osb, int drop_count)
356{
357 struct ocfs2_dentry_lock *dl;
358
359 spin_lock(&dentry_list_lock);
360 while (osb->dentry_lock_list && (drop_count < 0 || drop_count--)) {
361 dl = osb->dentry_lock_list;
362 osb->dentry_lock_list = dl->dl_next;
363 spin_unlock(&dentry_list_lock);
364 iput(dl->dl_inode);
365 kfree(dl);
366 spin_lock(&dentry_list_lock);
367 }
368 spin_unlock(&dentry_list_lock);
369}
370
371void ocfs2_drop_dl_inodes(struct work_struct *work)
372{
373 struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
374 dentry_lock_work);
375
376 __ocfs2_drop_dl_inodes(osb, DL_INODE_DROP_COUNT);
377
378
379
380
381 spin_lock(&dentry_list_lock);
382 if (osb->dentry_lock_list &&
383 !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
384 queue_work(ocfs2_wq, &osb->dentry_lock_work);
385 spin_unlock(&dentry_list_lock);
386}
387
388
389void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb)
390{
391 __ocfs2_drop_dl_inodes(osb, -1);
392}
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
416 struct ocfs2_dentry_lock *dl)
417{
418 ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
419 ocfs2_lock_res_free(&dl->dl_lockres);
420
421
422
423 spin_lock(&dentry_list_lock);
424 if (!osb->dentry_lock_list &&
425 !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
426 queue_work(ocfs2_wq, &osb->dentry_lock_work);
427 dl->dl_next = osb->dentry_lock_list;
428 osb->dentry_lock_list = dl;
429 spin_unlock(&dentry_list_lock);
430}
431
432void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
433 struct ocfs2_dentry_lock *dl)
434{
435 int unlock;
436
437 BUG_ON(dl->dl_count == 0);
438
439 spin_lock(&dentry_attach_lock);
440 dl->dl_count--;
441 unlock = !dl->dl_count;
442 spin_unlock(&dentry_attach_lock);
443
444 if (unlock)
445 ocfs2_drop_dentry_lock(osb, dl);
446}
447
448static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
449{
450 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
451
452 if (!dl) {
453
454
455
456
457 if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
458 !d_unhashed(dentry)) {
459 unsigned long long ino = 0ULL;
460 if (inode)
461 ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
462 mlog(ML_ERROR, "Dentry is missing cluster lock. "
463 "inode: %llu, d_flags: 0x%x, d_name: %.*s\n",
464 ino, dentry->d_flags, dentry->d_name.len,
465 dentry->d_name.name);
466 }
467
468 goto out;
469 }
470
471 mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u\n",
472 dentry->d_name.len, dentry->d_name.name,
473 dl->dl_count);
474
475 ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
476
477out:
478 iput(inode);
479}
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
501 struct inode *old_dir, struct inode *new_dir)
502{
503 int ret;
504 struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
505 struct inode *inode = dentry->d_inode;
506
507
508
509
510
511
512
513 if (old_dir == new_dir)
514 goto out_move;
515
516 ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
517
518 dentry->d_fsdata = NULL;
519 ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
520 if (ret)
521 mlog_errno(ret);
522
523out_move:
524 d_move(dentry, target);
525}
526
527const struct dentry_operations ocfs2_dentry_ops = {
528 .d_revalidate = ocfs2_dentry_revalidate,
529 .d_iput = ocfs2_dentry_iput,
530};
531