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
);
34 new_op
->upcall
.req
.lookup
.sym_follow
= ORANGEFS_LOOKUP_LINK_NO_FOLLOW
;
35 new_op
->upcall
.req
.lookup
.parent_refn
= parent
->refn
;
36 strncpy(new_op
->upcall
.req
.lookup
.d_name
,
38 ORANGEFS_NAME_MAX
- 1);
40 gossip_debug(GOSSIP_DCACHE_DEBUG
,
41 "%s:%s:%d interrupt flag [%d]\n",
45 get_interruptible_flag(parent_inode
));
47 err
= service_operation(new_op
, "orangefs_lookup",
48 get_interruptible_flag(parent_inode
));
50 /* Positive dentry: reject if error or not the same inode. */
53 gossip_debug(GOSSIP_DCACHE_DEBUG
,
54 "%s:%s:%d lookup failure.\n",
55 __FILE__
, __func__
, __LINE__
);
58 if (!match_handle(new_op
->downcall
.resp
.lookup
.refn
.khandle
,
60 gossip_debug(GOSSIP_DCACHE_DEBUG
,
61 "%s:%s:%d no match.\n",
62 __FILE__
, __func__
, __LINE__
);
66 /* Negative dentry: reject if success or error other than ENOENT. */
68 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: negative dentry.\n",
70 if (!err
|| err
!= -ENOENT
) {
71 if (new_op
->downcall
.status
!= 0)
72 gossip_debug(GOSSIP_DCACHE_DEBUG
,
73 "%s:%s:%d lookup failure.\n",
74 __FILE__
, __func__
, __LINE__
);
79 orangefs_set_timeout(dentry
);
87 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s:%s:%d revalidate failed\n",
88 __FILE__
, __func__
, __LINE__
);
93 * Verify that dentry is valid.
95 * Should return 1 if dentry can still be trusted, else 0.
97 static int orangefs_d_revalidate(struct dentry
*dentry
, unsigned int flags
)
100 unsigned long time
= (unsigned long) dentry
->d_fsdata
;
102 if (time_before(jiffies
, time
))
105 if (flags
& LOOKUP_RCU
)
108 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: called on dentry %p.\n",
111 /* skip root handle lookups. */
112 if (dentry
->d_inode
&& is_root_handle(dentry
->d_inode
))
116 * If this passes, the positive dentry still exists or the negative
117 * dentry still does not exist.
119 if (!orangefs_revalidate_lookup(dentry
))
122 /* We do not need to continue with negative dentries. */
123 if (!dentry
->d_inode
) {
124 gossip_debug(GOSSIP_DCACHE_DEBUG
,
125 "%s: negative dentry or positive dentry and inode valid.\n",
130 /* Now we must perform a getattr to validate the inode contents. */
132 ret
= orangefs_inode_check_changed(dentry
->d_inode
);
134 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s:%s:%d getattr failure.\n",
135 __FILE__
, __func__
, __LINE__
);
141 const struct dentry_operations orangefs_dentry_operations
= {
142 .d_revalidate
= orangefs_d_revalidate
,