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 GKH |
39 | #include "../include/obd_support.h" |
40 | #include "../include/lustre_lite.h" | |
41 | #include "../include/lustre/lustre_idl.h" | |
42 | #include "../include/lustre_dlm.h" | |
d7e09d03 PT |
43 | |
44 | #include "llite_internal.h" | |
45 | ||
46 | static void free_dentry_data(struct rcu_head *head) | |
47 | { | |
48 | struct ll_dentry_data *lld; | |
49 | ||
50 | lld = container_of(head, struct ll_dentry_data, lld_rcu_head); | |
97903a26 | 51 | kfree(lld); |
d7e09d03 PT |
52 | } |
53 | ||
54 | /* should NOT be called with the dcache lock, see fs/dcache.c */ | |
55 | static void ll_release(struct dentry *de) | |
56 | { | |
57 | struct ll_dentry_data *lld; | |
29aaf496 | 58 | |
6e16818b | 59 | LASSERT(de); |
d7e09d03 | 60 | lld = ll_d2d(de); |
61382aa8 | 61 | if (!lld) /* NFS copies the de->d_op methods (bug 4655) */ |
e05e02e4 | 62 | return; |
d7e09d03 PT |
63 | |
64 | if (lld->lld_it) { | |
65 | ll_intent_release(lld->lld_it); | |
97903a26 | 66 | kfree(lld->lld_it); |
d7e09d03 | 67 | } |
2d95f10e | 68 | |
d7e09d03 PT |
69 | de->d_fsdata = NULL; |
70 | call_rcu(&lld->lld_rcu_head, free_dentry_data); | |
d7e09d03 PT |
71 | } |
72 | ||
73 | /* Compare if two dentries are the same. Don't match if the existing dentry | |
74 | * is marked invalid. Returns 1 if different, 0 if the same. | |
75 | * | |
76 | * This avoids a race where ll_lookup_it() instantiates a dentry, but we get | |
77 | * an AST before calling d_revalidate_it(). The dentry still exists (marked | |
78 | * INVALID) so d_lookup() matches it, but we have no lock on it (so | |
c0894c6c OD |
79 | * lock_match() fails) and we spin around real_lookup(). |
80 | */ | |
6fa67e70 | 81 | static int ll_dcompare(const struct dentry *dentry, |
2d95f10e JH |
82 | unsigned int len, const char *str, |
83 | const struct qstr *name) | |
d7e09d03 | 84 | { |
d7e09d03 | 85 | if (len != name->len) |
0a3bdb00 | 86 | return 1; |
d7e09d03 PT |
87 | |
88 | if (memcmp(str, name->name, len)) | |
0a3bdb00 | 89 | return 1; |
d7e09d03 PT |
90 | |
91 | CDEBUG(D_DENTRY, "found name %.*s(%p) flags %#x refc %d\n", | |
92 | name->len, name->name, dentry, dentry->d_flags, | |
193deee1 | 93 | d_count(dentry)); |
d7e09d03 PT |
94 | |
95 | /* mountpoint is always valid */ | |
96 | if (d_mountpoint((struct dentry *)dentry)) | |
0a3bdb00 | 97 | return 0; |
d7e09d03 PT |
98 | |
99 | if (d_lustre_invalid(dentry)) | |
0a3bdb00 | 100 | return 1; |
d7e09d03 | 101 | |
0a3bdb00 | 102 | return 0; |
d7e09d03 PT |
103 | } |
104 | ||
d7e09d03 PT |
105 | /** |
106 | * Called when last reference to a dentry is dropped and dcache wants to know | |
107 | * whether or not it should cache it: | |
108 | * - return 1 to delete the dentry immediately | |
109 | * - return 0 to cache the dentry | |
110 | * Should NOT be called with the dcache lock, see fs/dcache.c | |
111 | */ | |
112 | static int ll_ddelete(const struct dentry *de) | |
113 | { | |
d7e09d03 PT |
114 | LASSERT(de); |
115 | ||
09561a53 | 116 | CDEBUG(D_DENTRY, "%s dentry %pd (%p, parent %p, inode %p) %s%s\n", |
d7e09d03 | 117 | d_lustre_invalid((struct dentry *)de) ? "deleting" : "keeping", |
2b0143b5 | 118 | de, de, de->d_parent, d_inode(de), |
09561a53 | 119 | d_unhashed(de) ? "" : "hashed,", |
d7e09d03 PT |
120 | list_empty(&de->d_subdirs) ? "" : "subdirs"); |
121 | ||
122 | /* kernel >= 2.6.38 last refcount is decreased after this function. */ | |
193deee1 | 123 | LASSERT(d_count(de) == 1); |
d7e09d03 | 124 | |
d7e09d03 | 125 | if (d_lustre_invalid((struct dentry *)de)) |
0a3bdb00 GKH |
126 | return 1; |
127 | return 0; | |
d7e09d03 PT |
128 | } |
129 | ||
3ea8f3bc | 130 | int ll_d_init(struct dentry *de) |
d7e09d03 | 131 | { |
09561a53 | 132 | CDEBUG(D_DENTRY, "ldd on dentry %pd (%p) parent %p inode %p refc %d\n", |
e15ba45d | 133 | de, de, de->d_parent, d_inode(de), d_count(de)); |
d7e09d03 | 134 | |
61382aa8 | 135 | if (!de->d_fsdata) { |
d7e09d03 PT |
136 | struct ll_dentry_data *lld; |
137 | ||
496a51bd JL |
138 | lld = kzalloc(sizeof(*lld), GFP_NOFS); |
139 | if (likely(lld)) { | |
d7e09d03 | 140 | spin_lock(&de->d_lock); |
61382aa8 | 141 | if (likely(!de->d_fsdata)) { |
d7e09d03 | 142 | de->d_fsdata = lld; |
3ea8f3bc LS |
143 | __d_lustre_invalidate(de); |
144 | } else { | |
97903a26 | 145 | kfree(lld); |
3ea8f3bc | 146 | } |
d7e09d03 PT |
147 | spin_unlock(&de->d_lock); |
148 | } else { | |
0a3bdb00 | 149 | return -ENOMEM; |
d7e09d03 PT |
150 | } |
151 | } | |
3ea8f3bc | 152 | LASSERT(de->d_op == &ll_d_ops); |
d7e09d03 | 153 | |
0a3bdb00 | 154 | return 0; |
d7e09d03 PT |
155 | } |
156 | ||
d7e09d03 PT |
157 | void ll_intent_drop_lock(struct lookup_intent *it) |
158 | { | |
e476f2e5 | 159 | if (it->it_op && it->it_lock_mode) { |
d7e09d03 PT |
160 | struct lustre_handle handle; |
161 | ||
e476f2e5 | 162 | handle.cookie = it->it_lock_handle; |
d7e09d03 | 163 | |
55f5a824 GKH |
164 | CDEBUG(D_DLMTRACE, "releasing lock with cookie %#llx from it %p\n", |
165 | handle.cookie, it); | |
e476f2e5 | 166 | ldlm_lock_decref(&handle, it->it_lock_mode); |
d7e09d03 PT |
167 | |
168 | /* bug 494: intent_release may be called multiple times, from | |
c0894c6c OD |
169 | * this thread and we don't want to double-decref this lock |
170 | */ | |
e476f2e5 JH |
171 | it->it_lock_mode = 0; |
172 | if (it->it_remote_lock_mode != 0) { | |
173 | handle.cookie = it->it_remote_lock_handle; | |
d7e09d03 | 174 | |
55f5a824 GKH |
175 | CDEBUG(D_DLMTRACE, "releasing remote lock with cookie%#llx from it %p\n", |
176 | handle.cookie, it); | |
d7e09d03 | 177 | ldlm_lock_decref(&handle, |
e476f2e5 JH |
178 | it->it_remote_lock_mode); |
179 | it->it_remote_lock_mode = 0; | |
d7e09d03 PT |
180 | } |
181 | } | |
182 | } | |
183 | ||
184 | void ll_intent_release(struct lookup_intent *it) | |
185 | { | |
d7e09d03 PT |
186 | CDEBUG(D_INFO, "intent %p released\n", it); |
187 | ll_intent_drop_lock(it); | |
188 | /* We are still holding extra reference on a request, need to free it */ | |
189 | if (it_disposition(it, DISP_ENQ_OPEN_REF)) | |
8bf86fd9 | 190 | ptlrpc_req_finished(it->it_request); /* ll_file_open */ |
2d95f10e | 191 | |
d7e09d03 | 192 | if (it_disposition(it, DISP_ENQ_CREATE_REF)) /* create rec */ |
8bf86fd9 | 193 | ptlrpc_req_finished(it->it_request); |
d7e09d03 | 194 | |
e476f2e5 | 195 | it->it_disposition = 0; |
8bf86fd9 | 196 | it->it_request = NULL; |
d7e09d03 PT |
197 | } |
198 | ||
199 | void ll_invalidate_aliases(struct inode *inode) | |
200 | { | |
201 | struct dentry *dentry; | |
d7e09d03 | 202 | |
97a075cd JN |
203 | CDEBUG(D_INODE, "marking dentries for ino "DFID"(%p) invalid\n", |
204 | PFID(ll_inode2fid(inode)), inode); | |
d7e09d03 | 205 | |
2bbec0ed | 206 | spin_lock(&inode->i_lock); |
9d5be52f | 207 | hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { |
dab363f9 LT |
208 | CDEBUG(D_DENTRY, "dentry in drop %pd (%p) parent %p inode %p flags %d\n", |
209 | dentry, dentry, dentry->d_parent, | |
2b0143b5 | 210 | d_inode(dentry), dentry->d_flags); |
d7e09d03 | 211 | |
b1d2a127 | 212 | d_lustre_invalidate(dentry, 0); |
d7e09d03 | 213 | } |
2bbec0ed | 214 | spin_unlock(&inode->i_lock); |
d7e09d03 PT |
215 | } |
216 | ||
217 | int ll_revalidate_it_finish(struct ptlrpc_request *request, | |
218 | struct lookup_intent *it, | |
dbca51dd | 219 | struct inode *inode) |
d7e09d03 PT |
220 | { |
221 | int rc = 0; | |
d7e09d03 PT |
222 | |
223 | if (!request) | |
0a3bdb00 | 224 | return 0; |
d7e09d03 PT |
225 | |
226 | if (it_disposition(it, DISP_LOOKUP_NEG)) | |
0a3bdb00 | 227 | return -ENOENT; |
d7e09d03 | 228 | |
dbca51dd | 229 | rc = ll_prep_inode(&inode, request, NULL, it); |
d7e09d03 | 230 | |
0a3bdb00 | 231 | return rc; |
d7e09d03 PT |
232 | } |
233 | ||
dbca51dd | 234 | void ll_lookup_finish_locks(struct lookup_intent *it, struct inode *inode) |
d7e09d03 | 235 | { |
e476f2e5 | 236 | if (it->it_lock_mode && inode) { |
dbca51dd | 237 | struct ll_sb_info *sbi = ll_i2sbi(inode); |
d7e09d03 | 238 | |
97a075cd JN |
239 | CDEBUG(D_DLMTRACE, "setting l_data to inode "DFID"(%p)\n", |
240 | PFID(ll_inode2fid(inode)), inode); | |
d7e09d03 PT |
241 | ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL); |
242 | } | |
243 | ||
244 | /* drop lookup or getattr locks immediately */ | |
245 | if (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR) { | |
246 | /* on 2.6 there are situation when several lookups and | |
247 | * revalidations may be requested during single operation. | |
c0894c6c OD |
248 | * therefore, we don't release intent here -bzzz |
249 | */ | |
d7e09d03 PT |
250 | ll_intent_drop_lock(it); |
251 | } | |
252 | } | |
253 | ||
f236f69b LS |
254 | static int ll_revalidate_dentry(struct dentry *dentry, |
255 | unsigned int lookup_flags) | |
d7e09d03 | 256 | { |
2b0143b5 | 257 | struct inode *dir = d_inode(dentry->d_parent); |
d7e09d03 | 258 | |
aae5d55a OD |
259 | /* If this is intermediate component path lookup and we were able to get |
260 | * to this dentry, then its lock has not been revoked and the | |
261 | * path component is valid. | |
262 | */ | |
263 | if (lookup_flags & LOOKUP_PARENT) | |
264 | return 1; | |
265 | ||
266 | /* Symlink - always valid as long as the dentry was found */ | |
267 | if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) | |
268 | return 1; | |
269 | ||
f236f69b LS |
270 | /* |
271 | * if open&create is set, talk to MDS to make sure file is created if | |
272 | * necessary, because we can't do this in ->open() later since that's | |
273 | * called on an inode. return 0 here to let lookup to handle this. | |
274 | */ | |
275 | if ((lookup_flags & (LOOKUP_OPEN | LOOKUP_CREATE)) == | |
276 | (LOOKUP_OPEN | LOOKUP_CREATE)) | |
277 | return 0; | |
d7e09d03 | 278 | |
f236f69b | 279 | if (lookup_flags & (LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE)) |
0a3bdb00 | 280 | return 1; |
d7e09d03 | 281 | |
f236f69b LS |
282 | if (d_need_statahead(dir, dentry) <= 0) |
283 | return 1; | |
d7e09d03 | 284 | |
f236f69b LS |
285 | if (lookup_flags & LOOKUP_RCU) |
286 | return -ECHILD; | |
d7e09d03 | 287 | |
61382aa8 | 288 | do_statahead_enter(dir, &dentry, !d_inode(dentry)); |
f236f69b LS |
289 | ll_statahead_mark(dir, dentry); |
290 | return 1; | |
d7e09d03 PT |
291 | } |
292 | ||
293 | /* | |
294 | * Always trust cached dentries. Update statahead window if necessary. | |
295 | */ | |
2d95f10e | 296 | static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags) |
d7e09d03 | 297 | { |
09561a53 AV |
298 | CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, flags=%u\n", |
299 | dentry, flags); | |
d7e09d03 | 300 | |
5a091a1f | 301 | return ll_revalidate_dentry(dentry, flags); |
d7e09d03 PT |
302 | } |
303 | ||
2d95f10e | 304 | const struct dentry_operations ll_d_ops = { |
d7e09d03 PT |
305 | .d_revalidate = ll_revalidate_nd, |
306 | .d_release = ll_release, | |
307 | .d_delete = ll_ddelete, | |
d7e09d03 PT |
308 | .d_compare = ll_dcompare, |
309 | }; |