]>
Commit | Line | Data |
---|---|---|
d7e09d03 PT |
1 | /* |
2 | * GPL HEADER START | |
3 | * | |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 only, | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License version 2 for more details (a copy is included | |
14 | * in the LICENSE file that accompanied this code). | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * version 2 along with this program; If not, see | |
6a5b99a4 | 18 | * http://www.gnu.org/licenses/gpl-2.0.html |
d7e09d03 | 19 | * |
d7e09d03 PT |
20 | * GPL HEADER END |
21 | */ | |
22 | /* | |
23 | * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | * | |
1dc563a6 | 26 | * Copyright (c) 2011, 2015, Intel Corporation. |
d7e09d03 PT |
27 | */ |
28 | /* | |
29 | * This file is part of Lustre, http://www.lustre.org/ | |
30 | * Lustre is a trademark of Sun Microsystems, Inc. | |
31 | */ | |
32 | ||
33 | #include <linux/fs.h> | |
34 | #include <linux/sched.h> | |
35 | #include <linux/quotaops.h> | |
36 | ||
37 | #define DEBUG_SUBSYSTEM S_LLITE | |
38 | ||
67a235f5 | 39 | #include "../include/obd_support.h" |
67a235f5 GKH |
40 | #include "../include/lustre/lustre_idl.h" |
41 | #include "../include/lustre_dlm.h" | |
d7e09d03 PT |
42 | |
43 | #include "llite_internal.h" | |
44 | ||
45 | static void free_dentry_data(struct rcu_head *head) | |
46 | { | |
47 | struct ll_dentry_data *lld; | |
48 | ||
49 | lld = container_of(head, struct ll_dentry_data, lld_rcu_head); | |
97903a26 | 50 | kfree(lld); |
d7e09d03 PT |
51 | } |
52 | ||
53 | /* should NOT be called with the dcache lock, see fs/dcache.c */ | |
54 | static void ll_release(struct dentry *de) | |
55 | { | |
56 | struct ll_dentry_data *lld; | |
29aaf496 | 57 | |
6e16818b | 58 | LASSERT(de); |
d7e09d03 | 59 | lld = ll_d2d(de); |
d7e09d03 PT |
60 | if (lld->lld_it) { |
61 | ll_intent_release(lld->lld_it); | |
97903a26 | 62 | kfree(lld->lld_it); |
d7e09d03 | 63 | } |
2d95f10e | 64 | |
d7e09d03 PT |
65 | de->d_fsdata = NULL; |
66 | call_rcu(&lld->lld_rcu_head, free_dentry_data); | |
d7e09d03 PT |
67 | } |
68 | ||
69 | /* Compare if two dentries are the same. Don't match if the existing dentry | |
70 | * is marked invalid. Returns 1 if different, 0 if the same. | |
71 | * | |
72 | * This avoids a race where ll_lookup_it() instantiates a dentry, but we get | |
73 | * an AST before calling d_revalidate_it(). The dentry still exists (marked | |
74 | * INVALID) so d_lookup() matches it, but we have no lock on it (so | |
c0894c6c OD |
75 | * lock_match() fails) and we spin around real_lookup(). |
76 | */ | |
6fa67e70 | 77 | static int ll_dcompare(const struct dentry *dentry, |
2d95f10e JH |
78 | unsigned int len, const char *str, |
79 | const struct qstr *name) | |
d7e09d03 | 80 | { |
d7e09d03 | 81 | if (len != name->len) |
0a3bdb00 | 82 | return 1; |
d7e09d03 PT |
83 | |
84 | if (memcmp(str, name->name, len)) | |
0a3bdb00 | 85 | return 1; |
d7e09d03 PT |
86 | |
87 | CDEBUG(D_DENTRY, "found name %.*s(%p) flags %#x refc %d\n", | |
88 | name->len, name->name, dentry, dentry->d_flags, | |
193deee1 | 89 | d_count(dentry)); |
d7e09d03 PT |
90 | |
91 | /* mountpoint is always valid */ | |
92 | if (d_mountpoint((struct dentry *)dentry)) | |
0a3bdb00 | 93 | return 0; |
d7e09d03 PT |
94 | |
95 | if (d_lustre_invalid(dentry)) | |
0a3bdb00 | 96 | return 1; |
d7e09d03 | 97 | |
0a3bdb00 | 98 | return 0; |
d7e09d03 PT |
99 | } |
100 | ||
d7e09d03 PT |
101 | /** |
102 | * Called when last reference to a dentry is dropped and dcache wants to know | |
103 | * whether or not it should cache it: | |
104 | * - return 1 to delete the dentry immediately | |
105 | * - return 0 to cache the dentry | |
106 | * Should NOT be called with the dcache lock, see fs/dcache.c | |
107 | */ | |
108 | static int ll_ddelete(const struct dentry *de) | |
109 | { | |
d7e09d03 PT |
110 | LASSERT(de); |
111 | ||
09561a53 | 112 | CDEBUG(D_DENTRY, "%s dentry %pd (%p, parent %p, inode %p) %s%s\n", |
d7e09d03 | 113 | d_lustre_invalid((struct dentry *)de) ? "deleting" : "keeping", |
2b0143b5 | 114 | de, de, de->d_parent, d_inode(de), |
09561a53 | 115 | d_unhashed(de) ? "" : "hashed,", |
d7e09d03 PT |
116 | list_empty(&de->d_subdirs) ? "" : "subdirs"); |
117 | ||
118 | /* kernel >= 2.6.38 last refcount is decreased after this function. */ | |
193deee1 | 119 | LASSERT(d_count(de) == 1); |
d7e09d03 | 120 | |
d7e09d03 | 121 | if (d_lustre_invalid((struct dentry *)de)) |
0a3bdb00 GKH |
122 | return 1; |
123 | return 0; | |
d7e09d03 PT |
124 | } |
125 | ||
7126bc2e | 126 | static int ll_d_init(struct dentry *de) |
d7e09d03 | 127 | { |
7126bc2e | 128 | struct ll_dentry_data *lld = kzalloc(sizeof(*lld), GFP_KERNEL); |
d9f5af4a | 129 | |
7126bc2e AV |
130 | if (unlikely(!lld)) |
131 | return -ENOMEM; | |
132 | lld->lld_invalid = 1; | |
133 | de->d_fsdata = lld; | |
0a3bdb00 | 134 | return 0; |
d7e09d03 PT |
135 | } |
136 | ||
d7e09d03 PT |
137 | void ll_intent_drop_lock(struct lookup_intent *it) |
138 | { | |
e476f2e5 | 139 | if (it->it_op && it->it_lock_mode) { |
d7e09d03 PT |
140 | struct lustre_handle handle; |
141 | ||
e476f2e5 | 142 | handle.cookie = it->it_lock_handle; |
d7e09d03 | 143 | |
55f5a824 GKH |
144 | CDEBUG(D_DLMTRACE, "releasing lock with cookie %#llx from it %p\n", |
145 | handle.cookie, it); | |
e476f2e5 | 146 | ldlm_lock_decref(&handle, it->it_lock_mode); |
d7e09d03 PT |
147 | |
148 | /* bug 494: intent_release may be called multiple times, from | |
c0894c6c OD |
149 | * this thread and we don't want to double-decref this lock |
150 | */ | |
e476f2e5 JH |
151 | it->it_lock_mode = 0; |
152 | if (it->it_remote_lock_mode != 0) { | |
153 | handle.cookie = it->it_remote_lock_handle; | |
d7e09d03 | 154 | |
55f5a824 GKH |
155 | CDEBUG(D_DLMTRACE, "releasing remote lock with cookie%#llx from it %p\n", |
156 | handle.cookie, it); | |
d7e09d03 | 157 | ldlm_lock_decref(&handle, |
e476f2e5 JH |
158 | it->it_remote_lock_mode); |
159 | it->it_remote_lock_mode = 0; | |
d7e09d03 PT |
160 | } |
161 | } | |
162 | } | |
163 | ||
164 | void ll_intent_release(struct lookup_intent *it) | |
165 | { | |
d7e09d03 PT |
166 | CDEBUG(D_INFO, "intent %p released\n", it); |
167 | ll_intent_drop_lock(it); | |
168 | /* We are still holding extra reference on a request, need to free it */ | |
169 | if (it_disposition(it, DISP_ENQ_OPEN_REF)) | |
8bf86fd9 | 170 | ptlrpc_req_finished(it->it_request); /* ll_file_open */ |
2d95f10e | 171 | |
d7e09d03 | 172 | if (it_disposition(it, DISP_ENQ_CREATE_REF)) /* create rec */ |
8bf86fd9 | 173 | ptlrpc_req_finished(it->it_request); |
d7e09d03 | 174 | |
e476f2e5 | 175 | it->it_disposition = 0; |
8bf86fd9 | 176 | it->it_request = NULL; |
d7e09d03 PT |
177 | } |
178 | ||
179 | void ll_invalidate_aliases(struct inode *inode) | |
180 | { | |
181 | struct dentry *dentry; | |
d7e09d03 | 182 | |
1ada25dc | 183 | CDEBUG(D_INODE, "marking dentries for ino " DFID "(%p) invalid\n", |
97a075cd | 184 | PFID(ll_inode2fid(inode)), inode); |
d7e09d03 | 185 | |
2bbec0ed | 186 | spin_lock(&inode->i_lock); |
9d5be52f | 187 | hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { |
dab363f9 LT |
188 | CDEBUG(D_DENTRY, "dentry in drop %pd (%p) parent %p inode %p flags %d\n", |
189 | dentry, dentry, dentry->d_parent, | |
2b0143b5 | 190 | d_inode(dentry), dentry->d_flags); |
d7e09d03 | 191 | |
b1d2a127 | 192 | d_lustre_invalidate(dentry, 0); |
d7e09d03 | 193 | } |
2bbec0ed | 194 | spin_unlock(&inode->i_lock); |
d7e09d03 PT |
195 | } |
196 | ||
197 | int ll_revalidate_it_finish(struct ptlrpc_request *request, | |
198 | struct lookup_intent *it, | |
dbca51dd | 199 | struct inode *inode) |
d7e09d03 PT |
200 | { |
201 | int rc = 0; | |
d7e09d03 PT |
202 | |
203 | if (!request) | |
0a3bdb00 | 204 | return 0; |
d7e09d03 PT |
205 | |
206 | if (it_disposition(it, DISP_LOOKUP_NEG)) | |
0a3bdb00 | 207 | return -ENOENT; |
d7e09d03 | 208 | |
dbca51dd | 209 | rc = ll_prep_inode(&inode, request, NULL, it); |
d7e09d03 | 210 | |
0a3bdb00 | 211 | return rc; |
d7e09d03 PT |
212 | } |
213 | ||
dbca51dd | 214 | void ll_lookup_finish_locks(struct lookup_intent *it, struct inode *inode) |
d7e09d03 | 215 | { |
e476f2e5 | 216 | if (it->it_lock_mode && inode) { |
dbca51dd | 217 | struct ll_sb_info *sbi = ll_i2sbi(inode); |
d7e09d03 | 218 | |
1ada25dc | 219 | CDEBUG(D_DLMTRACE, "setting l_data to inode " DFID "(%p)\n", |
97a075cd | 220 | PFID(ll_inode2fid(inode)), inode); |
d7e09d03 PT |
221 | ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL); |
222 | } | |
223 | ||
224 | /* drop lookup or getattr locks immediately */ | |
225 | if (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR) { | |
226 | /* on 2.6 there are situation when several lookups and | |
227 | * revalidations may be requested during single operation. | |
c0894c6c OD |
228 | * therefore, we don't release intent here -bzzz |
229 | */ | |
d7e09d03 PT |
230 | ll_intent_drop_lock(it); |
231 | } | |
232 | } | |
233 | ||
f236f69b LS |
234 | static int ll_revalidate_dentry(struct dentry *dentry, |
235 | unsigned int lookup_flags) | |
d7e09d03 | 236 | { |
2b0143b5 | 237 | struct inode *dir = d_inode(dentry->d_parent); |
d7e09d03 | 238 | |
aae5d55a OD |
239 | /* If this is intermediate component path lookup and we were able to get |
240 | * to this dentry, then its lock has not been revoked and the | |
241 | * path component is valid. | |
242 | */ | |
243 | if (lookup_flags & LOOKUP_PARENT) | |
244 | return 1; | |
245 | ||
246 | /* Symlink - always valid as long as the dentry was found */ | |
247 | if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) | |
248 | return 1; | |
249 | ||
f236f69b | 250 | /* |
d9421ff6 OD |
251 | * VFS warns us that this is the second go around and previous |
252 | * operation failed (most likely open|creat), so this time | |
253 | * we better talk to the server via the lookup path by name, | |
254 | * not by fid. | |
f236f69b | 255 | */ |
d9421ff6 | 256 | if (lookup_flags & LOOKUP_REVAL) |
f236f69b | 257 | return 0; |
d7e09d03 | 258 | |
5231f765 | 259 | if (!dentry_may_statahead(dir, dentry)) |
f236f69b | 260 | return 1; |
d7e09d03 | 261 | |
f236f69b LS |
262 | if (lookup_flags & LOOKUP_RCU) |
263 | return -ECHILD; | |
d7e09d03 | 264 | |
5231f765 | 265 | ll_statahead(dir, &dentry, !d_inode(dentry)); |
f236f69b | 266 | return 1; |
d7e09d03 PT |
267 | } |
268 | ||
269 | /* | |
270 | * Always trust cached dentries. Update statahead window if necessary. | |
271 | */ | |
2d95f10e | 272 | static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags) |
d7e09d03 | 273 | { |
09561a53 AV |
274 | CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, flags=%u\n", |
275 | dentry, flags); | |
d7e09d03 | 276 | |
5a091a1f | 277 | return ll_revalidate_dentry(dentry, flags); |
d7e09d03 PT |
278 | } |
279 | ||
2d95f10e | 280 | const struct dentry_operations ll_d_ops = { |
7126bc2e | 281 | .d_init = ll_d_init, |
d7e09d03 PT |
282 | .d_revalidate = ll_revalidate_nd, |
283 | .d_release = ll_release, | |
284 | .d_delete = ll_ddelete, | |
d7e09d03 PT |
285 | .d_compare = ll_dcompare, |
286 | }; |