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", |
2b0143b5 | 156 | de, de, de->d_parent, d_inode(de), |
09561a53 | 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 */ | |
2b0143b5 DH |
170 | if (d_really_is_positive(de) && !find_cbdata(d_inode(de))) |
171 | clear_nlink(d_inode(de)); | |
d7e09d03 PT |
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 | 183 | CDEBUG(D_DENTRY, "ldd on dentry %pd (%p) parent %p inode %p refc %d\n", |
2b0143b5 | 184 | de, de, de->d_parent, d_inode(de), |
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) { |
dab363f9 LT |
262 | CDEBUG(D_DENTRY, "dentry in drop %pd (%p) parent %p inode %p flags %d\n", |
263 | dentry, dentry, dentry->d_parent, | |
2b0143b5 | 264 | d_inode(dentry), dentry->d_flags); |
d7e09d03 | 265 | |
b1d2a127 | 266 | d_lustre_invalidate(dentry, 0); |
d7e09d03 PT |
267 | } |
268 | ll_unlock_dcache(inode); | |
d7e09d03 PT |
269 | } |
270 | ||
271 | int ll_revalidate_it_finish(struct ptlrpc_request *request, | |
272 | struct lookup_intent *it, | |
dbca51dd | 273 | struct inode *inode) |
d7e09d03 PT |
274 | { |
275 | int rc = 0; | |
d7e09d03 PT |
276 | |
277 | if (!request) | |
0a3bdb00 | 278 | return 0; |
d7e09d03 PT |
279 | |
280 | if (it_disposition(it, DISP_LOOKUP_NEG)) | |
0a3bdb00 | 281 | return -ENOENT; |
d7e09d03 | 282 | |
dbca51dd | 283 | rc = ll_prep_inode(&inode, request, NULL, it); |
d7e09d03 | 284 | |
0a3bdb00 | 285 | return rc; |
d7e09d03 PT |
286 | } |
287 | ||
dbca51dd | 288 | void ll_lookup_finish_locks(struct lookup_intent *it, struct inode *inode) |
d7e09d03 PT |
289 | { |
290 | LASSERT(it != NULL); | |
d7e09d03 | 291 | |
dbca51dd AV |
292 | if (it->d.lustre.it_lock_mode && inode != NULL) { |
293 | struct ll_sb_info *sbi = ll_i2sbi(inode); | |
d7e09d03 PT |
294 | |
295 | CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n", | |
296 | inode, inode->i_ino, inode->i_generation); | |
297 | ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL); | |
298 | } | |
299 | ||
300 | /* drop lookup or getattr locks immediately */ | |
301 | if (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR) { | |
302 | /* on 2.6 there are situation when several lookups and | |
303 | * revalidations may be requested during single operation. | |
304 | * therefore, we don't release intent here -bzzz */ | |
305 | ll_intent_drop_lock(it); | |
306 | } | |
307 | } | |
308 | ||
f236f69b LS |
309 | static int ll_revalidate_dentry(struct dentry *dentry, |
310 | unsigned int lookup_flags) | |
d7e09d03 | 311 | { |
2b0143b5 | 312 | struct inode *dir = d_inode(dentry->d_parent); |
d7e09d03 | 313 | |
f236f69b LS |
314 | /* |
315 | * if open&create is set, talk to MDS to make sure file is created if | |
316 | * necessary, because we can't do this in ->open() later since that's | |
317 | * called on an inode. return 0 here to let lookup to handle this. | |
318 | */ | |
319 | if ((lookup_flags & (LOOKUP_OPEN | LOOKUP_CREATE)) == | |
320 | (LOOKUP_OPEN | LOOKUP_CREATE)) | |
321 | return 0; | |
d7e09d03 | 322 | |
f236f69b | 323 | if (lookup_flags & (LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE)) |
0a3bdb00 | 324 | return 1; |
d7e09d03 | 325 | |
f236f69b LS |
326 | if (d_need_statahead(dir, dentry) <= 0) |
327 | return 1; | |
d7e09d03 | 328 | |
f236f69b LS |
329 | if (lookup_flags & LOOKUP_RCU) |
330 | return -ECHILD; | |
d7e09d03 | 331 | |
2b0143b5 | 332 | do_statahead_enter(dir, &dentry, d_inode(dentry) == NULL); |
f236f69b LS |
333 | ll_statahead_mark(dir, dentry); |
334 | return 1; | |
d7e09d03 PT |
335 | } |
336 | ||
337 | /* | |
338 | * Always trust cached dentries. Update statahead window if necessary. | |
339 | */ | |
2d95f10e | 340 | static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags) |
d7e09d03 | 341 | { |
f236f69b | 342 | int rc; |
d7e09d03 | 343 | |
09561a53 AV |
344 | CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, flags=%u\n", |
345 | dentry, flags); | |
d7e09d03 | 346 | |
f236f69b LS |
347 | rc = ll_revalidate_dentry(dentry, flags); |
348 | return rc; | |
d7e09d03 PT |
349 | } |
350 | ||
351 | ||
2d95f10e | 352 | static void ll_d_iput(struct dentry *de, struct inode *inode) |
d7e09d03 PT |
353 | { |
354 | LASSERT(inode); | |
355 | if (!find_cbdata(inode)) | |
356 | clear_nlink(inode); | |
357 | iput(inode); | |
358 | } | |
359 | ||
2d95f10e | 360 | const struct dentry_operations ll_d_ops = { |
d7e09d03 PT |
361 | .d_revalidate = ll_revalidate_nd, |
362 | .d_release = ll_release, | |
363 | .d_delete = ll_ddelete, | |
364 | .d_iput = ll_d_iput, | |
365 | .d_compare = ll_dcompare, | |
366 | }; |