1 // SPDX-License-Identifier: GPL-2.0
3 * (C) 2001 Clemson University and The University of Chicago
5 * See COPYING in top-level directory.
9 * Implementation of dentry (directory cache) functions.
13 #include "orangefs-kernel.h"
15 /* Returns 1 if dentry can still be trusted, else 0. */
16 static int orangefs_revalidate_lookup(struct dentry
*dentry
)
18 struct dentry
*parent_dentry
= dget_parent(dentry
);
19 struct inode
*parent_inode
= parent_dentry
->d_inode
;
20 struct orangefs_inode_s
*parent
= ORANGEFS_I(parent_inode
);
21 struct inode
*inode
= dentry
->d_inode
;
22 struct orangefs_kernel_op_s
*new_op
;
26 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: attempting lookup.\n", __func__
);
28 new_op
= op_alloc(ORANGEFS_VFS_OP_LOOKUP
);
32 new_op
->upcall
.req
.lookup
.sym_follow
= ORANGEFS_LOOKUP_LINK_NO_FOLLOW
;
33 new_op
->upcall
.req
.lookup
.parent_refn
= parent
->refn
;
34 strncpy(new_op
->upcall
.req
.lookup
.d_name
,
38 gossip_debug(GOSSIP_DCACHE_DEBUG
,
39 "%s:%s:%d interrupt flag [%d]\n",
43 get_interruptible_flag(parent_inode
));
45 err
= service_operation(new_op
, "orangefs_lookup",
46 get_interruptible_flag(parent_inode
));
48 /* Positive dentry: reject if error or not the same inode. */
51 gossip_debug(GOSSIP_DCACHE_DEBUG
,
52 "%s:%s:%d lookup failure.\n",
53 __FILE__
, __func__
, __LINE__
);
56 if (!match_handle(new_op
->downcall
.resp
.lookup
.refn
.khandle
,
58 gossip_debug(GOSSIP_DCACHE_DEBUG
,
59 "%s:%s:%d no match.\n",
60 __FILE__
, __func__
, __LINE__
);
64 /* Negative dentry: reject if success or error other than ENOENT. */
66 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: negative dentry.\n",
68 if (!err
|| err
!= -ENOENT
) {
69 if (new_op
->downcall
.status
!= 0)
70 gossip_debug(GOSSIP_DCACHE_DEBUG
,
71 "%s:%s:%d lookup failure.\n",
72 __FILE__
, __func__
, __LINE__
);
77 orangefs_set_timeout(dentry
);
85 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s:%s:%d revalidate failed\n",
86 __FILE__
, __func__
, __LINE__
);
91 * Verify that dentry is valid.
93 * Should return 1 if dentry can still be trusted, else 0.
95 static int orangefs_d_revalidate(struct dentry
*dentry
, unsigned int flags
)
98 unsigned long time
= (unsigned long) dentry
->d_fsdata
;
100 if (time_before(jiffies
, time
))
103 if (flags
& LOOKUP_RCU
)
106 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: called on dentry %p.\n",
109 /* skip root handle lookups. */
110 if (dentry
->d_inode
&& is_root_handle(dentry
->d_inode
))
114 * If this passes, the positive dentry still exists or the negative
115 * dentry still does not exist.
117 if (!orangefs_revalidate_lookup(dentry
))
120 /* We do not need to continue with negative dentries. */
121 if (!dentry
->d_inode
)
124 /* Now we must perform a getattr to validate the inode contents. */
126 ret
= orangefs_inode_check_changed(dentry
->d_inode
);
128 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s:%s:%d getattr failure.\n",
129 __FILE__
, __func__
, __LINE__
);
136 gossip_debug(GOSSIP_DCACHE_DEBUG
,
137 "%s: negative dentry or positive dentry and inode valid.\n",
142 const struct dentry_operations orangefs_dentry_operations
= {
143 .d_revalidate
= orangefs_d_revalidate
,