Blame view

fs/ocfs2/dcache.c 14.6 KB
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
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
27
28
29
  /* -*- mode: c; c-basic-offset: 8; -*-
   * vim: noexpandtab sw=8 ts=8 sts=0:
   *
   * dcache.c
   *
   * dentry cache handling code
   *
   * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License as published by the Free Software Foundation; either
   * version 2 of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   */
  
  #include <linux/fs.h>
  #include <linux/types.h>
  #include <linux/slab.h>
  #include <linux/namei.h>
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
30
31
32
33
34
35
  #include <cluster/masklog.h>
  
  #include "ocfs2.h"
  
  #include "alloc.h"
  #include "dcache.h"
80c05846f   Mark Fasheh   ocfs2: Add dentry...
36
  #include "dlmglue.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
37
38
  #include "file.h"
  #include "inode.h"
ea455f8ab   Jan Kara   ocfs2: Push out d...
39
  #include "super.h"
a5b8443b3   Tao Ma   ocfs2: Remove mas...
40
  #include "ocfs2_trace.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
41

5e98d4924   Goldwyn Rodrigues   Track negative en...
42
43
44
45
46
47
48
  void ocfs2_dentry_attach_gen(struct dentry *dentry)
  {
  	unsigned long gen =
  		OCFS2_I(dentry->d_parent->d_inode)->ip_dir_lock_gen;
  	BUG_ON(dentry->d_inode);
  	dentry->d_fsdata = (void *)gen;
  }
