Blame view
fs/orangefs/dcache.c
3.58 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
5db11c21a Orangefs: kernel ... |
2 3 4 5 6 7 8 9 10 11 12 |
/* * (C) 2001 Clemson University and The University of Chicago * * See COPYING in top-level directory. */ /* * Implementation of dentry (directory cache) functions. */ #include "protocol.h" |
575e94612 Orangefs: change ... |
13 |
#include "orangefs-kernel.h" |
5db11c21a Orangefs: kernel ... |
14 15 |
/* Returns 1 if dentry can still be trusted, else 0. */ |
8bb8aefd5 OrangeFS: Change ... |
16 |
static int orangefs_revalidate_lookup(struct dentry *dentry) |
5db11c21a Orangefs: kernel ... |
17 18 19 |
{ struct dentry *parent_dentry = dget_parent(dentry); struct inode *parent_inode = parent_dentry->d_inode; |
8bb8aefd5 OrangeFS: Change ... |
20 |
struct orangefs_inode_s *parent = ORANGEFS_I(parent_inode); |
5db11c21a Orangefs: kernel ... |
21 |
struct inode *inode = dentry->d_inode; |
8bb8aefd5 OrangeFS: Change ... |
22 |
struct orangefs_kernel_op_s *new_op; |
5db11c21a Orangefs: kernel ... |
23 24 25 26 27 |
int ret = 0; int err = 0; gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup. ", __func__); |
8bb8aefd5 OrangeFS: Change ... |
28 |
new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP); |
5db11c21a Orangefs: kernel ... |
29 30 |
if (!new_op) goto out_put_parent; |
8bb8aefd5 OrangeFS: Change ... |
31 |
new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW; |
5db11c21a Orangefs: kernel ... |
32 33 34 |
new_op->upcall.req.lookup.parent_refn = parent->refn; strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name, |
6bdfb48da orangefs: use cor... |
35 |
ORANGEFS_NAME_MAX - 1); |
5db11c21a Orangefs: kernel ... |
36 37 38 39 40 41 42 43 |
gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d interrupt flag [%d] ", __FILE__, __func__, __LINE__, get_interruptible_flag(parent_inode)); |
8bb8aefd5 OrangeFS: Change ... |
44 |
err = service_operation(new_op, "orangefs_lookup", |
5db11c21a Orangefs: kernel ... |
45 |
get_interruptible_flag(parent_inode)); |
99109822f orangefs: Fix rev... |
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
/* Positive dentry: reject if error or not the same inode. */ if (inode) { if (err) { gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d lookup failure. ", __FILE__, __func__, __LINE__); goto out_drop; } if (!match_handle(new_op->downcall.resp.lookup.refn.khandle, inode)) { gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d no match. ", __FILE__, __func__, __LINE__); goto out_drop; } /* Negative dentry: reject if success or error other than ENOENT. */ } else { gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry. ", __func__); if (!err || err != -ENOENT) { if (new_op->downcall.status != 0) gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d lookup failure. ", __FILE__, __func__, __LINE__); goto out_drop; } |
5db11c21a Orangefs: kernel ... |
78 |
} |
804b1737d orangefs: don't u... |
79 |
orangefs_set_timeout(dentry); |
5db11c21a Orangefs: kernel ... |
80 81 82 83 84 85 86 |
ret = 1; out_release_op: op_release(new_op); out_put_parent: dput(parent_dentry); return ret; out_drop: |
99109822f orangefs: Fix rev... |
87 88 89 |
gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d revalidate failed ", __FILE__, __func__, __LINE__); |
5db11c21a Orangefs: kernel ... |
90 91 92 93 94 95 |
goto out_release_op; } /* * Verify that dentry is valid. * |
f987f4c28 Orangefs: don't t... |
96 |
* Should return 1 if dentry can still be trusted, else 0. |
5db11c21a Orangefs: kernel ... |
97 |
*/ |
8bb8aefd5 OrangeFS: Change ... |
98 |
static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) |
5db11c21a Orangefs: kernel ... |
99 |
{ |
99109822f orangefs: Fix rev... |
100 |
int ret; |
804b1737d orangefs: don't u... |
101 |
unsigned long time = (unsigned long) dentry->d_fsdata; |
5db11c21a Orangefs: kernel ... |
102 |
|
804b1737d orangefs: don't u... |
103 |
if (time_before(jiffies, time)) |
31b7c1ab4 orangefs: Use d_t... |
104 |
return 1; |
5db11c21a Orangefs: kernel ... |
105 106 107 108 109 110 |
if (flags & LOOKUP_RCU) return -ECHILD; gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: called on dentry %p. ", __func__, dentry); |
99109822f orangefs: Fix rev... |
111 112 113 114 115 116 117 118 |
/* skip root handle lookups. */ if (dentry->d_inode && is_root_handle(dentry->d_inode)) return 1; /* * If this passes, the positive dentry still exists or the negative * dentry still does not exist. */ |
ee70fca0b orangefs: don't d... |
119 |
if (!orangefs_revalidate_lookup(dentry)) |
99109822f orangefs: Fix rev... |
120 |
return 0; |
5db11c21a Orangefs: kernel ... |
121 |
|
99109822f orangefs: Fix rev... |
122 |
/* We do not need to continue with negative dentries. */ |
74e938c22 orangefs: reverse... |
123 124 125 126 127 128 129 |
if (!dentry->d_inode) { gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry or positive dentry and inode valid. ", __func__); return 1; } |
5db11c21a Orangefs: kernel ... |
130 |
|
99109822f orangefs: Fix rev... |
131 |
/* Now we must perform a getattr to validate the inode contents. */ |
933287da7 orangefs: Impleme... |
132 |
|
5859d77e5 orangefs: use new... |
133 |
ret = orangefs_inode_check_changed(dentry->d_inode); |
99109822f orangefs: Fix rev... |
134 135 136 137 |
if (ret < 0) { gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d getattr failure. ", __FILE__, __func__, __LINE__); |
99109822f orangefs: Fix rev... |
138 139 |
return 0; } |
74e938c22 orangefs: reverse... |
140 |
return !ret; |
5db11c21a Orangefs: kernel ... |
141 |
} |
8bb8aefd5 OrangeFS: Change ... |
142 143 |
const struct dentry_operations orangefs_dentry_operations = { .d_revalidate = orangefs_d_revalidate, |
5db11c21a Orangefs: kernel ... |
144 |
}; |