0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "protocol.h"
0013 #include "orangefs-kernel.h"
0014
0015
0016 static int orangefs_revalidate_lookup(struct dentry *dentry)
0017 {
0018 struct dentry *parent_dentry = dget_parent(dentry);
0019 struct inode *parent_inode = parent_dentry->d_inode;
0020 struct orangefs_inode_s *parent = ORANGEFS_I(parent_inode);
0021 struct inode *inode = dentry->d_inode;
0022 struct orangefs_kernel_op_s *new_op;
0023 int ret = 0;
0024 int err = 0;
0025
0026 gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup.\n", __func__);
0027
0028 new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP);
0029 if (!new_op) {
0030 ret = -ENOMEM;
0031 goto out_put_parent;
0032 }
0033
0034 new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW;
0035 new_op->upcall.req.lookup.parent_refn = parent->refn;
0036 strncpy(new_op->upcall.req.lookup.d_name,
0037 dentry->d_name.name,
0038 ORANGEFS_NAME_MAX - 1);
0039
0040 gossip_debug(GOSSIP_DCACHE_DEBUG,
0041 "%s:%s:%d interrupt flag [%d]\n",
0042 __FILE__,
0043 __func__,
0044 __LINE__,
0045 get_interruptible_flag(parent_inode));
0046
0047 err = service_operation(new_op, "orangefs_lookup",
0048 get_interruptible_flag(parent_inode));
0049
0050
0051 if (inode) {
0052 if (err) {
0053 gossip_debug(GOSSIP_DCACHE_DEBUG,
0054 "%s:%s:%d lookup failure.\n",
0055 __FILE__, __func__, __LINE__);
0056 goto out_drop;
0057 }
0058 if (!match_handle(new_op->downcall.resp.lookup.refn.khandle,
0059 inode)) {
0060 gossip_debug(GOSSIP_DCACHE_DEBUG,
0061 "%s:%s:%d no match.\n",
0062 __FILE__, __func__, __LINE__);
0063 goto out_drop;
0064 }
0065
0066
0067 } else {
0068 gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry.\n",
0069 __func__);
0070 if (!err || err != -ENOENT) {
0071 if (new_op->downcall.status != 0)
0072 gossip_debug(GOSSIP_DCACHE_DEBUG,
0073 "%s:%s:%d lookup failure.\n",
0074 __FILE__, __func__, __LINE__);
0075 goto out_drop;
0076 }
0077 }
0078
0079 orangefs_set_timeout(dentry);
0080 ret = 1;
0081 out_release_op:
0082 op_release(new_op);
0083 out_put_parent:
0084 dput(parent_dentry);
0085 return ret;
0086 out_drop:
0087 gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d revalidate failed\n",
0088 __FILE__, __func__, __LINE__);
0089 goto out_release_op;
0090 }
0091
0092
0093
0094
0095
0096
0097 static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags)
0098 {
0099 int ret;
0100 unsigned long time = (unsigned long) dentry->d_fsdata;
0101
0102 if (time_before(jiffies, time))
0103 return 1;
0104
0105 if (flags & LOOKUP_RCU)
0106 return -ECHILD;
0107
0108 gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: called on dentry %p.\n",
0109 __func__, dentry);
0110
0111
0112 if (dentry->d_inode && is_root_handle(dentry->d_inode))
0113 return 1;
0114
0115
0116
0117
0118
0119 if (!orangefs_revalidate_lookup(dentry))
0120 return 0;
0121
0122
0123 if (!dentry->d_inode) {
0124 gossip_debug(GOSSIP_DCACHE_DEBUG,
0125 "%s: negative dentry or positive dentry and inode valid.\n",
0126 __func__);
0127 return 1;
0128 }
0129
0130
0131
0132 ret = orangefs_inode_check_changed(dentry->d_inode);
0133 if (ret < 0) {
0134 gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d getattr failure.\n",
0135 __FILE__, __func__, __LINE__);
0136 return 0;
0137 }
0138 return !ret;
0139 }
0140
0141 const struct dentry_operations orangefs_dentry_operations = {
0142 .d_revalidate = orangefs_d_revalidate,
0143 };