Blame view

fs/orangefs/dcache.c 3.58 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
5db11c21a   Mike Marshall   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   Mike Marshall   Orangefs: change ...
13
  #include "orangefs-kernel.h"
5db11c21a   Mike Marshall   Orangefs: kernel ...
14
15
  
  /* Returns 1 if dentry can still be trusted, else 0. */
8bb8aefd5   Yi Liu   OrangeFS: Change ...
16
  static int orangefs_revalidate_lookup(struct dentry *dentry)
5db11c21a   Mike Marshall   Orangefs: kernel ...
17
18
19
  {
  	struct dentry *parent_dentry = dget_parent(dentry);
  	struct inode *parent_inode = parent_dentry->d_inode;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
20
  	struct orangefs_inode_s *parent = ORANGEFS_I(parent_inode);
5db11c21a   Mike Marshall   Orangefs: kernel ...
21
  	struct inode *inode = dentry->d_inode;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
22
  	struct orangefs_kernel_op_s *new_op;
5db11c21a   Mike Marshall   Orangefs: kernel ...
23
24
25
26
27
  	int ret = 0;
  	int err = 0;
  
  	gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup.
  ", __func__);
8bb8aefd5   Yi Liu   OrangeFS: Change ...
28
  	new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP);
5db11c21a   Mike Marshall   Orangefs: kernel ...
29
30
  	if (!new_op)
  		goto out_put_parent;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
31
  	new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW;
5db11c21a   Mike Marshall   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   Xiongfeng Wang   orangefs: use cor...
35
  		ORANGEFS_NAME_MAX - 1);
5db11c21a   Mike Marshall   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   Yi Liu   OrangeFS: Change ...
44
  	err = service_operation(new_op, "orangefs_lookup",
5db11c21a   Mike Marshall   Orangefs: kernel ...
45
  			get_interruptible_flag(parent_inode));
99109822f   Martin Brandenburg   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   Mike Marshall   Orangefs: kernel ...
78
  	}
804b1737d   Miklos Szeredi   orangefs: don't u...
79
  	orangefs_set_timeout(dentry);
5db11c21a   Mike Marshall   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   Martin Brandenburg   orangefs: Fix rev...
87
88
89
  	gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d revalidate failed
  ",
  	    __FILE__, __func__, __LINE__);
5db11c21a   Mike Marshall   Orangefs: kernel ...
90
91
92
93
94
95
  	goto out_release_op;
  }
  
  /*
   * Verify that dentry is valid.
   *
f987f4c28   Mike Marshall   Orangefs: don't t...
96
   * Should return 1 if dentry can still be trusted, else 0.
5db11c21a   Mike Marshall   Orangefs: kernel ...
97
   */
8bb8aefd5   Yi Liu   OrangeFS: Change ...
98
  static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags)
5db11c21a   Mike Marshall   Orangefs: kernel ...
99
  {
99109822f   Martin Brandenburg   orangefs: Fix rev...
100
  	int ret;
804b1737d   Miklos Szeredi   orangefs: don't u...
101
  	unsigned long time = (unsigned long) dentry->d_fsdata;
5db11c21a   Mike Marshall   Orangefs: kernel ...
102

804b1737d   Miklos Szeredi   orangefs: don't u...
103
  	if (time_before(jiffies, time))
31b7c1ab4   Martin Brandenburg   orangefs: Use d_t...
104
  		return 1;
5db11c21a   Mike Marshall   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   Martin Brandenburg   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   Martin Brandenburg   orangefs: don't d...
119
  	if (!orangefs_revalidate_lookup(dentry))
99109822f   Martin Brandenburg   orangefs: Fix rev...
120
  		return 0;
5db11c21a   Mike Marshall   Orangefs: kernel ...
121

99109822f   Martin Brandenburg   orangefs: Fix rev...
122
  	/* We do not need to continue with negative dentries. */
74e938c22   Martin Brandenburg   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   Mike Marshall   Orangefs: kernel ...
130

99109822f   Martin Brandenburg   orangefs: Fix rev...
131
  	/* Now we must perform a getattr to validate the inode contents. */
933287da7   Martin Brandenburg   orangefs: Impleme...
132

5859d77e5   Martin Brandenburg   orangefs: use new...
133
  	ret = orangefs_inode_check_changed(dentry->d_inode);
99109822f   Martin Brandenburg   orangefs: Fix rev...
134
135
136
137
  	if (ret < 0) {
  		gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d getattr failure.
  ",
  		    __FILE__, __func__, __LINE__);
99109822f   Martin Brandenburg   orangefs: Fix rev...
138
139
  		return 0;
  	}
74e938c22   Martin Brandenburg   orangefs: reverse...
140
  	return !ret;
5db11c21a   Mike Marshall   Orangefs: kernel ...
141
  }
8bb8aefd5   Yi Liu   OrangeFS: Change ...
142
143
  const struct dentry_operations orangefs_dentry_operations = {
  	.d_revalidate = orangefs_d_revalidate,
5db11c21a   Mike Marshall   Orangefs: kernel ...
144
  };