xref: /linux/fs/ocfs2/dcache.c (revision 06d07429858317ded2db7986113a9e0129cd599b)
1328970deSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2*fa60ce2cSMasahiro Yamada /*
3ccd979bdSMark Fasheh  * dcache.c
4ccd979bdSMark Fasheh  *
5ccd979bdSMark Fasheh  * dentry cache handling code
6ccd979bdSMark Fasheh  *
7ccd979bdSMark Fasheh  * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
8ccd979bdSMark Fasheh  */
9ccd979bdSMark Fasheh 
10ccd979bdSMark Fasheh #include <linux/fs.h>
11ccd979bdSMark Fasheh #include <linux/types.h>
12ccd979bdSMark Fasheh #include <linux/slab.h>
13ccd979bdSMark Fasheh #include <linux/namei.h>
14ccd979bdSMark Fasheh 
15ccd979bdSMark Fasheh #include <cluster/masklog.h>
16ccd979bdSMark Fasheh 
17ccd979bdSMark Fasheh #include "ocfs2.h"
18ccd979bdSMark Fasheh 
19ccd979bdSMark Fasheh #include "alloc.h"
20ccd979bdSMark Fasheh #include "dcache.h"
2180c05846SMark Fasheh #include "dlmglue.h"
22ccd979bdSMark Fasheh #include "file.h"
23ccd979bdSMark Fasheh #include "inode.h"
24a5b8443bSTao Ma #include "ocfs2_trace.h"
25ccd979bdSMark Fasheh 
ocfs2_dentry_attach_gen(struct dentry * dentry)265e98d492SGoldwyn Rodrigues void ocfs2_dentry_attach_gen(struct dentry *dentry)
275e98d492SGoldwyn Rodrigues {
285e98d492SGoldwyn Rodrigues 	unsigned long gen =
292b0143b5SDavid Howells 		OCFS2_I(d_inode(dentry->d_parent))->ip_dir_lock_gen;
302b0143b5SDavid Howells 	BUG_ON(d_inode(dentry));
315e98d492SGoldwyn Rodrigues 	dentry->d_fsdata = (void *)gen;
325e98d492SGoldwyn Rodrigues }
335e98d492SGoldwyn Rodrigues 
3480c05846SMark Fasheh 
ocfs2_dentry_revalidate(struct dentry * dentry,unsigned int flags)350b728e19SAl Viro static int ocfs2_dentry_revalidate(struct dentry *dentry, unsigned int flags)
36ccd979bdSMark Fasheh {
3734286d66SNick Piggin 	struct inode *inode;
38ccd979bdSMark Fasheh 	int ret = 0;    /* if all else fails, just return false */
3934286d66SNick Piggin 	struct ocfs2_super *osb;
4034286d66SNick Piggin 
410b728e19SAl Viro 	if (flags & LOOKUP_RCU)
4234286d66SNick Piggin 		return -ECHILD;
4334286d66SNick Piggin 
442b0143b5SDavid Howells 	inode = d_inode(dentry);
4534286d66SNick Piggin 	osb = OCFS2_SB(dentry->d_sb);
46ccd979bdSMark Fasheh 
47a5b8443bSTao Ma 	trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len,
48a5b8443bSTao Ma 				      dentry->d_name.name);
49ccd979bdSMark Fasheh 
505e98d492SGoldwyn Rodrigues 	/* For a negative dentry -
515e98d492SGoldwyn Rodrigues 	 * check the generation number of the parent and compare with the
525e98d492SGoldwyn Rodrigues 	 * one stored in the inode.
535e98d492SGoldwyn Rodrigues 	 */
54ccd979bdSMark Fasheh 	if (inode == NULL) {
555e98d492SGoldwyn Rodrigues 		unsigned long gen = (unsigned long) dentry->d_fsdata;
567b9a2378SAl Viro 		unsigned long pgen;
577b9a2378SAl Viro 		spin_lock(&dentry->d_lock);
582b0143b5SDavid Howells 		pgen = OCFS2_I(d_inode(dentry->d_parent))->ip_dir_lock_gen;
597b9a2378SAl Viro 		spin_unlock(&dentry->d_lock);
60a5b8443bSTao Ma 		trace_ocfs2_dentry_revalidate_negative(dentry->d_name.len,
61a5b8443bSTao Ma 						       dentry->d_name.name,
62a5b8443bSTao Ma 						       pgen, gen);
635e98d492SGoldwyn Rodrigues 		if (gen != pgen)
64ccd979bdSMark Fasheh 			goto bail;
655e98d492SGoldwyn Rodrigues 		goto valid;
66ccd979bdSMark Fasheh 	}
67ccd979bdSMark Fasheh 
68ccd979bdSMark Fasheh 	BUG_ON(!osb);
69ccd979bdSMark Fasheh 
7080c05846SMark Fasheh 	if (inode == osb->root_inode || is_bad_inode(inode))
7180c05846SMark Fasheh 		goto bail;
7280c05846SMark Fasheh 
73ccd979bdSMark Fasheh 	spin_lock(&OCFS2_I(inode)->ip_lock);
74ccd979bdSMark Fasheh 	/* did we or someone else delete this inode? */
75ccd979bdSMark Fasheh 	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
76ccd979bdSMark Fasheh 		spin_unlock(&OCFS2_I(inode)->ip_lock);
77a5b8443bSTao Ma 		trace_ocfs2_dentry_revalidate_delete(
78b0697053SMark Fasheh 				(unsigned long long)OCFS2_I(inode)->ip_blkno);
79ccd979bdSMark Fasheh 		goto bail;
80ccd979bdSMark Fasheh 	}
81ccd979bdSMark Fasheh 	spin_unlock(&OCFS2_I(inode)->ip_lock);
82ccd979bdSMark Fasheh 
8380c05846SMark Fasheh 	/*
8480c05846SMark Fasheh 	 * We don't need a cluster lock to test this because once an
8580c05846SMark Fasheh 	 * inode nlink hits zero, it never goes back.
8680c05846SMark Fasheh 	 */
8780c05846SMark Fasheh 	if (inode->i_nlink == 0) {
88a5b8443bSTao Ma 		trace_ocfs2_dentry_revalidate_orphaned(
89b0697053SMark Fasheh 			(unsigned long long)OCFS2_I(inode)->ip_blkno,
90ccd979bdSMark Fasheh 			S_ISDIR(inode->i_mode));
91ccd979bdSMark Fasheh 		goto bail;
92ccd979bdSMark Fasheh 	}
93ccd979bdSMark Fasheh 
94a1b08e75STao Ma 	/*
95a1b08e75STao Ma 	 * If the last lookup failed to create dentry lock, let us
96a1b08e75STao Ma 	 * redo it.
97a1b08e75STao Ma 	 */
98a1b08e75STao Ma 	if (!dentry->d_fsdata) {
99a5b8443bSTao Ma 		trace_ocfs2_dentry_revalidate_nofsdata(
100a1b08e75STao Ma 				(unsigned long long)OCFS2_I(inode)->ip_blkno);
101a1b08e75STao Ma 		goto bail;
102a1b08e75STao Ma 	}
103a1b08e75STao Ma 
1045e98d492SGoldwyn Rodrigues valid:
105ccd979bdSMark Fasheh 	ret = 1;
106ccd979bdSMark Fasheh 
107ccd979bdSMark Fasheh bail:
108a5b8443bSTao Ma 	trace_ocfs2_dentry_revalidate_ret(ret);
109ccd979bdSMark Fasheh 	return ret;
110ccd979bdSMark Fasheh }
111ccd979bdSMark Fasheh 
ocfs2_match_dentry(struct dentry * dentry,u64 parent_blkno,int skip_unhashed)11280c05846SMark Fasheh static int ocfs2_match_dentry(struct dentry *dentry,
11380c05846SMark Fasheh 			      u64 parent_blkno,
11480c05846SMark Fasheh 			      int skip_unhashed)
11580c05846SMark Fasheh {
11680c05846SMark Fasheh 	struct inode *parent;
11780c05846SMark Fasheh 
11880c05846SMark Fasheh 	/*
11980c05846SMark Fasheh 	 * ocfs2_lookup() does a d_splice_alias() _before_ attaching
12080c05846SMark Fasheh 	 * to the lock data, so we skip those here, otherwise
12180c05846SMark Fasheh 	 * ocfs2_dentry_attach_lock() will get its original dentry
12280c05846SMark Fasheh 	 * back.
12380c05846SMark Fasheh 	 */
12480c05846SMark Fasheh 	if (!dentry->d_fsdata)
12580c05846SMark Fasheh 		return 0;
12680c05846SMark Fasheh 
12780c05846SMark Fasheh 	if (skip_unhashed && d_unhashed(dentry))
12880c05846SMark Fasheh 		return 0;
12980c05846SMark Fasheh 
1302b0143b5SDavid Howells 	parent = d_inode(dentry->d_parent);
13180c05846SMark Fasheh 	/* Name is in a different directory. */
13280c05846SMark Fasheh 	if (OCFS2_I(parent)->ip_blkno != parent_blkno)
13380c05846SMark Fasheh 		return 0;
13480c05846SMark Fasheh 
13580c05846SMark Fasheh 	return 1;
13680c05846SMark Fasheh }
13780c05846SMark Fasheh 
13880c05846SMark Fasheh /*
13980c05846SMark Fasheh  * Walk the inode alias list, and find a dentry which has a given
14080c05846SMark Fasheh  * parent. ocfs2_dentry_attach_lock() wants to find _any_ alias as it
14134d024f8SMark Fasheh  * is looking for a dentry_lock reference. The downconvert thread is
14234d024f8SMark Fasheh  * looking to unhash aliases, so we allow it to skip any that already
14334d024f8SMark Fasheh  * have that property.
14480c05846SMark Fasheh  */
ocfs2_find_local_alias(struct inode * inode,u64 parent_blkno,int skip_unhashed)14580c05846SMark Fasheh struct dentry *ocfs2_find_local_alias(struct inode *inode,
14680c05846SMark Fasheh 				      u64 parent_blkno,
14780c05846SMark Fasheh 				      int skip_unhashed)
14880c05846SMark Fasheh {
149a614a092SAl Viro 	struct dentry *dentry;
15080c05846SMark Fasheh 
151873feea0SNick Piggin 	spin_lock(&inode->i_lock);
152946e51f2SAl Viro 	hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
153da502956SNick Piggin 		spin_lock(&dentry->d_lock);
15480c05846SMark Fasheh 		if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
155a5b8443bSTao Ma 			trace_ocfs2_find_local_alias(dentry->d_name.len,
156a5b8443bSTao Ma 						     dentry->d_name.name);
15780c05846SMark Fasheh 
158dc0474beSNick Piggin 			dget_dlock(dentry);
159da502956SNick Piggin 			spin_unlock(&dentry->d_lock);
160a614a092SAl Viro 			spin_unlock(&inode->i_lock);
161a614a092SAl Viro 			return dentry;
16280c05846SMark Fasheh 		}
163da502956SNick Piggin 		spin_unlock(&dentry->d_lock);
16480c05846SMark Fasheh 	}
165873feea0SNick Piggin 	spin_unlock(&inode->i_lock);
166a614a092SAl Viro 	return NULL;
16780c05846SMark Fasheh }
16880c05846SMark Fasheh 
169d680efe9SMark Fasheh DEFINE_SPINLOCK(dentry_attach_lock);
170d680efe9SMark Fasheh 
17180c05846SMark Fasheh /*
17280c05846SMark Fasheh  * Attach this dentry to a cluster lock.
17380c05846SMark Fasheh  *
17480c05846SMark Fasheh  * Dentry locks cover all links in a given directory to a particular
17580c05846SMark Fasheh  * inode. We do this so that ocfs2 can build a lock name which all
17680c05846SMark Fasheh  * nodes in the cluster can agree on at all times. Shoving full names
17780c05846SMark Fasheh  * in the cluster lock won't work due to size restrictions. Covering
17880c05846SMark Fasheh  * links inside of a directory is a good compromise because it still
17980c05846SMark Fasheh  * allows us to use the parent directory lock to synchronize
18080c05846SMark Fasheh  * operations.
18180c05846SMark Fasheh  *
18280c05846SMark Fasheh  * Call this function with the parent dir semaphore and the parent dir
18380c05846SMark Fasheh  * cluster lock held.
18480c05846SMark Fasheh  *
18580c05846SMark Fasheh  * The dir semaphore will protect us from having to worry about
18680c05846SMark Fasheh  * concurrent processes on our node trying to attach a lock at the
18780c05846SMark Fasheh  * same time.
18880c05846SMark Fasheh  *
18980c05846SMark Fasheh  * The dir cluster lock (held at either PR or EX mode) protects us
19080c05846SMark Fasheh  * from unlink and rename on other nodes.
19180c05846SMark Fasheh  *
19280c05846SMark Fasheh  * A dput() can happen asynchronously due to pruning, so we cover
19380c05846SMark Fasheh  * attaching and detaching the dentry lock with a
19480c05846SMark Fasheh  * dentry_attach_lock.
19580c05846SMark Fasheh  *
19680c05846SMark Fasheh  * A node which has done lookup on a name retains a protected read
19780c05846SMark Fasheh  * lock until final dput. If the user requests and unlink or rename,
19880c05846SMark Fasheh  * the protected read is upgraded to an exclusive lock. Other nodes
19980c05846SMark Fasheh  * who have seen the dentry will then be informed that they need to
20080c05846SMark Fasheh  * downgrade their lock, which will involve d_delete on the
20180c05846SMark Fasheh  * dentry. This happens in ocfs2_dentry_convert_worker().
20280c05846SMark Fasheh  */
ocfs2_dentry_attach_lock(struct dentry * dentry,struct inode * inode,u64 parent_blkno)20380c05846SMark Fasheh int ocfs2_dentry_attach_lock(struct dentry *dentry,
20480c05846SMark Fasheh 			     struct inode *inode,
2050027dd5bSMark Fasheh 			     u64 parent_blkno)
20680c05846SMark Fasheh {
20780c05846SMark Fasheh 	int ret;
20880c05846SMark Fasheh 	struct dentry *alias;
20980c05846SMark Fasheh 	struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
21080c05846SMark Fasheh 
211a5b8443bSTao Ma 	trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
2120027dd5bSMark Fasheh 				       (unsigned long long)parent_blkno, dl);
21380c05846SMark Fasheh 
21480c05846SMark Fasheh 	/*
21580c05846SMark Fasheh 	 * Negative dentry. We ignore these for now.
21680c05846SMark Fasheh 	 *
21780c05846SMark Fasheh 	 * XXX: Could we can improve ocfs2_dentry_revalidate() by
21880c05846SMark Fasheh 	 * tracking these?
21980c05846SMark Fasheh 	 */
22080c05846SMark Fasheh 	if (!inode)
22180c05846SMark Fasheh 		return 0;
22280c05846SMark Fasheh 
2232b0143b5SDavid Howells 	if (d_really_is_negative(dentry) && dentry->d_fsdata) {
2245e98d492SGoldwyn Rodrigues 		/* Converting a negative dentry to positive
2255e98d492SGoldwyn Rodrigues 		   Clear dentry->d_fsdata */
2265e98d492SGoldwyn Rodrigues 		dentry->d_fsdata = dl = NULL;
2275e98d492SGoldwyn Rodrigues 	}
2285e98d492SGoldwyn Rodrigues 
22980c05846SMark Fasheh 	if (dl) {
23080c05846SMark Fasheh 		mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
231a455589fSAl Viro 				" \"%pd\": old parent: %llu, new: %llu\n",
232a455589fSAl Viro 				dentry,
23380c05846SMark Fasheh 				(unsigned long long)parent_blkno,
23480c05846SMark Fasheh 				(unsigned long long)dl->dl_parent_blkno);
23580c05846SMark Fasheh 		return 0;
23680c05846SMark Fasheh 	}
23780c05846SMark Fasheh 
23880c05846SMark Fasheh 	alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
23980c05846SMark Fasheh 	if (alias) {
24080c05846SMark Fasheh 		/*
24180c05846SMark Fasheh 		 * Great, an alias exists, which means we must have a
24280c05846SMark Fasheh 		 * dentry lock already. We can just grab the lock off
24380c05846SMark Fasheh 		 * the alias and add it to the list.
24480c05846SMark Fasheh 		 *
24580c05846SMark Fasheh 		 * We're depending here on the fact that this dentry
24680c05846SMark Fasheh 		 * was found and exists in the dcache and so must have
24780c05846SMark Fasheh 		 * a reference to the dentry_lock because we can't
24880c05846SMark Fasheh 		 * race creates. Final dput() cannot happen on it
24980c05846SMark Fasheh 		 * since we have it pinned, so our reference is safe.
25080c05846SMark Fasheh 		 */
25180c05846SMark Fasheh 		dl = alias->d_fsdata;
2520027dd5bSMark Fasheh 		mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
25380c05846SMark Fasheh 				(unsigned long long)parent_blkno,
2540027dd5bSMark Fasheh 				(unsigned long long)OCFS2_I(inode)->ip_blkno);
25580c05846SMark Fasheh 
25680c05846SMark Fasheh 		mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
257a455589fSAl Viro 				" \"%pd\": old parent: %llu, new: %llu\n",
258a455589fSAl Viro 				dentry,
25980c05846SMark Fasheh 				(unsigned long long)parent_blkno,
26080c05846SMark Fasheh 				(unsigned long long)dl->dl_parent_blkno);
26180c05846SMark Fasheh 
262a5b8443bSTao Ma 		trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
263a5b8443bSTao Ma 				(unsigned long long)parent_blkno,
264a5b8443bSTao Ma 				(unsigned long long)OCFS2_I(inode)->ip_blkno);
26580c05846SMark Fasheh 
26680c05846SMark Fasheh 		goto out_attach;
26780c05846SMark Fasheh 	}
26880c05846SMark Fasheh 
26980c05846SMark Fasheh 	/*
27080c05846SMark Fasheh 	 * There are no other aliases
27180c05846SMark Fasheh 	 */
27280c05846SMark Fasheh 	dl = kmalloc(sizeof(*dl), GFP_NOFS);
27380c05846SMark Fasheh 	if (!dl) {
27480c05846SMark Fasheh 		ret = -ENOMEM;
27580c05846SMark Fasheh 		mlog_errno(ret);
27680c05846SMark Fasheh 		return ret;
27780c05846SMark Fasheh 	}
27880c05846SMark Fasheh 
27980c05846SMark Fasheh 	dl->dl_count = 0;
28080c05846SMark Fasheh 	/*
28180c05846SMark Fasheh 	 * Does this have to happen below, for all attaches, in case
28234d024f8SMark Fasheh 	 * the struct inode gets blown away by the downconvert thread?
28380c05846SMark Fasheh 	 */
28480c05846SMark Fasheh 	dl->dl_inode = igrab(inode);
28580c05846SMark Fasheh 	dl->dl_parent_blkno = parent_blkno;
28680c05846SMark Fasheh 	ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
28780c05846SMark Fasheh 
28880c05846SMark Fasheh out_attach:
28980c05846SMark Fasheh 	spin_lock(&dentry_attach_lock);
290be99ca27SWengang Wang 	if (unlikely(dentry->d_fsdata && !alias)) {
291be99ca27SWengang Wang 		/* d_fsdata is set by a racing thread which is doing
292be99ca27SWengang Wang 		 * the same thing as this thread is doing. Leave the racing
293be99ca27SWengang Wang 		 * thread going ahead and we return here.
294be99ca27SWengang Wang 		 */
295be99ca27SWengang Wang 		spin_unlock(&dentry_attach_lock);
296be99ca27SWengang Wang 		iput(dl->dl_inode);
297be99ca27SWengang Wang 		ocfs2_lock_res_free(&dl->dl_lockres);
298be99ca27SWengang Wang 		kfree(dl);
299be99ca27SWengang Wang 		return 0;
300be99ca27SWengang Wang 	}
301be99ca27SWengang Wang 
30280c05846SMark Fasheh 	dentry->d_fsdata = dl;
30380c05846SMark Fasheh 	dl->dl_count++;
30480c05846SMark Fasheh 	spin_unlock(&dentry_attach_lock);
30580c05846SMark Fasheh 
30680c05846SMark Fasheh 	/*
30780c05846SMark Fasheh 	 * This actually gets us our PRMODE level lock. From now on,
30880c05846SMark Fasheh 	 * we'll have a notification if one of these names is
30980c05846SMark Fasheh 	 * destroyed on another node.
31080c05846SMark Fasheh 	 */
31180c05846SMark Fasheh 	ret = ocfs2_dentry_lock(dentry, 0);
3120027dd5bSMark Fasheh 	if (!ret)
31380c05846SMark Fasheh 		ocfs2_dentry_unlock(dentry, 0);
3140027dd5bSMark Fasheh 	else
3150027dd5bSMark Fasheh 		mlog_errno(ret);
31680c05846SMark Fasheh 
317a5a0a630SSunil Mushran 	/*
318a5a0a630SSunil Mushran 	 * In case of error, manually free the allocation and do the iput().
319a5a0a630SSunil Mushran 	 * We need to do this because error here means no d_instantiate(),
320a5a0a630SSunil Mushran 	 * which means iput() will not be called during dput(dentry).
321a5a0a630SSunil Mushran 	 */
322a5a0a630SSunil Mushran 	if (ret < 0 && !alias) {
323a5a0a630SSunil Mushran 		ocfs2_lock_res_free(&dl->dl_lockres);
324a5a0a630SSunil Mushran 		BUG_ON(dl->dl_count != 1);
325a5a0a630SSunil Mushran 		spin_lock(&dentry_attach_lock);
326a5a0a630SSunil Mushran 		dentry->d_fsdata = NULL;
327a5a0a630SSunil Mushran 		spin_unlock(&dentry_attach_lock);
328a5a0a630SSunil Mushran 		kfree(dl);
329a5a0a630SSunil Mushran 		iput(inode);
330a5a0a630SSunil Mushran 	}
331a5a0a630SSunil Mushran 
33280c05846SMark Fasheh 	dput(alias);
33380c05846SMark Fasheh 
33480c05846SMark Fasheh 	return ret;
33580c05846SMark Fasheh }
33680c05846SMark Fasheh 
33780c05846SMark Fasheh /*
33880c05846SMark Fasheh  * ocfs2_dentry_iput() and friends.
33980c05846SMark Fasheh  *
34080c05846SMark Fasheh  * At this point, our particular dentry is detached from the inodes
34180c05846SMark Fasheh  * alias list, so there's no way that the locking code can find it.
34280c05846SMark Fasheh  *
34380c05846SMark Fasheh  * The interesting stuff happens when we determine that our lock needs
34480c05846SMark Fasheh  * to go away because this is the last subdir alias in the
34580c05846SMark Fasheh  * system. This function needs to handle a couple things:
34680c05846SMark Fasheh  *
34780c05846SMark Fasheh  * 1) Synchronizing lock shutdown with the downconvert threads. This
34880c05846SMark Fasheh  *    is already handled for us via the lockres release drop function
34980c05846SMark Fasheh  *    called in ocfs2_release_dentry_lock()
35080c05846SMark Fasheh  *
35180c05846SMark Fasheh  * 2) A race may occur when we're doing our lock shutdown and
35280c05846SMark Fasheh  *    another process wants to create a new dentry lock. Right now we
35380c05846SMark Fasheh  *    let them race, which means that for a very short while, this
35480c05846SMark Fasheh  *    node might have two locks on a lock resource. This should be a
35580c05846SMark Fasheh  *    problem though because one of them is in the process of being
35680c05846SMark Fasheh  *    thrown out.
35780c05846SMark Fasheh  */
ocfs2_drop_dentry_lock(struct ocfs2_super * osb,struct ocfs2_dentry_lock * dl)35880c05846SMark Fasheh static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
35980c05846SMark Fasheh 				   struct ocfs2_dentry_lock *dl)
36080c05846SMark Fasheh {
3618ed6b237SGoldwyn Rodrigues 	iput(dl->dl_inode);
36280c05846SMark Fasheh 	ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
36380c05846SMark Fasheh 	ocfs2_lock_res_free(&dl->dl_lockres);
3648ed6b237SGoldwyn Rodrigues 	kfree(dl);
36580c05846SMark Fasheh }
36680c05846SMark Fasheh 
ocfs2_dentry_lock_put(struct ocfs2_super * osb,struct ocfs2_dentry_lock * dl)36780c05846SMark Fasheh void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
36880c05846SMark Fasheh 			   struct ocfs2_dentry_lock *dl)
36980c05846SMark Fasheh {
3708ed6b237SGoldwyn Rodrigues 	int unlock = 0;
37180c05846SMark Fasheh 
37280c05846SMark Fasheh 	BUG_ON(dl->dl_count == 0);
37380c05846SMark Fasheh 
37480c05846SMark Fasheh 	spin_lock(&dentry_attach_lock);
37580c05846SMark Fasheh 	dl->dl_count--;
37680c05846SMark Fasheh 	unlock = !dl->dl_count;
37780c05846SMark Fasheh 	spin_unlock(&dentry_attach_lock);
37880c05846SMark Fasheh 
37980c05846SMark Fasheh 	if (unlock)
38080c05846SMark Fasheh 		ocfs2_drop_dentry_lock(osb, dl);
38180c05846SMark Fasheh }
38280c05846SMark Fasheh 
ocfs2_dentry_iput(struct dentry * dentry,struct inode * inode)38380c05846SMark Fasheh static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
38480c05846SMark Fasheh {
38580c05846SMark Fasheh 	struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
38680c05846SMark Fasheh 
387bccb9dadSMark Fasheh 	if (!dl) {
388bccb9dadSMark Fasheh 		/*
389bccb9dadSMark Fasheh 		 * No dentry lock is ok if we're disconnected or
390bccb9dadSMark Fasheh 		 * unhashed.
391bccb9dadSMark Fasheh 		 */
392bccb9dadSMark Fasheh 		if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
393bccb9dadSMark Fasheh 		    !d_unhashed(dentry)) {
394bccb9dadSMark Fasheh 			unsigned long long ino = 0ULL;
395bccb9dadSMark Fasheh 			if (inode)
396bccb9dadSMark Fasheh 				ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
397bccb9dadSMark Fasheh 			mlog(ML_ERROR, "Dentry is missing cluster lock. "
398a455589fSAl Viro 			     "inode: %llu, d_flags: 0x%x, d_name: %pd\n",
399a455589fSAl Viro 			     ino, dentry->d_flags, dentry);
400bccb9dadSMark Fasheh 		}
40180c05846SMark Fasheh 
40280c05846SMark Fasheh 		goto out;
403bccb9dadSMark Fasheh 	}
40480c05846SMark Fasheh 
405a455589fSAl Viro 	mlog_bug_on_msg(dl->dl_count == 0, "dentry: %pd, count: %u\n",
406a455589fSAl Viro 			dentry, dl->dl_count);
40780c05846SMark Fasheh 
40880c05846SMark Fasheh 	ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
40980c05846SMark Fasheh 
41080c05846SMark Fasheh out:
41180c05846SMark Fasheh 	iput(inode);
41280c05846SMark Fasheh }
41380c05846SMark Fasheh 
41480c05846SMark Fasheh /*
41580c05846SMark Fasheh  * d_move(), but keep the locks in sync.
41680c05846SMark Fasheh  *
41780c05846SMark Fasheh  * When we are done, "dentry" will have the parent dir and name of
41880c05846SMark Fasheh  * "target", which will be thrown away.
41980c05846SMark Fasheh  *
42080c05846SMark Fasheh  * We manually update the lock of "dentry" if need be.
42180c05846SMark Fasheh  *
42280c05846SMark Fasheh  * "target" doesn't have it's dentry lock touched - we allow the later
42380c05846SMark Fasheh  * dput() to handle this for us.
42480c05846SMark Fasheh  *
42580c05846SMark Fasheh  * This is called during ocfs2_rename(), while holding parent
42680c05846SMark Fasheh  * directory locks. The dentries have already been deleted on other
42780c05846SMark Fasheh  * nodes via ocfs2_remote_dentry_delete().
42880c05846SMark Fasheh  *
4293a4fa0a2SRobert P. J. Day  * Normally, the VFS handles the d_move() for the file system, after
43080c05846SMark Fasheh  * the ->rename() callback. OCFS2 wants to handle this internally, so
43180c05846SMark Fasheh  * the new lock can be created atomically with respect to the cluster.
43280c05846SMark Fasheh  */
ocfs2_dentry_move(struct dentry * dentry,struct dentry * target,struct inode * old_dir,struct inode * new_dir)43380c05846SMark Fasheh void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
43480c05846SMark Fasheh 		       struct inode *old_dir, struct inode *new_dir)
43580c05846SMark Fasheh {
43680c05846SMark Fasheh 	int ret;
43780c05846SMark Fasheh 	struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
4382b0143b5SDavid Howells 	struct inode *inode = d_inode(dentry);
43980c05846SMark Fasheh 
44080c05846SMark Fasheh 	/*
44180c05846SMark Fasheh 	 * Move within the same directory, so the actual lock info won't
44280c05846SMark Fasheh 	 * change.
44380c05846SMark Fasheh 	 *
44480c05846SMark Fasheh 	 * XXX: Is there any advantage to dropping the lock here?
44580c05846SMark Fasheh 	 */
44680c05846SMark Fasheh 	if (old_dir == new_dir)
4471ba9da2fSMark Fasheh 		goto out_move;
44880c05846SMark Fasheh 
44980c05846SMark Fasheh 	ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
45080c05846SMark Fasheh 
45180c05846SMark Fasheh 	dentry->d_fsdata = NULL;
4520027dd5bSMark Fasheh 	ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
45380c05846SMark Fasheh 	if (ret)
45480c05846SMark Fasheh 		mlog_errno(ret);
4551ba9da2fSMark Fasheh 
4561ba9da2fSMark Fasheh out_move:
4571ba9da2fSMark Fasheh 	d_move(dentry, target);
45880c05846SMark Fasheh }
45980c05846SMark Fasheh 
460d8fba0ffSAl Viro const struct dentry_operations ocfs2_dentry_ops = {
461ccd979bdSMark Fasheh 	.d_revalidate		= ocfs2_dentry_revalidate,
46280c05846SMark Fasheh 	.d_iput			= ocfs2_dentry_iput,
463ccd979bdSMark Fasheh };
464