2 * (C) 2001 Clemson University and The University of Chicago
4 * See COPYING in top-level directory.
8 * Implementation of dentry (directory cache) functions.
12 #include "orangefs-kernel.h"
14 /* Returns 1 if dentry can still be trusted, else 0. */
15 static int orangefs_revalidate_lookup(struct dentry
*dentry
)
17 struct dentry
*parent_dentry
= dget_parent(dentry
);
18 struct inode
*parent_inode
= parent_dentry
->d_inode
;
19 struct orangefs_inode_s
*parent
= ORANGEFS_I(parent_inode
);
20 struct inode
*inode
= dentry
->d_inode
;
21 struct orangefs_kernel_op_s
*new_op
;
25 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: attempting lookup.\n", __func__
);
27 new_op
= op_alloc(ORANGEFS_VFS_OP_LOOKUP
);
31 new_op
->upcall
.req
.lookup
.sym_follow
= ORANGEFS_LOOKUP_LINK_NO_FOLLOW
;
32 new_op
->upcall
.req
.lookup
.parent_refn
= parent
->refn
;
33 strncpy(new_op
->upcall
.req
.lookup
.d_name
,
37 gossip_debug(GOSSIP_DCACHE_DEBUG
,
38 "%s:%s:%d interrupt flag [%d]\n",
42 get_interruptible_flag(parent_inode
));
44 err
= service_operation(new_op
, "orangefs_lookup",
45 get_interruptible_flag(parent_inode
));
47 /* Positive dentry: reject if error or not the same inode. */
50 gossip_debug(GOSSIP_DCACHE_DEBUG
,
51 "%s:%s:%d lookup failure.\n",
52 __FILE__
, __func__
, __LINE__
);
55 if (!match_handle(new_op
->downcall
.resp
.lookup
.refn
.khandle
,
57 gossip_debug(GOSSIP_DCACHE_DEBUG
,
58 "%s:%s:%d no match.\n",
59 __FILE__
, __func__
, __LINE__
);
63 /* Negative dentry: reject if success or error other than ENOENT. */
65 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: negative dentry.\n",
67 if (!err
|| err
!= -ENOENT
) {
68 if (new_op
->downcall
.status
!= 0)
69 gossip_debug(GOSSIP_DCACHE_DEBUG
,
70 "%s:%s:%d lookup failure.\n",
71 __FILE__
, __func__
, __LINE__
);
83 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s:%s:%d revalidate failed\n",
84 __FILE__
, __func__
, __LINE__
);
89 * Verify that dentry is valid.
91 * Should return 1 if dentry can still be trusted, else 0.
93 static int orangefs_d_revalidate(struct dentry
*dentry
, unsigned int flags
)
97 if (flags
& LOOKUP_RCU
)
100 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s: called on dentry %p.\n",
103 /* skip root handle lookups. */
104 if (dentry
->d_inode
&& is_root_handle(dentry
->d_inode
))
108 * If this passes, the positive dentry still exists or the negative
109 * dentry still does not exist.
111 if (!orangefs_revalidate_lookup(dentry
))
114 /* We do not need to continue with negative dentries. */
115 if (!dentry
->d_inode
)
118 /* Now we must perform a getattr to validate the inode contents. */
120 ret
= orangefs_inode_check_changed(dentry
->d_inode
);
122 gossip_debug(GOSSIP_DCACHE_DEBUG
, "%s:%s:%d getattr failure.\n",
123 __FILE__
, __func__
, __LINE__
);
130 gossip_debug(GOSSIP_DCACHE_DEBUG
,
131 "%s: negative dentry or positive dentry and inode valid.\n",
136 const struct dentry_operations orangefs_dentry_operations
= {
137 .d_revalidate
= orangefs_d_revalidate
,