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