80c05846f   Mark Fasheh   ocfs2: Add dentry...
49

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
50
51
52
  static int ocfs2_dentry_revalidate(struct dentry *dentry,
  				   struct nameidata *nd)
  {
34286d666   Nick Piggin   fs: rcu-walk awar...
53
  	struct inode *inode;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
54
  	int ret = 0;    /* if all else fails, just return false */
34286d666   Nick Piggin   fs: rcu-walk awar...
55
  	struct ocfs2_super *osb;
4714e6373   Al Viro   ocfs2: fix d_reva...
56
  	if (nd && nd->flags & LOOKUP_RCU)
34286d666   Nick Piggin   fs: rcu-walk awar...
57
58
59
60
  		return -ECHILD;
  
  	inode = dentry->d_inode;
  	osb = OCFS2_SB(dentry->d_sb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
61

a5b8443b3   Tao Ma   ocfs2: Remove mas...
62
63
  	trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len,
  				      dentry->d_name.name);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
64

5e98d4924   Goldwyn Rodrigues   Track negative en...
65
66
67
68
  	/* For a negative dentry -
  	 * check the generation number of the parent and compare with the
  	 * one stored in the inode.
  	 */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
69
  	if (inode == NULL) {
5e98d4924   Goldwyn Rodrigues   Track negative en...
70
71
72
  		unsigned long gen = (unsigned long) dentry->d_fsdata;
  		unsigned long pgen =
  			OCFS2_I(dentry->d_parent->d_inode)->ip_dir_lock_gen;
a5b8443b3   Tao Ma   ocfs2: Remove mas...
73
74
75
76
  
  		trace_ocfs2_dentry_revalidate_negative(dentry->d_name.len,
  						       dentry->d_name.name,
  						       pgen, gen);
5e98d4924   Goldwyn Rodrigues   Track negative en...
77
78
79
  		if (gen != pgen)
  			goto bail;
  		goto valid;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
80
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
81
  	BUG_ON(!osb);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
82
83
84
85
86
87
  	if (inode == osb->root_inode || is_bad_inode(inode))
  		goto bail;
  
  	spin_lock(&OCFS2_I(inode)->ip_lock);
  	/* did we or someone else delete this inode? */
  	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
88
  		spin_unlock(&OCFS2_I(inode)->ip_lock);
a5b8443b3   Tao Ma   ocfs2: Remove mas...
89
90
  		trace_ocfs2_dentry_revalidate_delete(
  				(unsigned long long)OCFS2_I(inode)->ip_blkno);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
91
92
93
  		goto bail;
  	}
  	spin_unlock(&OCFS2_I(inode)->ip_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
94

80c05846f   Mark Fasheh   ocfs2: Add dentry...
95
96
97
98
99
  	/*
  	 * We don't need a cluster lock to test this because once an
  	 * inode nlink hits zero, it never goes back.
  	 */
  	if (inode->i_nlink == 0) {
a5b8443b3   Tao Ma   ocfs2: Remove mas...
100
101
102
  		trace_ocfs2_dentry_revalidate_orphaned(
  			(unsigned long long)OCFS2_I(inode)->ip_blkno,
  			S_ISDIR(inode->i_mode));
80c05846f   Mark Fasheh   ocfs2: Add dentry...
103
  		goto bail;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
104
  	}
a1b08e75d   Tao Ma   ocfs2: invalidate...
105
106
107
108
109
  	/*
  	 * If the last lookup failed to create dentry lock, let us
  	 * redo it.
  	 */
  	if (!dentry->d_fsdata) {
a5b8443b3   Tao Ma   ocfs2: Remove mas...
110
111
  		trace_ocfs2_dentry_revalidate_nofsdata(
  				(unsigned long long)OCFS2_I(inode)->ip_blkno);
a1b08e75d   Tao Ma   ocfs2: invalidate...
112
113
  		goto bail;
  	}
5e98d4924   Goldwyn Rodrigues   Track negative en...
114
  valid:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
115
116
117
  	ret = 1;
  
  bail:
a5b8443b3   Tao Ma   ocfs2: Remove mas...
118
  	trace_ocfs2_dentry_revalidate_ret(ret);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
119
120
  	return ret;
  }
80c05846f   Mark Fasheh   ocfs2: Add dentry...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  static int ocfs2_match_dentry(struct dentry *dentry,
  			      u64 parent_blkno,
  			      int skip_unhashed)
  {
  	struct inode *parent;
  
  	/*
  	 * ocfs2_lookup() does a d_splice_alias() _before_ attaching
  	 * to the lock data, so we skip those here, otherwise
  	 * ocfs2_dentry_attach_lock() will get its original dentry
  	 * back.
  	 */
  	if (!dentry->d_fsdata)
  		return 0;
  
  	if (!dentry->d_parent)
  		return 0;
  
  	if (skip_unhashed && d_unhashed(dentry))
  		return 0;
  
  	parent = dentry->d_parent->d_inode;
  	/* Negative parent dentry? */
  	if (!parent)
  		return 0;
  
  	/* Name is in a different directory. */
  	if (OCFS2_I(parent)->ip_blkno != parent_blkno)
  		return 0;
  
  	return 1;
  }
  
  /*
   * Walk the inode alias list, and find a dentry which has a given
   * parent. ocfs2_dentry_attach_lock() wants to find _any_ alias as it
34d024f84   Mark Fasheh   ocfs2: Remove mou...
157
158
159
   * is looking for a dentry_lock reference. The downconvert thread is
   * looking to unhash aliases, so we allow it to skip any that already
   * have that property.
80c05846f   Mark Fasheh   ocfs2: Add dentry...
160
161
162
163
164
165
166
   */
  struct dentry *ocfs2_find_local_alias(struct inode *inode,
  				      u64 parent_blkno,
  				      int skip_unhashed)
  {
  	struct list_head *p;
  	struct dentry *dentry = NULL;
873feea09   Nick Piggin   fs: dcache per-in...
167
  	spin_lock(&inode->i_lock);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
168
169
  	list_for_each(p, &inode->i_dentry) {
  		dentry = list_entry(p, struct dentry, d_alias);
da5029563   Nick Piggin   fs: dcache scale ...
170
  		spin_lock(&dentry->d_lock);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
171
  		if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
a5b8443b3   Tao Ma   ocfs2: Remove mas...
172
173
  			trace_ocfs2_find_local_alias(dentry->d_name.len,
  						     dentry->d_name.name);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
174

dc0474be3   Nick Piggin   fs: dcache ration...
175
  			dget_dlock(dentry);
da5029563   Nick Piggin   fs: dcache scale ...
176
  			spin_unlock(&dentry->d_lock);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
177
178
  			break;
  		}
da5029563   Nick Piggin   fs: dcache scale ...
179
  		spin_unlock(&dentry->d_lock);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
180
181
182
  
  		dentry = NULL;
  	}
873feea09   Nick Piggin   fs: dcache per-in...
183
  	spin_unlock(&inode->i_lock);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
184
185
186
  
  	return dentry;
  }
