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 (!dentry->d_parent)
12880c05846SMark Fasheh return 0;
12980c05846SMark Fasheh
13080c05846SMark Fasheh if (skip_unhashed && d_unhashed(dentry))
13180c05846SMark Fasheh return 0;
13280c05846SMark Fasheh
1332b0143b5SDavid Howells parent = d_inode(dentry->d_parent);
13480c05846SMark Fasheh /* Negative parent dentry? */
13580c05846SMark Fasheh if (!parent)
13680c05846SMark Fasheh return 0;
13780c05846SMark Fasheh
13880c05846SMark Fasheh /* Name is in a different directory. */
13980c05846SMark Fasheh if (OCFS2_I(parent)->ip_blkno != parent_blkno)
14080c05846SMark Fasheh return 0;
14180c05846SMark Fasheh
14280c05846SMark Fasheh return 1;
14380c05846SMark Fasheh }
14480c05846SMark Fasheh
14580c05846SMark Fasheh /*
14680c05846SMark Fasheh * Walk the inode alias list, and find a dentry which has a given
14780c05846SMark Fasheh * parent. ocfs2_dentry_attach_lock() wants to find _any_ alias as it
14834d024f8SMark Fasheh * is looking for a dentry_lock reference. The downconvert thread is
14934d024f8SMark Fasheh * looking to unhash aliases, so we allow it to skip any that already
15034d024f8SMark Fasheh * have that property.
15180c05846SMark Fasheh */
ocfs2_find_local_alias(struct inode * inode,u64 parent_blkno,int skip_unhashed)15280c05846SMark Fasheh struct dentry *ocfs2_find_local_alias(struct inode *inode,
15380c05846SMark Fasheh u64 parent_blkno,
15480c05846SMark Fasheh int skip_unhashed)
15580c05846SMark Fasheh {
156a614a092SAl Viro struct dentry *dentry;
15780c05846SMark Fasheh
158873feea0SNick Piggin spin_lock(&inode->i_lock);
159946e51f2SAl Viro hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
160da502956SNick Piggin spin_lock(&dentry->d_lock);
16180c05846SMark Fasheh if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
162a5b8443bSTao Ma trace_ocfs2_find_local_alias(dentry->d_name.len,
163a5b8443bSTao Ma dentry->d_name.name);
16480c05846SMark Fasheh
165dc0474beSNick Piggin dget_dlock(dentry);
166da502956SNick Piggin spin_unlock(&dentry->d_lock);
167a614a092SAl Viro spin_unlock(&inode->i_lock);
168a614a092SAl Viro return dentry;
16980c05846SMark Fasheh }
170da502956SNick Piggin spin_unlock(&dentry->d_lock);
17180c05846SMark Fasheh }
172873feea0SNick Piggin spin_unlock(&inode->i_lock);
173a614a092SAl Viro return NULL;
17480c05846SMark Fasheh }
17580c05846SMark Fasheh
176d680efe9SMark Fasheh DEFINE_SPINLOCK(dentry_attach_lock);
177d680efe9SMark Fasheh
17880c05846SMark Fasheh /*
17980c05846SMark Fasheh * Attach this dentry to a cluster lock.
18080c05846SMark Fasheh *
18180c05846SMark Fasheh * Dentry locks cover all links in a given directory to a particular
18280c05846SMark Fasheh * inode. We do this so that ocfs2 can build a lock name which all
18380c05846SMark Fasheh * nodes in the cluster can agree on at all times. Shoving full names
18480c05846SMark Fasheh * in the cluster lock won't work due to size restrictions. Covering
18580c05846SMark Fasheh * links inside of a directory is a good compromise because it still
18680c05846SMark Fasheh * allows us to use the parent directory lock to synchronize
18780c05846SMark Fasheh * operations.
18880c05846SMark Fasheh *
18980c05846SMark Fasheh * Call this function with the parent dir semaphore and the parent dir
19080c05846SMark Fasheh * cluster lock held.
19180c05846SMark Fasheh *
19280c05846SMark Fasheh * The dir semaphore will protect us from having to worry about
19380c05846SMark Fasheh * concurrent processes on our node trying to attach a lock at the
19480c05846SMark Fasheh * same time.
19580c05846SMark Fasheh *
19680c05846SMark Fasheh * The dir cluster lock (held at either PR or EX mode) protects us
19780c05846SMark Fasheh * from unlink and rename on other nodes.
19880c05846SMark Fasheh *
19980c05846SMark Fasheh * A dput() can happen asynchronously due to pruning, so we cover
20080c05846SMark Fasheh * attaching and detaching the dentry lock with a
20180c05846SMark Fasheh * dentry_attach_lock.
20280c05846SMark Fasheh *
20380c05846SMark Fasheh * A node which has done lookup on a name retains a protected read
20480c05846SMark Fasheh * lock until final dput. If the user requests and unlink or rename,
20580c05846SMark Fasheh * the protected read is upgraded to an exclusive lock. Other nodes
20680c05846SMark Fasheh * who have seen the dentry will then be informed that they need to
20780c05846SMark Fasheh * downgrade their lock, which will involve d_delete on the
20880c05846SMark Fasheh * dentry. This happens in ocfs2_dentry_convert_worker().
20980c05846SMark Fasheh */
ocfs2_dentry_attach_lock(struct dentry * dentry,struct inode * inode,u64 parent_blkno)21080c05846SMark Fasheh int ocfs2_dentry_attach_lock(struct dentry *dentry,
21180c05846SMark Fasheh struct inode *inode,
2120027dd5bSMark Fasheh u64 parent_blkno)
21380c05846SMark Fasheh {
21480c05846SMark Fasheh int ret;
21580c05846SMark Fasheh struct dentry *alias;
21680c05846SMark Fasheh struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
21780c05846SMark Fasheh
218a5b8443bSTao Ma trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
2190027dd5bSMark Fasheh (unsigned long long)parent_blkno, dl);
22080c05846SMark Fasheh
22180c05846SMark Fasheh /*
22280c05846SMark Fasheh * Negative dentry. We ignore these for now.
22380c05846SMark Fasheh *
22480c05846SMark Fasheh * XXX: Could we can improve ocfs2_dentry_revalidate() by
22580c05846SMark Fasheh * tracking these?
22680c05846SMark Fasheh */
22780c05846SMark Fasheh if (!inode)
22880c05846SMark Fasheh return 0;
22980c05846SMark Fasheh
2302b0143b5SDavid Howells if (d_really_is_negative(dentry) && dentry->d_fsdata) {
2315e98d492SGoldwyn Rodrigues /* Converting a negative dentry to positive
2325e98d492SGoldwyn Rodrigues Clear dentry->d_fsdata */
2335e98d492SGoldwyn Rodrigues dentry->d_fsdata = dl = NULL;
2345e98d492SGoldwyn Rodrigues }
2355e98d492SGoldwyn Rodrigues
23680c05846SMark Fasheh if (dl) {
23780c05846SMark Fasheh mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
238a455589fSAl Viro " \"%pd\": old parent: %llu, new: %llu\n",
239a455589fSAl Viro dentry,
24080c05846SMark Fasheh (unsigned long long)parent_blkno,
24180c05846SMark Fasheh (unsigned long long)dl->dl_parent_blkno);
24280c05846SMark Fasheh return 0;
24380c05846SMark Fasheh }
24480c05846SMark Fasheh
24580c05846SMark Fasheh alias = ocfs2_find_local_alias(inode, parent_blkno, 0);
24680c05846SMark Fasheh if (alias) {
24780c05846SMark Fasheh /*
24880c05846SMark Fasheh * Great, an alias exists, which means we must have a
24980c05846SMark Fasheh * dentry lock already. We can just grab the lock off
25080c05846SMark Fasheh * the alias and add it to the list.
25180c05846SMark Fasheh *
25280c05846SMark Fasheh * We're depending here on the fact that this dentry
25380c05846SMark Fasheh * was found and exists in the dcache and so must have
25480c05846SMark Fasheh * a reference to the dentry_lock because we can't
25580c05846SMark Fasheh * race creates. Final dput() cannot happen on it
25680c05846SMark Fasheh * since we have it pinned, so our reference is safe.
25780c05846SMark Fasheh */
25880c05846SMark Fasheh dl = alias->d_fsdata;
2590027dd5bSMark Fasheh mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
26080c05846SMark Fasheh (unsigned long long)parent_blkno,
2610027dd5bSMark Fasheh (unsigned long long)OCFS2_I(inode)->ip_blkno);
26280c05846SMark Fasheh
26380c05846SMark Fasheh mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
264a455589fSAl Viro " \"%pd\": old parent: %llu, new: %llu\n",
265a455589fSAl Viro dentry,
26680c05846SMark Fasheh (unsigned long long)parent_blkno,
26780c05846SMark Fasheh (unsigned long long)dl->dl_parent_blkno);
26880c05846SMark Fasheh
269a5b8443bSTao Ma trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
270a5b8443bSTao Ma (unsigned long long)parent_blkno,
271a5b8443bSTao Ma (unsigned long long)OCFS2_I(inode)->ip_blkno);
27280c05846SMark Fasheh
27380c05846SMark Fasheh goto out_attach;
27480c05846SMark Fasheh }
27580c05846SMark Fasheh
27680c05846SMark Fasheh /*
27780c05846SMark Fasheh * There are no other aliases
27880c05846SMark Fasheh */
27980c05846SMark Fasheh dl = kmalloc(sizeof(*dl), GFP_NOFS);
28080c05846SMark Fasheh if (!dl) {
28180c05846SMark Fasheh ret = -ENOMEM;
28280c05846SMark Fasheh mlog_errno(ret);
28380c05846SMark Fasheh return ret;
28480c05846SMark Fasheh }
28580c05846SMark Fasheh
28680c05846SMark Fasheh dl->dl_count = 0;
28780c05846SMark Fasheh /*
28880c05846SMark Fasheh * Does this have to happen below, for all attaches, in case
28934d024f8SMark Fasheh * the struct inode gets blown away by the downconvert thread?
29080c05846SMark Fasheh */
29180c05846SMark Fasheh dl->dl_inode = igrab(inode);
29280c05846SMark Fasheh dl->dl_parent_blkno = parent_blkno;
29380c05846SMark Fasheh ocfs2_dentry_lock_res_init(dl, parent_blkno, inode);
29480c05846SMark Fasheh
29580c05846SMark Fasheh out_attach:
29680c05846SMark Fasheh spin_lock(&dentry_attach_lock);
297be99ca27SWengang Wang if (unlikely(dentry->d_fsdata && !alias)) {
298be99ca27SWengang Wang /* d_fsdata is set by a racing thread which is doing
299be99ca27SWengang Wang * the same thing as this thread is doing. Leave the racing
300be99ca27SWengang Wang * thread going ahead and we return here.
301be99ca27SWengang Wang */
302be99ca27SWengang Wang spin_unlock(&dentry_attach_lock);
303be99ca27SWengang Wang iput(dl->dl_inode);
304be99ca27SWengang Wang ocfs2_lock_res_free(&dl->dl_lockres);
305be99ca27SWengang Wang kfree(dl);
306be99ca27SWengang Wang return 0;
307be99ca27SWengang Wang }
308be99ca27SWengang Wang
30980c05846SMark Fasheh dentry->d_fsdata = dl;
31080c05846SMark Fasheh dl->dl_count++;
31180c05846SMark Fasheh spin_unlock(&dentry_attach_lock);
31280c05846SMark Fasheh
31380c05846SMark Fasheh /*
31480c05846SMark Fasheh * This actually gets us our PRMODE level lock. From now on,
31580c05846SMark Fasheh * we'll have a notification if one of these names is
31680c05846SMark Fasheh * destroyed on another node.
31780c05846SMark Fasheh */
31880c05846SMark Fasheh ret = ocfs2_dentry_lock(dentry, 0);
3190027dd5bSMark Fasheh if (!ret)
32080c05846SMark Fasheh ocfs2_dentry_unlock(dentry, 0);
3210027dd5bSMark Fasheh else
3220027dd5bSMark Fasheh mlog_errno(ret);
32380c05846SMark Fasheh
324a5a0a630SSunil Mushran /*
325a5a0a630SSunil Mushran * In case of error, manually free the allocation and do the iput().
326a5a0a630SSunil Mushran * We need to do this because error here means no d_instantiate(),
327a5a0a630SSunil Mushran * which means iput() will not be called during dput(dentry).
328a5a0a630SSunil Mushran */
329a5a0a630SSunil Mushran if (ret < 0 && !alias) {
330a5a0a630SSunil Mushran ocfs2_lock_res_free(&dl->dl_lockres);
331a5a0a630SSunil Mushran BUG_ON(dl->dl_count != 1);
332a5a0a630SSunil Mushran spin_lock(&dentry_attach_lock);
333a5a0a630SSunil Mushran dentry->d_fsdata = NULL;
334a5a0a630SSunil Mushran spin_unlock(&dentry_attach_lock);
335a5a0a630SSunil Mushran kfree(dl);
336a5a0a630SSunil Mushran iput(inode);
337a5a0a630SSunil Mushran }
338a5a0a630SSunil Mushran
33980c05846SMark Fasheh dput(alias);
34080c05846SMark Fasheh
34180c05846SMark Fasheh return ret;
34280c05846SMark Fasheh }
34380c05846SMark Fasheh
34480c05846SMark Fasheh /*
34580c05846SMark Fasheh * ocfs2_dentry_iput() and friends.
34680c05846SMark Fasheh *
34780c05846SMark Fasheh * At this point, our particular dentry is detached from the inodes
34880c05846SMark Fasheh * alias list, so there's no way that the locking code can find it.
34980c05846SMark Fasheh *
35080c05846SMark Fasheh * The interesting stuff happens when we determine that our lock needs
35180c05846SMark Fasheh * to go away because this is the last subdir alias in the
35280c05846SMark Fasheh * system. This function needs to handle a couple things:
35380c05846SMark Fasheh *
35480c05846SMark Fasheh * 1) Synchronizing lock shutdown with the downconvert threads. This
35580c05846SMark Fasheh * is already handled for us via the lockres release drop function
35680c05846SMark Fasheh * called in ocfs2_release_dentry_lock()
35780c05846SMark Fasheh *
35880c05846SMark Fasheh * 2) A race may occur when we're doing our lock shutdown and
35980c05846SMark Fasheh * another process wants to create a new dentry lock. Right now we
36080c05846SMark Fasheh * let them race, which means that for a very short while, this
36180c05846SMark Fasheh * node might have two locks on a lock resource. This should be a
36280c05846SMark Fasheh * problem though because one of them is in the process of being
36380c05846SMark Fasheh * thrown out.
36480c05846SMark Fasheh */
ocfs2_drop_dentry_lock(struct ocfs2_super * osb,struct ocfs2_dentry_lock * dl)36580c05846SMark Fasheh static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
36680c05846SMark Fasheh struct ocfs2_dentry_lock *dl)
36780c05846SMark Fasheh {
3688ed6b237SGoldwyn Rodrigues iput(dl->dl_inode);
36980c05846SMark Fasheh ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
37080c05846SMark Fasheh ocfs2_lock_res_free(&dl->dl_lockres);
3718ed6b237SGoldwyn Rodrigues kfree(dl);
37280c05846SMark Fasheh }
37380c05846SMark Fasheh
ocfs2_dentry_lock_put(struct ocfs2_super * osb,struct ocfs2_dentry_lock * dl)37480c05846SMark Fasheh void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
37580c05846SMark Fasheh struct ocfs2_dentry_lock *dl)
37680c05846SMark Fasheh {
3778ed6b237SGoldwyn Rodrigues int unlock = 0;
37880c05846SMark Fasheh
37980c05846SMark Fasheh BUG_ON(dl->dl_count == 0);
38080c05846SMark Fasheh
38180c05846SMark Fasheh spin_lock(&dentry_attach_lock);
38280c05846SMark Fasheh dl->dl_count--;
38380c05846SMark Fasheh unlock = !dl->dl_count;
38480c05846SMark Fasheh spin_unlock(&dentry_attach_lock);
38580c05846SMark Fasheh
38680c05846SMark Fasheh if (unlock)
38780c05846SMark Fasheh ocfs2_drop_dentry_lock(osb, dl);
38880c05846SMark Fasheh }
38980c05846SMark Fasheh
ocfs2_dentry_iput(struct dentry * dentry,struct inode * inode)39080c05846SMark Fasheh static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
39180c05846SMark Fasheh {
39280c05846SMark Fasheh struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
39380c05846SMark Fasheh
394bccb9dadSMark Fasheh if (!dl) {
395bccb9dadSMark Fasheh /*
396bccb9dadSMark Fasheh * No dentry lock is ok if we're disconnected or
397bccb9dadSMark Fasheh * unhashed.
398bccb9dadSMark Fasheh */
399bccb9dadSMark Fasheh if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
400bccb9dadSMark Fasheh !d_unhashed(dentry)) {
401bccb9dadSMark Fasheh unsigned long long ino = 0ULL;
402bccb9dadSMark Fasheh if (inode)
403bccb9dadSMark Fasheh ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
404bccb9dadSMark Fasheh mlog(ML_ERROR, "Dentry is missing cluster lock. "
405a455589fSAl Viro "inode: %llu, d_flags: 0x%x, d_name: %pd\n",
406a455589fSAl Viro ino, dentry->d_flags, dentry);
407bccb9dadSMark Fasheh }
40880c05846SMark Fasheh
40980c05846SMark Fasheh goto out;
410bccb9dadSMark Fasheh }
41180c05846SMark Fasheh
412a455589fSAl Viro mlog_bug_on_msg(dl->dl_count == 0, "dentry: %pd, count: %u\n",
413a455589fSAl Viro dentry, dl->dl_count);
41480c05846SMark Fasheh
41580c05846SMark Fasheh ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl);
41680c05846SMark Fasheh
41780c05846SMark Fasheh out:
41880c05846SMark Fasheh iput(inode);
41980c05846SMark Fasheh }
42080c05846SMark Fasheh
42180c05846SMark Fasheh /*
42280c05846SMark Fasheh * d_move(), but keep the locks in sync.
42380c05846SMark Fasheh *
42480c05846SMark Fasheh * When we are done, "dentry" will have the parent dir and name of
42580c05846SMark Fasheh * "target", which will be thrown away.
42680c05846SMark Fasheh *
42780c05846SMark Fasheh * We manually update the lock of "dentry" if need be.
42880c05846SMark Fasheh *
42980c05846SMark Fasheh * "target" doesn't have it's dentry lock touched - we allow the later
43080c05846SMark Fasheh * dput() to handle this for us.
43180c05846SMark Fasheh *
43280c05846SMark Fasheh * This is called during ocfs2_rename(), while holding parent
43380c05846SMark Fasheh * directory locks. The dentries have already been deleted on other
43480c05846SMark Fasheh * nodes via ocfs2_remote_dentry_delete().
43580c05846SMark Fasheh *
4363a4fa0a2SRobert P. J. Day * Normally, the VFS handles the d_move() for the file system, after
43780c05846SMark Fasheh * the ->rename() callback. OCFS2 wants to handle this internally, so
43880c05846SMark Fasheh * the new lock can be created atomically with respect to the cluster.
43980c05846SMark Fasheh */
ocfs2_dentry_move(struct dentry * dentry,struct dentry * target,struct inode * old_dir,struct inode * new_dir)44080c05846SMark Fasheh void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
44180c05846SMark Fasheh struct inode *old_dir, struct inode *new_dir)
44280c05846SMark Fasheh {
44380c05846SMark Fasheh int ret;
44480c05846SMark Fasheh struct ocfs2_super *osb = OCFS2_SB(old_dir->i_sb);
4452b0143b5SDavid Howells struct inode *inode = d_inode(dentry);
44680c05846SMark Fasheh
44780c05846SMark Fasheh /*
44880c05846SMark Fasheh * Move within the same directory, so the actual lock info won't
44980c05846SMark Fasheh * change.
45080c05846SMark Fasheh *
45180c05846SMark Fasheh * XXX: Is there any advantage to dropping the lock here?
45280c05846SMark Fasheh */
45380c05846SMark Fasheh if (old_dir == new_dir)
4541ba9da2fSMark Fasheh goto out_move;
45580c05846SMark Fasheh
45680c05846SMark Fasheh ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
45780c05846SMark Fasheh
45880c05846SMark Fasheh dentry->d_fsdata = NULL;
4590027dd5bSMark Fasheh ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
46080c05846SMark Fasheh if (ret)
46180c05846SMark Fasheh mlog_errno(ret);
4621ba9da2fSMark Fasheh
4631ba9da2fSMark Fasheh out_move:
4641ba9da2fSMark Fasheh d_move(dentry, target);
46580c05846SMark Fasheh }
46680c05846SMark Fasheh
467d8fba0ffSAl Viro const struct dentry_operations ocfs2_dentry_ops = {
468ccd979bdSMark Fasheh .d_revalidate = ocfs2_dentry_revalidate,
46980c05846SMark Fasheh .d_iput = ocfs2_dentry_iput,
470ccd979bdSMark Fasheh };
471