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 | |
18 | * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf | |
19 | * | |
20 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
21 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
22 | * have any questions. | |
23 | * | |
24 | * GPL HEADER END | |
25 | */ | |
26 | /* | |
27 | * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. | |
28 | * Use is subject to license terms. | |
29 | * | |
30 | * Copyright (c) 2011, 2012, Intel Corporation. | |
31 | */ | |
32 | /* | |
33 | * This file is part of Lustre, http://www.lustre.org/ | |
34 | * Lustre is a trademark of Sun Microsystems, Inc. | |
35 | */ | |
36 | ||
37 | #include <linux/fs.h> | |
38 | #include <linux/sched.h> | |
39 | #include <linux/quotaops.h> | |
40 | ||
41 | #define DEBUG_SUBSYSTEM S_LLITE | |
42 | ||
67a235f5 GKH |
43 | #include "../include/obd_support.h" |
44 | #include "../include/lustre_lite.h" | |
45 | #include "../include/lustre/lustre_idl.h" | |
46 | #include "../include/lustre_dlm.h" | |
d7e09d03 PT |
47 | |
48 | #include "llite_internal.h" | |
49 | ||
50 | static void free_dentry_data(struct rcu_head *head) | |
51 | { | |
52 | struct ll_dentry_data *lld; | |
53 | ||
54 | lld = container_of(head, struct ll_dentry_data, lld_rcu_head); | |
55 | OBD_FREE_PTR(lld); | |
56 | } | |
57 | ||
58 | /* should NOT be called with the dcache lock, see fs/dcache.c */ | |
59 | static void ll_release(struct dentry *de) | |
60 | { | |
61 | struct ll_dentry_data *lld; | |
29aaf496 | 62 | |
d7e09d03 PT |
63 | LASSERT(de != NULL); |
64 | lld = ll_d2d(de); | |
65 | if (lld == NULL) /* NFS copies the de->d_op methods (bug 4655) */ | |
e05e02e4 | 66 | return; |
d7e09d03 PT |
67 | |
68 | if (lld->lld_it) { | |
69 | ll_intent_release(lld->lld_it); | |
70 | OBD_FREE(lld->lld_it, sizeof(*lld->lld_it)); | |
71 | } | |
2d95f10e | 72 | |
d7e09d03 PT |
73 | de->d_fsdata = NULL; |
74 | call_rcu(&lld->lld_rcu_head, free_dentry_data); | |
d7e09d03 PT |
75 | } |
76 | ||
77 | /* Compare if two dentries are the same. Don't match if the existing dentry | |
78 | * is marked invalid. Returns 1 if different, 0 if the same. | |
79 | * | |
80 | * This avoids a race where ll_lookup_it() instantiates a dentry, but we get | |
81 | * an AST before calling d_revalidate_it(). The dentry still exists (marked | |
82 | * INVALID) so d_lookup() matches it, but we have no lock on it (so | |
83 | * lock_match() fails) and we spin around real_lookup(). */ | |
2d95f10e JH |
84 | static int ll_dcompare(const struct dentry *parent, const struct dentry *dentry, |
85 | unsigned int len, const char *str, | |
86 | const struct qstr *name) | |
d7e09d03 | 87 | { |
d7e09d03 | 88 | if (len != name->len) |
0a3bdb00 | 89 | return 1; |
d7e09d03 PT |
90 | |
91 | if (memcmp(str, name->name, len)) | |
0a3bdb00 | 92 | return 1; |
d7e09d03 PT |
93 | |
94 | CDEBUG(D_DENTRY, "found name %.*s(%p) flags %#x refc %d\n", | |
95 | name->len, name->name, dentry, dentry->d_flags, | |
193deee1 | 96 | d_count(dentry)); |
d7e09d03 PT |
97 | |
98 | /* mountpoint is always valid */ | |
99 | if (d_mountpoint((struct dentry *)dentry)) | |
0a3bdb00 | 100 | return 0; |
d7e09d03 PT |
101 | |
102 | if (d_lustre_invalid(dentry)) | |
0a3bdb00 | 103 | return 1; |
d7e09d03 | 104 | |
0a3bdb00 | 105 | return 0; |
d7e09d03 PT |
106 | } |
107 | ||
108 | static inline int return_if_equal(struct ldlm_lock *lock, void *data) | |
109 | { | |
110 | if ((lock->l_flags & | |
111 | (LDLM_FL_CANCELING | LDLM_FL_DISCARD_DATA)) == | |
112 | (LDLM_FL_CANCELING | LDLM_FL_DISCARD_DATA)) | |
113 | return LDLM_ITER_CONTINUE; | |
114 | return LDLM_ITER_STOP; | |
115 | } | |
116 | ||
117 | /* find any ldlm lock of the inode in mdc and lov | |
118 | * return 0 not find | |
119 | * 1 find one | |
120 | * < 0 error */ | |
121 | static int find_cbdata(struct inode *inode) | |
122 | { | |
123 | struct ll_sb_info *sbi = ll_i2sbi(inode); | |
124 | struct lov_stripe_md *lsm; | |
125 | int rc = 0; | |
d7e09d03 PT |
126 | |
127 | LASSERT(inode); | |
128 | rc = md_find_cbdata(sbi->ll_md_exp, ll_inode2fid(inode), | |
129 | return_if_equal, NULL); | |
130 | if (rc != 0) | |
0a3bdb00 | 131 | return rc; |
d7e09d03 PT |
132 | |
133 | lsm = ccc_inode_lsm_get(inode); | |
134 | if (lsm == NULL) | |
0a3bdb00 | 135 | return rc; |
d7e09d03 PT |
136 | |
137 | rc = obd_find_cbdata(sbi->ll_dt_exp, lsm, return_if_equal, NULL); | |
138 | ccc_inode_lsm_put(inode, lsm); | |
139 | ||
0a3bdb00 | 140 | return rc; |
d7e09d03 PT |
141 | } |
142 | ||
143 | /** | |
144 | * Called when last reference to a dentry is dropped and dcache wants to know | |
145 | * whether or not it should cache it: | |
146 | * - return 1 to delete the dentry immediately | |
147 | * - return 0 to cache the dentry | |
148 | * Should NOT be called with the dcache lock, see fs/dcache.c | |
149 | */ | |
150 | static int ll_ddelete(const struct dentry *de) | |
151 | { | |
d7e09d03 PT |
152 | LASSERT(de); |
153 | ||
09561a53 | 154 | CDEBUG(D_DENTRY, "%s dentry %pd (%p, parent %p, inode %p) %s%s\n", |
d7e09d03 | 155 | d_lustre_invalid((struct dentry *)de) ? "deleting" : "keeping", |
09561a53 AV |
156 | de, de, de->d_parent, de->d_inode, |
157 | d_unhashed(de) ? "" : "hashed,", | |
d7e09d03 PT |
158 | list_empty(&de->d_subdirs) ? "" : "subdirs"); |
159 | ||
160 | /* kernel >= 2.6.38 last refcount is decreased after this function. */ | |
193deee1 | 161 | LASSERT(d_count(de) == 1); |
d7e09d03 | 162 | |
d0a0acc3 | 163 | /* Disable this piece of code temporarily because this is called |
d7e09d03 PT |
164 | * inside dcache_lock so it's not appropriate to do lots of work |
165 | * here. ATTENTION: Before this piece of code enabling, LU-2487 must be | |
166 | * resolved. */ | |
167 | #if 0 | |
168 | /* if not ldlm lock for this inode, set i_nlink to 0 so that | |
169 | * this inode can be recycled later b=20433 */ | |
170 | if (de->d_inode && !find_cbdata(de->d_inode)) | |
171 | clear_nlink(de->d_inode); | |
172 | #endif | |
173 | ||
174 | if (d_lustre_invalid((struct dentry *)de)) | |
0a3bdb00 GKH |
175 | return 1; |
176 | return 0; | |
d7e09d03 PT |
177 | } |
178 | ||
3ea8f3bc | 179 | int ll_d_init(struct dentry *de) |
d7e09d03 | 180 | { |
d7e09d03 PT |
181 | LASSERT(de != NULL); |
182 | ||
09561a53 AV |
183 | CDEBUG(D_DENTRY, "ldd on dentry %pd (%p) parent %p inode %p refc %d\n", |
184 | de, de, de->d_parent, de->d_inode, | |
193deee1 | 185 | d_count(de)); |
d7e09d03 PT |
186 | |
187 | if (de->d_fsdata == NULL) { | |
188 | struct ll_dentry_data *lld; | |
189 | ||
496a51bd JL |
190 | lld = kzalloc(sizeof(*lld), GFP_NOFS); |
191 | if (likely(lld)) { | |
d7e09d03 | 192 | spin_lock(&de->d_lock); |
3ea8f3bc | 193 | if (likely(de->d_fsdata == NULL)) { |
d7e09d03 | 194 | de->d_fsdata = lld; |
3ea8f3bc LS |
195 | __d_lustre_invalidate(de); |
196 | } else { | |
d7e09d03 | 197 | OBD_FREE_PTR(lld); |
3ea8f3bc | 198 | } |
d7e09d03 PT |
199 | spin_unlock(&de->d_lock); |
200 | } else { | |
0a3bdb00 | 201 | return -ENOMEM; |
d7e09d03 PT |
202 | } |
203 | } | |
3ea8f3bc | 204 | LASSERT(de->d_op == &ll_d_ops); |
d7e09d03 | 205 | |
0a3bdb00 | 206 | return 0; |
d7e09d03 PT |
207 | } |
208 | ||
d7e09d03 PT |
209 | void ll_intent_drop_lock(struct lookup_intent *it) |
210 | { | |
211 | if (it->it_op && it->d.lustre.it_lock_mode) { | |
212 | struct lustre_handle handle; | |
213 | ||
214 | handle.cookie = it->d.lustre.it_lock_handle; | |
215 | ||
55f5a824 GKH |
216 | CDEBUG(D_DLMTRACE, "releasing lock with cookie %#llx from it %p\n", |
217 | handle.cookie, it); | |
d7e09d03 PT |
218 | ldlm_lock_decref(&handle, it->d.lustre.it_lock_mode); |
219 | ||
220 | /* bug 494: intent_release may be called multiple times, from | |
221 | * this thread and we don't want to double-decref this lock */ | |
222 | it->d.lustre.it_lock_mode = 0; | |
223 | if (it->d.lustre.it_remote_lock_mode != 0) { | |
224 | handle.cookie = it->d.lustre.it_remote_lock_handle; | |
225 | ||
55f5a824 GKH |
226 | CDEBUG(D_DLMTRACE, "releasing remote lock with cookie%#llx from it %p\n", |
227 | handle.cookie, it); | |
d7e09d03 PT |
228 | ldlm_lock_decref(&handle, |
229 | it->d.lustre.it_remote_lock_mode); | |
230 | it->d.lustre.it_remote_lock_mode = 0; | |
231 | } | |
232 | } | |
233 | } | |
234 | ||
235 | void ll_intent_release(struct lookup_intent *it) | |
236 | { | |
d7e09d03 PT |
237 | CDEBUG(D_INFO, "intent %p released\n", it); |
238 | ll_intent_drop_lock(it); | |
239 | /* We are still holding extra reference on a request, need to free it */ | |
240 | if (it_disposition(it, DISP_ENQ_OPEN_REF)) | |
2d95f10e JH |
241 | ptlrpc_req_finished(it->d.lustre.it_data); /* ll_file_open */ |
242 | ||
d7e09d03 PT |
243 | if (it_disposition(it, DISP_ENQ_CREATE_REF)) /* create rec */ |
244 | ptlrpc_req_finished(it->d.lustre.it_data); | |
d7e09d03 PT |
245 | |
246 | it->d.lustre.it_disposition = 0; | |
247 | it->d.lustre.it_data = NULL; | |
d7e09d03 PT |
248 | } |
249 | ||
250 | void ll_invalidate_aliases(struct inode *inode) | |
251 | { | |
252 | struct dentry *dentry; | |
253 | struct ll_d_hlist_node *p; | |
d7e09d03 PT |
254 | |
255 | LASSERT(inode != NULL); | |
256 | ||
257 | CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n", | |
258 | inode->i_ino, inode->i_generation, inode); | |
259 | ||
260 | ll_lock_dcache(inode); | |
946e51f2 | 261 | ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_u.d_alias) { |
09561a53 AV |
262 | CDEBUG(D_DENTRY, "dentry in drop %pd (%p) parent %p " |
263 | "inode %p flags %d\n", dentry, dentry, dentry->d_parent, | |
d7e09d03 PT |
264 | dentry->d_inode, dentry->d_flags); |
265 | ||
4c2060a8 PF |
266 | if (unlikely(dentry == dentry->d_sb->s_root)) { |
267 | CERROR("%s: called on root dentry=%p, fid="DFID"\n", | |
268 | ll_get_fsname(dentry->d_sb, NULL, 0), | |
269 | dentry, PFID(ll_inode2fid(inode))); | |
d7e09d03 | 270 | lustre_dump_dentry(dentry, 1); |
5d4450c4 | 271 | dump_stack(); |
d7e09d03 PT |
272 | } |
273 | ||
b1d2a127 | 274 | d_lustre_invalidate(dentry, 0); |
d7e09d03 PT |
275 | } |
276 | ll_unlock_dcache(inode); | |
d7e09d03 PT |
277 | } |
278 | ||
279 | int ll_revalidate_it_finish(struct ptlrpc_request *request, | |
280 | struct lookup_intent *it, | |
281 | struct dentry *de) | |
282 | { | |
283 | int rc = 0; | |
d7e09d03 PT |
284 | |
285 | if (!request) | |
0a3bdb00 | 286 | return 0; |
d7e09d03 PT |
287 | |
288 | if (it_disposition(it, DISP_LOOKUP_NEG)) | |
0a3bdb00 | 289 | return -ENOENT; |
d7e09d03 PT |
290 | |
291 | rc = ll_prep_inode(&de->d_inode, request, NULL, it); | |
292 | ||
0a3bdb00 | 293 | return rc; |
d7e09d03 PT |
294 | } |
295 | ||
296 | void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry) | |
297 | { | |
298 | LASSERT(it != NULL); | |
299 | LASSERT(dentry != NULL); | |
300 | ||
301 | if (it->d.lustre.it_lock_mode && dentry->d_inode != NULL) { | |
302 | struct inode *inode = dentry->d_inode; | |
303 | struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode); | |
304 | ||
305 | CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n", | |
306 | inode, inode->i_ino, inode->i_generation); | |
307 | ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL); | |
308 | } | |
309 | ||
310 | /* drop lookup or getattr locks immediately */ | |
311 | if (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR) { | |
312 | /* on 2.6 there are situation when several lookups and | |
313 | * revalidations may be requested during single operation. | |
314 | * therefore, we don't release intent here -bzzz */ | |
315 | ll_intent_drop_lock(it); | |
316 | } | |
317 | } | |
318 | ||
f236f69b LS |
319 | static int ll_revalidate_dentry(struct dentry *dentry, |
320 | unsigned int lookup_flags) | |
d7e09d03 | 321 | { |
f236f69b | 322 | struct inode *dir = dentry->d_parent->d_inode; |
d7e09d03 | 323 | |
f236f69b LS |
324 | /* |
325 | * if open&create is set, talk to MDS to make sure file is created if | |
326 | * necessary, because we can't do this in ->open() later since that's | |
327 | * called on an inode. return 0 here to let lookup to handle this. | |
328 | */ | |
329 | if ((lookup_flags & (LOOKUP_OPEN | LOOKUP_CREATE)) == | |
330 | (LOOKUP_OPEN | LOOKUP_CREATE)) | |
331 | return 0; | |
d7e09d03 | 332 | |
f236f69b | 333 | if (lookup_flags & (LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE)) |
0a3bdb00 | 334 | return 1; |
d7e09d03 | 335 | |
f236f69b LS |
336 | if (d_need_statahead(dir, dentry) <= 0) |
337 | return 1; | |
d7e09d03 | 338 | |
f236f69b LS |
339 | if (lookup_flags & LOOKUP_RCU) |
340 | return -ECHILD; | |
d7e09d03 | 341 | |
f236f69b LS |
342 | do_statahead_enter(dir, &dentry, dentry->d_inode == NULL); |
343 | ll_statahead_mark(dir, dentry); | |
344 | return 1; | |
d7e09d03 PT |
345 | } |
346 | ||
347 | /* | |
348 | * Always trust cached dentries. Update statahead window if necessary. | |
349 | */ | |
2d95f10e | 350 | static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags) |
d7e09d03 | 351 | { |
f236f69b | 352 | int rc; |
d7e09d03 | 353 | |
09561a53 AV |
354 | CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, flags=%u\n", |
355 | dentry, flags); | |
d7e09d03 | 356 | |
f236f69b LS |
357 | rc = ll_revalidate_dentry(dentry, flags); |
358 | return rc; | |
d7e09d03 PT |
359 | } |
360 | ||
361 | ||
2d95f10e | 362 | static void ll_d_iput(struct dentry *de, struct inode *inode) |
d7e09d03 PT |
363 | { |
364 | LASSERT(inode); | |
365 | if (!find_cbdata(inode)) | |
366 | clear_nlink(inode); | |
367 | iput(inode); | |
368 | } | |
369 | ||
2d95f10e | 370 | const struct dentry_operations ll_d_ops = { |
d7e09d03 PT |
371 | .d_revalidate = ll_revalidate_nd, |
372 | .d_release = ll_release, | |
373 | .d_delete = ll_ddelete, | |
374 | .d_iput = ll_d_iput, | |
375 | .d_compare = ll_dcompare, | |
376 | }; |