d680efe9d   Mark Fasheh   ocfs2: Add new cl...
187
  DEFINE_SPINLOCK(dentry_attach_lock);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
  /*
   * Attach this dentry to a cluster lock.
   *
   * Dentry locks cover all links in a given directory to a particular
   * inode. We do this so that ocfs2 can build a lock name which all
   * nodes in the cluster can agree on at all times. Shoving full names
   * in the cluster lock won't work due to size restrictions. Covering
   * links inside of a directory is a good compromise because it still
   * allows us to use the parent directory lock to synchronize
   * operations.
   *
   * Call this function with the parent dir semaphore and the parent dir
   * cluster lock held.
   *
   * The dir semaphore will protect us from having to worry about
   * concurrent processes on our node trying to attach a lock at the
   * same time.
   *
   * The dir cluster lock (held at either PR or EX mode) protects us
   * from unlink and rename on other nodes.
   *
80c05846f   Mark Fasheh   ocfs2: Add dentry...
209
210
211
212
213
214
215
216
217
218
219
220
221
   * A dput() can happen asynchronously due to pruning, so we cover
   * attaching and detaching the dentry lock with a
   * dentry_attach_lock.
   *
   * A node which has done lookup on a name retains a protected read
   * lock until final dput. If the user requests and unlink or rename,
   * the protected read is upgraded to an exclusive lock. Other nodes
   * who have seen the dentry will then be informed that they need to
   * downgrade their lock, which will involve d_delete on the
   * dentry. This happens in ocfs2_dentry_convert_worker().
   */
  int ocfs2_dentry_attach_lock(struct dentry *dentry,
  			     struct inode *inode,
0027dd5bc   Mark Fasheh   ocfs2: Remove spe...
222
  			     u64 parent_blkno)
80c05846f   Mark Fasheh   ocfs2: Add dentry...
223
224
225
226
  {
  	int ret;
  	struct dentry *alias;
  	struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
a5b8443b3   Tao Ma   ocfs2: Remove mas...
227
228
  	trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
  				       (unsigned long long)parent_blkno, dl);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
229
230
231
232
233
234
235
236
237
  
  	/*
  	 * Negative dentry. We ignore these for now.
  	 *
  	 * XXX: Could we can improve ocfs2_dentry_revalidate() by
  	 * tracking these?
  	 */
  	if (!inode)
  		return 0;
5e98d4924   Goldwyn Rodrigues   Track negative en...
238
239
240
241
242
  	if (!dentry->d_inode && dentry->d_fsdata) {
  		/* Converting a negative dentry to positive
  		   Clear dentry->d_fsdata */
  		dentry->d_fsdata = dl = NULL;
  	}
