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
42
43static int ocfs2_dentry_revalidate(struct dentry *dentry,
44 struct nameidata *nd)
45{
46 struct inode *inode = dentry->d_inode;
47 int ret = 0;
48 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
49
50 mlog_entry("(0x%p, '%.*s')\n", dentry,
51 dentry->d_name.len, dentry->d_name.name);
52
53
54 if (inode == NULL) {
55 mlog(0, "negative dentry: %.*s\n", dentry->d_name.len,
56 dentry->d_name.name);
57 goto bail;
58 }
59
60 BUG_ON(!osb);
61
62 if (inode == osb->root_inode || is_bad_inode(inode))
63 goto bail;
64
65 spin_lock(&OCFS2_I(inode)->ip_lock);
66
67 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
68 spin_unlock(&OCFS2_I(inode)->ip_lock);
69 mlog(0, "inode (%llu) deleted, returning false\n",
70 (unsigned long long)OCFS2_I(inode)->ip_blkno);
71 goto bail;
72 }
73 spin_unlock(&OCFS2_I(inode)->ip_lock);
74
75
76
77
78
79 if (inode->i_nlink == 0) {
80 mlog(0, "Inode %llu orphaned, returning false "
81 "dir = %d\n",
82 (unsigned long long)OCFS2_I(inode)->ip_blkno,
83 S_ISDIR(inode->i_mode));
84 goto bail;
85 }
86
87 ret = 1;
88
89bail:
90 mlog_exit(ret);
91
92 return ret;
93}
94
95static int ocfs2_match_dentry(struct dentry *dentry,
96 u64 parent_blkno,
97 int skip_unhashed)
98{
99 struct inode *parent;
100
101
102
103
104
105
106
107 if (!dentry->d_fsdata)
108 return 0;
109
110 if (!dentry->d_parent)
111 return 0;
112
113 if (skip_unhashed && d_unhashed(dentry))
114 return 0;
115
116 parent = dentry->d_parent->d_inode;
117
118 if (!parent)
119 return 0;
120
121
122 if (OCFS2_I(parent)->ip_blkno != parent_blkno)
123 return 0;
124
125 return 1;
126}
127
128
129
130
131
132
133
134
135struct dentry *ocfs2_find_local_alias(struct inode *inode,
136 u64 parent_blkno,
137 int skip_unhashed)
138{
139 struct list_head *p;
140 struct dentry *dentry = NULL;
141
142 spin_lock(&dcache_lock);
143
144 list_for_each(p, &inode->i_dentry) {
145 dentry = list_entry(p, struct dentry, d_alias);
146
147 if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
148 mlog(0, "dentry found: %.*s\n",
149 dentry->d_name.len, dentry->d_name.name);
150
151 dget_locked(dentry);
152 break;
153 }
154
155 dentry = NULL;
156 }
157
158 spin_unlock(&dcache_lock);
159
160 return dentry;
161}
162
163DEFINE_SPINLOCK(dentry_attach_lock);
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197int ocfs2_dentry_attach_lock(struct dentry *dentry,
198 struct inode *inode,
199 u64 parent_blkno)
200{
201 int ret;
202 struct dentry *alias;
203 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
204
205 mlog(0, "Attach \"%.*s\", parent %llu, fsdata: %p\n",
206 dentry->d_name.len, dentry->d_name.name,
207 (unsigned long long)parent_blkno, dl);
208
209
210
211
212
213
214
215 if (!inode)
216 return 0;
217
218 if (dl) {
219 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
220 " \"%.*s\": old parent: %llu, new: %llu\n",
221 dentry->d_name.len, dentry->d_name.name,
222 (unsigned long long)parent_blkno,
223 (unsigned long long)dl->dl_parent_blkno);
224 return 0;
225 }
226
227 alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
228 if (alias) {
229
230
231
232
233
234
235
236
237
238
239
240 dl = alias->d_fsdata;
241 mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
242 (unsigned long long)parent_blkno,
243 (unsigned long long)OCFS2_I(inode)->ip_blkno);
244
245 mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
246 " \"%.*s\": old parent: %llu, new: %llu\n",
247 dentry->d_name.len, dentry->d_name.name,
248 (unsigned long long)parent_blkno,
249 (unsigned long long)dl->dl_parent_blkno);
250
251 mlog(0, "Found: %s\n", dl->dl_lockres.l_name);
252
253 goto out_attach;
254 }
255
256
257
258
259 dl = kmalloc(sizeof(*dl), GFP_NOFS);
260 if (!dl) {
261 ret = -ENOMEM;
262 mlog_errno(ret);
263 return ret;
264 }
265
266 dl->dl_count = 0;
267
268
269
270
271 dl->dl_inode = igrab(inode);
272 dl->dl_parent_blkno = parent_blkno;
273 ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
274
275out_attach:
276 spin_lock(&dentry_attach_lock);
277 dentry->d_fsdata = dl;
278 dl->dl_count++;
279 spin_unlock(&dentry_attach_lock);
280
281
282
283
284
285
286 ret = ocfs2_dentry_lock(dentry, 0);
287 if (!ret)
288 ocfs2_dentry_unlock(dentry, 0);
289 else
290 mlog_errno(ret);
291
292 dput(alias);
293
294 return ret;
295}
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
319 struct ocfs2_dentry_lock *dl)
320{
321 iput(dl->dl_inode);
322 ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
323 ocfs2_lock_res_free(&dl->dl_lockres);
324 kfree(dl);
325}
326
327void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
328 struct ocfs2_dentry_lock *dl)
329{
330 int unlock = 0;
331
332 BUG_ON(dl->dl_count == 0);
333
334 spin_lock(&dentry_attach_lock);
335 dl->dl_count--;
336 unlock = !dl->dl_count;
337 spin_unlock(&dentry_attach_lock);
338
339 if (unlock)
340 ocfs2_drop_dentry_lock(osb, dl);
341}
342
343static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
344{
345 struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
346
347 if (!dl) {
348
349
350
351
352 if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
353 !d_unhashed(dentry)) {
354 unsigned long long ino = 0ULL;
355 if (inode)
356 ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
357 mlog(ML_ERROR, "Dentry is missing cluster lock. "
358 "inode: %llu, d_flags: 0x%x, d_name: %.*s\n",
359 ino, dentry->d_flags, dentry->d_name.len,
360 dentry->d_name.name);
361 }
362
363 goto out;
364 }
365
366 mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u\n",
367 dentry->d_name.len, dentry->d_name.name,
368 dl->dl_count);
369
370 ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
371
372out:
373 iput(inode);
374}
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
396 struct inode *old_dir, struct inode *new_dir)
397{
398 int ret;
399 struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
400 struct inode *inode = dentry->d_inode;
401
402
403
404
405
406
407
408 if (old_dir == new_dir)
409 goto out_move;
410
411 ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
412
413 dentry->d_fsdata = NULL;
414 ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
415 if (ret)
416 mlog_errno(ret);
417
418out_move:
419 d_move(dentry, target);
420}
421
422struct dentry_operations ocfs2_dentry_ops = {
423 .d_revalidate = ocfs2_dentry_revalidate,
424 .d_iput = ocfs2_dentry_iput,
425};
426