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 hlist_node *p;
173 struct dentry *dentry;
174
175 spin_lock(&inode->i_lock);
176 hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
177 spin_lock(&dentry->d_lock);
178 if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
179 trace_ocfs2_find_local_alias(dentry->d_name.len,
180 dentry->d_name.name);
181
182 dget_dlock(dentry);
183 spin_unlock(&dentry->d_lock);
184 spin_unlock(&inode->i_lock);
185 return dentry;
186 }
187 spin_unlock(&dentry->d_lock);
188 }
189 spin_unlock(&inode->i_lock);
190 return NULL;
191}
192
193DEFINE_SPINLOCK(dentry_attach_lock);
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
226
227int ocfs2_dentry_attach_lock(struct dentry *dentry,
228 struct inode *inode,
229 u64 parent_blkno)
230{
231 int ret;
232 struct dentry *alias;
233 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
234
235 trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
236 (unsigned long long)parent_blkno, dl);
237
238
239
240
241
242
243
244 if (!inode)
245 return 0;
246
247 if (!dentry->d_inode && dentry->d_fsdata) {
248
249
250 dentry->d_fsdata = dl = NULL;
251 }
252
253 if (dl) {
254 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
255 " \"%.*s\": old parent: %llu, new: %llu\n",
256 dentry->d_name.len, dentry->d_name.name,
257 (unsigned long long)parent_blkno,
258 (unsigned long long)dl->dl_parent_blkno);
259 return 0;
260 }
261
262 alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
263 if (alias) {
264
265
266
267
268
269
270
271
272
273
274
275 dl = alias->d_fsdata;
276 mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
277 (unsigned long long)parent_blkno,
278 (unsigned long long)OCFS2_I(inode)->ip_blkno);
279
280 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
281 " \"%.*s\": old parent: %llu, new: %llu\n",
282 dentry->d_name.len, dentry->d_name.name,
283 (unsigned long long)parent_blkno,
284 (unsigned long long)dl->dl_parent_blkno);
285
286 trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
287 (unsigned long long)parent_blkno,
288 (unsigned long long)OCFS2_I(inode)->ip_blkno);
289
290 goto out_attach;
291 }
292
293
294
295
296 dl = kmalloc(sizeof(*dl), GFP_NOFS);
297 if (!dl) {
298 ret = -ENOMEM;
299 mlog_errno(ret);
300 return ret;
301 }
302
303 dl->dl_count = 0;
304
305
306
307
308 dl->dl_inode = igrab(inode);
309 dl->dl_parent_blkno = parent_blkno;
310 ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
311
312out_attach:
313 spin_lock(&dentry_attach_lock);
314 dentry->d_fsdata = dl;
315 dl->dl_count++;
316 spin_unlock(&dentry_attach_lock);
317
318
319
320
321
322
323 ret = ocfs2_dentry_lock(dentry, 0);
324 if (!ret)
325 ocfs2_dentry_unlock(dentry, 0);
326 else
327 mlog_errno(ret);
328
329
330
331
332
333
334 if (ret < 0 && !alias) {
335 ocfs2_lock_res_free(&dl->dl_lockres);
336 BUG_ON(dl->dl_count != 1);
337 spin_lock(&dentry_attach_lock);
338 dentry->d_fsdata = NULL;
339 spin_unlock(&dentry_attach_lock);
340 kfree(dl);
341 iput(inode);
342 }
343
344 dput(alias);
345
346 return ret;
347}
348
349DEFINE_SPINLOCK(dentry_list_lock);
350
351
352
353#define DL_INODE_DROP_COUNT 64
354
355
356static void __ocfs2_drop_dl_inodes(struct ocfs2_super *osb, int drop_count)
357{
358 struct ocfs2_dentry_lock *dl;
359
360 spin_lock(&dentry_list_lock);
361 while (osb->dentry_lock_list && (drop_count < 0 || drop_count--)) {
362 dl = osb->dentry_lock_list;
363 osb->dentry_lock_list = dl->dl_next;
364 spin_unlock(&dentry_list_lock);
365 iput(dl->dl_inode);
366 kfree(dl);
367 spin_lock(&dentry_list_lock);
368 }
369 spin_unlock(&dentry_list_lock);
370}
371
372void ocfs2_drop_dl_inodes(struct work_struct *work)
373{
374 struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
375 dentry_lock_work);
376
377 __ocfs2_drop_dl_inodes(osb, DL_INODE_DROP_COUNT);
378
379
380
381
382 spin_lock(&dentry_list_lock);
383 if (osb->dentry_lock_list &&
384 !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
385 queue_work(ocfs2_wq, &osb->dentry_lock_work);
386 spin_unlock(&dentry_list_lock);
387}
388
389
390void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb)
391{
392 __ocfs2_drop_dl_inodes(osb, -1);
393}
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
417 struct ocfs2_dentry_lock *dl)
418{
419 ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
420 ocfs2_lock_res_free(&dl->dl_lockres);
421
422
423
424 spin_lock(&dentry_list_lock);
425 if (!osb->dentry_lock_list &&
426 !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
427 queue_work(ocfs2_wq, &osb->dentry_lock_work);
428 dl->dl_next = osb->dentry_lock_list;
429 osb->dentry_lock_list = dl;
430 spin_unlock(&dentry_list_lock);
431}
432
433void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
434 struct ocfs2_dentry_lock *dl)
435{
436 int unlock;
437
438 BUG_ON(dl->dl_count == 0);
439
440 spin_lock(&dentry_attach_lock);
441 dl->dl_count--;
442 unlock = !dl->dl_count;
443 spin_unlock(&dentry_attach_lock);
444
445 if (unlock)
446 ocfs2_drop_dentry_lock(osb, dl);
447}
448
449static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
450{
451 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
452
453 if (!dl) {
454
455
456
457
458 if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
459 !d_unhashed(dentry)) {
460 unsigned long long ino = 0ULL;
461 if (inode)
462 ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
463 mlog(ML_ERROR, "Dentry is missing cluster lock. "
464 "inode: %llu, d_flags: 0x%x, d_name: %.*s\n",
465 ino, dentry->d_flags, dentry->d_name.len,
466 dentry->d_name.name);
467 }
468
469 goto out;
470 }
471
472 mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u\n",
473 dentry->d_name.len, dentry->d_name.name,
474 dl->dl_count);
475
476 ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
477
478out:
479 iput(inode);
480}
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
502 struct inode *old_dir, struct inode *new_dir)
503{
504 int ret;
505 struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
506 struct inode *inode = dentry->d_inode;
507
508
509
510
511
512
513
514 if (old_dir == new_dir)
515 goto out_move;
516
517 ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
518
519 dentry->d_fsdata = NULL;
520 ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
521 if (ret)
522 mlog_errno(ret);
523
524out_move:
525 d_move(dentry, target);
526}
527
528const struct dentry_operations ocfs2_dentry_ops = {
529 .d_revalidate = ocfs2_dentry_revalidate,
530 .d_iput = ocfs2_dentry_iput,
531};
532