80c05846f   Mark Fasheh   ocfs2: Add dentry...
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
  	if (dl) {
  		mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
  				" \"%.*s\": old parent: %llu, new: %llu
  ",
  				dentry->d_name.len, dentry->d_name.name,
  				(unsigned long long)parent_blkno,
  				(unsigned long long)dl->dl_parent_blkno);
  		return 0;
  	}
  
  	alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
  	if (alias) {
  		/*
  		 * Great, an alias exists, which means we must have a
  		 * dentry lock already. We can just grab the lock off
  		 * the alias and add it to the list.
  		 *
  		 * We're depending here on the fact that this dentry
  		 * was found and exists in the dcache and so must have
  		 * a reference to the dentry_lock because we can't
  		 * race creates. Final dput() cannot happen on it
  		 * since we have it pinned, so our reference is safe.
  		 */
  		dl = alias->d_fsdata;
0027dd5bc   Mark Fasheh   ocfs2: Remove spe...
267
268
  		mlog_bug_on_msg(!dl, "parent %llu, ino %llu
  ",
80c05846f   Mark Fasheh   ocfs2: Add dentry...
269
  				(unsigned long long)parent_blkno,
0027dd5bc   Mark Fasheh   ocfs2: Remove spe...
270
  				(unsigned long long)OCFS2_I(inode)->ip_blkno);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
271
272
273
274
275
276
277
  
  		mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
  				" \"%.*s\": old parent: %llu, new: %llu
  ",
  				dentry->d_name.len, dentry->d_name.name,
  				(unsigned long long)parent_blkno,
  				(unsigned long long)dl->dl_parent_blkno);
a5b8443b3   Tao Ma   ocfs2: Remove mas...
278
279
280
  		trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
  				(unsigned long long)parent_blkno,
  				(unsigned long long)OCFS2_I(inode)->ip_blkno);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
  
  		goto out_attach;
  	}
  
  	/*
  	 * There are no other aliases
  	 */
  	dl = kmalloc(sizeof(*dl), GFP_NOFS);
  	if (!dl) {
  		ret = -ENOMEM;
  		mlog_errno(ret);
  		return ret;
  	}
  
  	dl->dl_count = 0;
  	/*
  	 * Does this have to happen below, for all attaches, in case
34d024f84   Mark Fasheh   ocfs2: Remove mou...
298
  	 * the struct inode gets blown away by the downconvert thread?
80c05846f   Mark Fasheh   ocfs2: Add dentry...
299
300
301
302
303
304
305
306
307
308
309
310
  	 */
  	dl->dl_inode = igrab(inode);
  	dl->dl_parent_blkno = parent_blkno;
  	ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
  
  out_attach:
  	spin_lock(&dentry_attach_lock);
  	dentry->d_fsdata = dl;
  	dl->dl_count++;
  	spin_unlock(&dentry_attach_lock);
  
  	/*
80c05846f   Mark Fasheh   ocfs2: Add dentry...
311
312
313
314
315
  	 * This actually gets us our PRMODE level lock. From now on,
  	 * we'll have a notification if one of these names is
  	 * destroyed on another node.
  	 */
  	ret = ocfs2_dentry_lock(dentry, 0);
0027dd5bc   Mark Fasheh   ocfs2: Remove spe...
316
317
318
  	if (!ret)
  		ocfs2_dentry_unlock(dentry, 0);
  	else
80c05846f   Mark Fasheh   ocfs2: Add dentry...
319
  		mlog_errno(ret);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
320

a5a0a6309   Sunil Mushran   ocfs2: Add missin...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  	/*
  	 * In case of error, manually free the allocation and do the iput().
  	 * We need to do this because error here means no d_instantiate(),
  	 * which means iput() will not be called during dput(dentry).
  	 */
  	if (ret < 0 && !alias) {
  		ocfs2_lock_res_free(&dl->dl_lockres);
  		BUG_ON(dl->dl_count != 1);
  		spin_lock(&dentry_attach_lock);
  		dentry->d_fsdata = NULL;
  		spin_unlock(&dentry_attach_lock);
  		kfree(dl);
  		iput(inode);
  	}
80c05846f   Mark Fasheh   ocfs2: Add dentry...
335
336
337
338
  	dput(alias);
  
  	return ret;
  }
f7b1aa69b   Jan Kara   ocfs2: Fix deadlo...
339
  DEFINE_SPINLOCK(dentry_list_lock);
ea455f8ab   Jan Kara   ocfs2: Push out d...
340
341
342
343
344
345
  
  /* We limit the number of dentry locks to drop in one go. We have
   * this limit so that we don't starve other users of ocfs2_wq. */
  #define DL_INODE_DROP_COUNT 64
  
  /* Drop inode references from dentry locks */
