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