f7b1aa69b   Jan Kara   ocfs2: Fix deadlo...
346
  static void __ocfs2_drop_dl_inodes(struct ocfs2_super *osb, int drop_count)
ea455f8ab   Jan Kara   ocfs2: Push out d...
347
  {
ea455f8ab   Jan Kara   ocfs2: Push out d...
348
  	struct ocfs2_dentry_lock *dl;
ea455f8ab   Jan Kara   ocfs2: Push out d...
349
350
  
  	spin_lock(&dentry_list_lock);
f7b1aa69b   Jan Kara   ocfs2: Fix deadlo...
351
  	while (osb->dentry_lock_list && (drop_count < 0 || drop_count--)) {
ea455f8ab   Jan Kara   ocfs2: Push out d...
352
353
354
355
356
357
358
  		dl = osb->dentry_lock_list;
  		osb->dentry_lock_list = dl->dl_next;
  		spin_unlock(&dentry_list_lock);
  		iput(dl->dl_inode);
  		kfree(dl);
  		spin_lock(&dentry_list_lock);
  	}
f7b1aa69b   Jan Kara   ocfs2: Fix deadlo...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  	spin_unlock(&dentry_list_lock);
  }
  
  void ocfs2_drop_dl_inodes(struct work_struct *work)
  {
  	struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
  					       dentry_lock_work);
  
  	__ocfs2_drop_dl_inodes(osb, DL_INODE_DROP_COUNT);
  	/*
  	 * Don't queue dropping if umount is in progress. We flush the
  	 * list in ocfs2_dismount_volume
  	 */
  	spin_lock(&dentry_list_lock);
  	if (osb->dentry_lock_list &&
  	    !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
ea455f8ab   Jan Kara   ocfs2: Push out d...
375
376
377
  		queue_work(ocfs2_wq, &osb->dentry_lock_work);
  	spin_unlock(&dentry_list_lock);
  }
f7b1aa69b   Jan Kara   ocfs2: Fix deadlo...
378
379
380
381
382
  /* Flush the whole work queue */
  void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb)
  {
  	__ocfs2_drop_dl_inodes(osb, -1);
  }
80c05846f   Mark Fasheh   ocfs2: Add dentry...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  /*
   * ocfs2_dentry_iput() and friends.
   *
   * At this point, our particular dentry is detached from the inodes
   * alias list, so there's no way that the locking code can find it.
   *
   * The interesting stuff happens when we determine that our lock needs
   * to go away because this is the last subdir alias in the
   * system. This function needs to handle a couple things:
   *
   * 1) Synchronizing lock shutdown with the downconvert threads. This
   *    is already handled for us via the lockres release drop function
   *    called in ocfs2_release_dentry_lock()
   *
   * 2) A race may occur when we're doing our lock shutdown and
   *    another process wants to create a new dentry lock. Right now we
   *    let them race, which means that for a very short while, this
   *    node might have two locks on a lock resource. This should be a
   *    problem though because one of them is in the process of being
   *    thrown out.
   */
  static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
  				   struct ocfs2_dentry_lock *dl)
  {
  	ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
  	ocfs2_lock_res_free(&dl->dl_lockres);
ea455f8ab   Jan Kara   ocfs2: Push out d...
409
410
411
412
  
  	/* We leave dropping of inode reference to ocfs2_wq as that can
  	 * possibly lead to inode deletion which gets tricky */
  	spin_lock(&dentry_list_lock);
f7b1aa69b   Jan Kara   ocfs2: Fix deadlo...
413
414
  	if (!osb->dentry_lock_list &&
  	    !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
ea455f8ab   Jan Kara   ocfs2: Push out d...
415
416
417
418
  		queue_work(ocfs2_wq, &osb->dentry_lock_work);
  	dl->dl_next = osb->dentry_lock_list;
  	osb->dentry_lock_list = dl;
  	spin_unlock(&dentry_list_lock);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
419
420
421
422
423
  }
  
  void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
  			   struct ocfs2_dentry_lock *dl)
  {
ea455f8ab   Jan Kara   ocfs2: Push out d...
424
  	int unlock;
80c05846f   Mark Fasheh   ocfs2: Add dentry...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  
  	BUG_ON(dl->dl_count == 0);
  
  	spin_lock(&dentry_attach_lock);
  	dl->dl_count--;
  	unlock = !dl->dl_count;
  	spin_unlock(&dentry_attach_lock);
  
  	if (unlock)
  		ocfs2_drop_dentry_lock(osb, dl);
  }
  
  static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
  {
  	struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
bccb9dad8   Mark Fasheh   ocfs2: Remove bug...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
  	if (!dl) {
  		/*
  		 * No dentry lock is ok if we're disconnected or
  		 * unhashed.
  		 */
  		if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
  		    !d_unhashed(dentry)) {
  			unsigned long long ino = 0ULL;
  			if (inode)
  				ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
  			mlog(ML_ERROR, "Dentry is missing cluster lock. "
  			     "inode: %llu, d_flags: 0x%x, d_name: %.*s
  ",
  			     ino, dentry->d_flags, dentry->d_name.len,
  			     dentry->d_name.name);
  		}
80c05846f   Mark Fasheh   ocfs2: Add dentry...
456

80c05846f   Mark Fasheh   ocfs2: Add dentry...
457
  		goto out;
bccb9dad8   Mark Fasheh   ocfs2: Remove bug...
458
  	}
80c05846f   Mark Fasheh   ocfs2: Add dentry...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
  
  	mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u
  ",
  			dentry->d_name.len, dentry->d_name.name,
  			dl->dl_count);
  
  	ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
  
  out:
  	iput(inode);
  }
  
  /*
   * d_move(), but keep the locks in sync.
   *
   * When we are done, "dentry" will have the parent dir and name of
   * "target", which will be thrown away.
   *
   * We manually update the lock of "dentry" if need be.
   *
   * "target" doesn't have it's dentry lock touched - we allow the later
   * dput() to handle this for us.
   *
   * This is called during ocfs2_rename(), while holding parent
   * directory locks. The dentries have already been deleted on other
   * nodes via ocfs2_remote_dentry_delete().
   *
3a4fa0a25   Robert P. J. Day   Fix misspellings ...
486
   * Normally, the VFS handles the d_move() for the file system, after
80c05846f   Mark Fasheh   ocfs2: Add dentry...
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
   * the ->rename() callback. OCFS2 wants to handle this internally, so
   * the new lock can be created atomically with respect to the cluster.
   */
  void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
  		       struct inode *old_dir, struct inode *new_dir)
  {
  	int ret;
  	struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
  	struct inode *inode = dentry->d_inode;
  
  	/*
  	 * Move within the same directory, so the actual lock info won't
  	 * change.
  	 *
  	 * XXX: Is there any advantage to dropping the lock here?
  	 */
  	if (old_dir == new_dir)
1ba9da2ff   Mark Fasheh   ocfs2: manually d...
504
  		goto out_move;
80c05846f   Mark Fasheh   ocfs2: Add dentry...
505
506
507
508
  
  	ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
  
  	dentry->d_fsdata = NULL;
0027dd5bc   Mark Fasheh   ocfs2: Remove spe...
509
  	ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
510
511
  	if (ret)
  		mlog_errno(ret);
1ba9da2ff   Mark Fasheh   ocfs2: manually d...
512
513
514
  
  out_move:
  	d_move(dentry, target);
80c05846f   Mark Fasheh   ocfs2: Add dentry...
515
  }
d8fba0ffe   Al Viro   constify dentry_o...
516
  const struct dentry_operations ocfs2_dentry_ops = {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
517
  	.d_revalidate		= ocfs2_dentry_revalidate,
80c05846f   Mark Fasheh   ocfs2: Add dentry...
518
  	.d_iput			= ocfs2_dentry_iput,
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
519
  };