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/mm.h> | |
40 | #include <linux/quotaops.h> | |
41 | #include <linux/highmem.h> | |
42 | #include <linux/pagemap.h> | |
43 | #include <linux/security.h> | |
44 | ||
45 | #define DEBUG_SUBSYSTEM S_LLITE | |
46 | ||
47 | #include <obd_support.h> | |
48 | #include <lustre_fid.h> | |
49 | #include <lustre_lite.h> | |
50 | #include <lustre_dlm.h> | |
51 | #include <lustre_ver.h> | |
52 | #include "llite_internal.h" | |
53 | ||
54 | static int ll_create_it(struct inode *, struct dentry *, | |
55 | int, struct lookup_intent *); | |
56 | ||
57 | /* | |
58 | * Check if we have something mounted at the named dchild. | |
59 | * In such a case there would always be dentry present. | |
60 | */ | |
61 | static int ll_d_mountpoint(struct dentry *dparent, struct dentry *dchild, | |
62 | struct qstr *name) | |
63 | { | |
64 | int mounted = 0; | |
65 | ||
66 | if (unlikely(dchild)) { | |
67 | mounted = d_mountpoint(dchild); | |
68 | } else if (dparent) { | |
69 | dchild = d_lookup(dparent, name); | |
70 | if (dchild) { | |
71 | mounted = d_mountpoint(dchild); | |
72 | dput(dchild); | |
73 | } | |
74 | } | |
75 | return mounted; | |
76 | } | |
77 | ||
78 | int ll_unlock(__u32 mode, struct lustre_handle *lockh) | |
79 | { | |
d7e09d03 PT |
80 | ldlm_lock_decref(lockh, mode); |
81 | ||
82 | RETURN(0); | |
83 | } | |
84 | ||
85 | ||
86 | /* called from iget5_locked->find_inode() under inode_lock spinlock */ | |
87 | static int ll_test_inode(struct inode *inode, void *opaque) | |
88 | { | |
89 | struct ll_inode_info *lli = ll_i2info(inode); | |
90 | struct lustre_md *md = opaque; | |
91 | ||
92 | if (unlikely(!(md->body->valid & OBD_MD_FLID))) { | |
93 | CERROR("MDS body missing FID\n"); | |
94 | return 0; | |
95 | } | |
96 | ||
97 | if (!lu_fid_eq(&lli->lli_fid, &md->body->fid1)) | |
98 | return 0; | |
99 | ||
100 | return 1; | |
101 | } | |
102 | ||
103 | static int ll_set_inode(struct inode *inode, void *opaque) | |
104 | { | |
105 | struct ll_inode_info *lli = ll_i2info(inode); | |
106 | struct mdt_body *body = ((struct lustre_md *)opaque)->body; | |
107 | ||
108 | if (unlikely(!(body->valid & OBD_MD_FLID))) { | |
109 | CERROR("MDS body missing FID\n"); | |
110 | return -EINVAL; | |
111 | } | |
112 | ||
113 | lli->lli_fid = body->fid1; | |
114 | if (unlikely(!(body->valid & OBD_MD_FLTYPE))) { | |
115 | CERROR("Can not initialize inode "DFID" without object type: " | |
116 | "valid = "LPX64"\n", PFID(&lli->lli_fid), body->valid); | |
117 | return -EINVAL; | |
118 | } | |
119 | ||
120 | inode->i_mode = (inode->i_mode & ~S_IFMT) | (body->mode & S_IFMT); | |
121 | if (unlikely(inode->i_mode == 0)) { | |
122 | CERROR("Invalid inode "DFID" type\n", PFID(&lli->lli_fid)); | |
123 | return -EINVAL; | |
124 | } | |
125 | ||
126 | ll_lli_init(lli); | |
127 | ||
128 | return 0; | |
129 | } | |
130 | ||
131 | ||
132 | /* | |
133 | * Get an inode by inode number (already instantiated by the intent lookup). | |
134 | * Returns inode or NULL | |
135 | */ | |
136 | struct inode *ll_iget(struct super_block *sb, ino_t hash, | |
137 | struct lustre_md *md) | |
138 | { | |
139 | struct inode *inode; | |
d7e09d03 PT |
140 | |
141 | LASSERT(hash != 0); | |
142 | inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md); | |
143 | ||
144 | if (inode) { | |
145 | if (inode->i_state & I_NEW) { | |
146 | int rc = 0; | |
147 | ||
148 | ll_read_inode2(inode, md); | |
149 | if (S_ISREG(inode->i_mode) && | |
150 | ll_i2info(inode)->lli_clob == NULL) { | |
151 | CDEBUG(D_INODE, | |
152 | "%s: apply lsm %p to inode "DFID".\n", | |
153 | ll_get_fsname(sb, NULL, 0), md->lsm, | |
154 | PFID(ll_inode2fid(inode))); | |
155 | rc = cl_file_inode_init(inode, md); | |
156 | } | |
157 | if (rc != 0) { | |
158 | make_bad_inode(inode); | |
159 | unlock_new_inode(inode); | |
160 | iput(inode); | |
161 | inode = ERR_PTR(rc); | |
162 | } else | |
163 | unlock_new_inode(inode); | |
164 | } else if (!(inode->i_state & (I_FREEING | I_CLEAR))) | |
165 | ll_update_inode(inode, md); | |
166 | CDEBUG(D_VFSTRACE, "got inode: %p for "DFID"\n", | |
167 | inode, PFID(&md->body->fid1)); | |
168 | } | |
169 | RETURN(inode); | |
170 | } | |
171 | ||
172 | static void ll_invalidate_negative_children(struct inode *dir) | |
173 | { | |
174 | struct dentry *dentry, *tmp_subdir; | |
175 | struct ll_d_hlist_node *p; | |
176 | ||
177 | ll_lock_dcache(dir); | |
178 | ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_alias) { | |
179 | spin_lock(&dentry->d_lock); | |
180 | if (!list_empty(&dentry->d_subdirs)) { | |
181 | struct dentry *child; | |
182 | ||
183 | list_for_each_entry_safe(child, tmp_subdir, | |
184 | &dentry->d_subdirs, | |
185 | d_u.d_child) { | |
186 | if (child->d_inode == NULL) | |
b1d2a127 | 187 | d_lustre_invalidate(child, 1); |
d7e09d03 PT |
188 | } |
189 | } | |
190 | spin_unlock(&dentry->d_lock); | |
191 | } | |
192 | ll_unlock_dcache(dir); | |
193 | } | |
194 | ||
195 | int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, | |
196 | void *data, int flag) | |
197 | { | |
198 | int rc; | |
199 | struct lustre_handle lockh; | |
d7e09d03 PT |
200 | |
201 | switch (flag) { | |
202 | case LDLM_CB_BLOCKING: | |
203 | ldlm_lock2handle(lock, &lockh); | |
204 | rc = ldlm_cli_cancel(&lockh, LCF_ASYNC); | |
205 | if (rc < 0) { | |
206 | CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc); | |
207 | RETURN(rc); | |
208 | } | |
209 | break; | |
210 | case LDLM_CB_CANCELING: { | |
211 | struct inode *inode = ll_inode_from_resource_lock(lock); | |
212 | struct ll_inode_info *lli; | |
213 | __u64 bits = lock->l_policy_data.l_inodebits.bits; | |
214 | struct lu_fid *fid; | |
215 | ldlm_mode_t mode = lock->l_req_mode; | |
216 | ||
217 | /* Inode is set to lock->l_resource->lr_lvb_inode | |
218 | * for mdc - bug 24555 */ | |
219 | LASSERT(lock->l_ast_data == NULL); | |
220 | ||
221 | /* Invalidate all dentries associated with this inode */ | |
222 | if (inode == NULL) | |
223 | break; | |
224 | ||
225 | LASSERT(lock->l_flags & LDLM_FL_CANCELING); | |
226 | /* For OPEN locks we differentiate between lock modes | |
227 | * LCK_CR, LCK_CW, LCK_PR - bug 22891 */ | |
228 | if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE | | |
229 | MDS_INODELOCK_LAYOUT | MDS_INODELOCK_PERM)) | |
230 | ll_have_md_lock(inode, &bits, LCK_MINMODE); | |
231 | ||
232 | if (bits & MDS_INODELOCK_OPEN) | |
233 | ll_have_md_lock(inode, &bits, mode); | |
234 | ||
235 | fid = ll_inode2fid(inode); | |
236 | if (lock->l_resource->lr_name.name[0] != fid_seq(fid) || | |
237 | lock->l_resource->lr_name.name[1] != fid_oid(fid) || | |
238 | lock->l_resource->lr_name.name[2] != fid_ver(fid)) { | |
239 | LDLM_ERROR(lock, "data mismatch with object " | |
240 | DFID" (%p)", PFID(fid), inode); | |
241 | } | |
242 | ||
243 | if (bits & MDS_INODELOCK_OPEN) { | |
244 | int flags = 0; | |
245 | switch (lock->l_req_mode) { | |
246 | case LCK_CW: | |
247 | flags = FMODE_WRITE; | |
248 | break; | |
249 | case LCK_PR: | |
250 | flags = FMODE_EXEC; | |
251 | break; | |
252 | case LCK_CR: | |
253 | flags = FMODE_READ; | |
254 | break; | |
255 | default: | |
256 | CERROR("Unexpected lock mode for OPEN lock " | |
257 | "%d, inode %ld\n", lock->l_req_mode, | |
258 | inode->i_ino); | |
259 | } | |
260 | ll_md_real_close(inode, flags); | |
261 | } | |
262 | ||
263 | lli = ll_i2info(inode); | |
264 | if (bits & MDS_INODELOCK_LAYOUT) { | |
265 | struct cl_object_conf conf = { { 0 } }; | |
266 | ||
267 | conf.coc_opc = OBJECT_CONF_INVALIDATE; | |
268 | conf.coc_inode = inode; | |
269 | rc = ll_layout_conf(inode, &conf); | |
270 | if (rc) | |
271 | CDEBUG(D_INODE, "invaliding layout %d.\n", rc); | |
272 | } | |
273 | ||
ae5ef67b SB |
274 | if (bits & MDS_INODELOCK_UPDATE) { |
275 | spin_lock(&lli->lli_lock); | |
d7e09d03 | 276 | lli->lli_flags &= ~LLIF_MDS_SIZE_LOCK; |
ae5ef67b SB |
277 | spin_unlock(&lli->lli_lock); |
278 | } | |
d7e09d03 PT |
279 | |
280 | if (S_ISDIR(inode->i_mode) && | |
281 | (bits & MDS_INODELOCK_UPDATE)) { | |
282 | CDEBUG(D_INODE, "invalidating inode %lu\n", | |
283 | inode->i_ino); | |
284 | truncate_inode_pages(inode->i_mapping, 0); | |
285 | ll_invalidate_negative_children(inode); | |
286 | } | |
287 | ||
288 | if (inode->i_sb->s_root && | |
289 | inode != inode->i_sb->s_root->d_inode && | |
290 | (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM))) | |
291 | ll_invalidate_aliases(inode); | |
292 | iput(inode); | |
293 | break; | |
294 | } | |
295 | default: | |
296 | LBUG(); | |
297 | } | |
298 | ||
299 | RETURN(0); | |
300 | } | |
301 | ||
302 | __u32 ll_i2suppgid(struct inode *i) | |
303 | { | |
4b1a25f0 PT |
304 | if (in_group_p(i->i_gid)) |
305 | return (__u32)from_kgid(&init_user_ns, i->i_gid); | |
d7e09d03 PT |
306 | else |
307 | return (__u32)(-1); | |
308 | } | |
309 | ||
310 | /* Pack the required supplementary groups into the supplied groups array. | |
311 | * If we don't need to use the groups from the target inode(s) then we | |
312 | * instead pack one or more groups from the user's supplementary group | |
313 | * array in case it might be useful. Not needed if doing an MDS-side upcall. */ | |
314 | void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2) | |
315 | { | |
316 | #if 0 | |
317 | int i; | |
318 | #endif | |
319 | ||
320 | LASSERT(i1 != NULL); | |
321 | LASSERT(suppgids != NULL); | |
322 | ||
323 | suppgids[0] = ll_i2suppgid(i1); | |
324 | ||
325 | if (i2) | |
326 | suppgids[1] = ll_i2suppgid(i2); | |
327 | else | |
328 | suppgids[1] = -1; | |
329 | ||
330 | #if 0 | |
331 | for (i = 0; i < current_ngroups; i++) { | |
332 | if (suppgids[0] == -1) { | |
333 | if (current_groups[i] != suppgids[1]) | |
334 | suppgids[0] = current_groups[i]; | |
335 | continue; | |
336 | } | |
337 | if (suppgids[1] == -1) { | |
338 | if (current_groups[i] != suppgids[0]) | |
339 | suppgids[1] = current_groups[i]; | |
340 | continue; | |
341 | } | |
342 | break; | |
343 | } | |
344 | #endif | |
345 | } | |
346 | ||
347 | /* | |
348 | * try to reuse three types of dentry: | |
349 | * 1. unhashed alias, this one is unhashed by d_invalidate (but it may be valid | |
350 | * by concurrent .revalidate). | |
351 | * 2. INVALID alias (common case for no valid ldlm lock held, but this flag may | |
352 | * be cleared by others calling d_lustre_revalidate). | |
353 | * 3. DISCONNECTED alias. | |
354 | */ | |
355 | static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry) | |
356 | { | |
357 | struct dentry *alias, *discon_alias, *invalid_alias; | |
358 | struct ll_d_hlist_node *p; | |
359 | ||
360 | if (ll_d_hlist_empty(&inode->i_dentry)) | |
361 | return NULL; | |
362 | ||
363 | discon_alias = invalid_alias = NULL; | |
364 | ||
365 | ll_lock_dcache(inode); | |
366 | ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) { | |
367 | LASSERT(alias != dentry); | |
368 | ||
369 | spin_lock(&alias->d_lock); | |
370 | if (alias->d_flags & DCACHE_DISCONNECTED) | |
371 | /* LASSERT(last_discon == NULL); LU-405, bz 20055 */ | |
372 | discon_alias = alias; | |
373 | else if (alias->d_parent == dentry->d_parent && | |
374 | alias->d_name.hash == dentry->d_name.hash && | |
375 | alias->d_name.len == dentry->d_name.len && | |
376 | memcmp(alias->d_name.name, dentry->d_name.name, | |
377 | dentry->d_name.len) == 0) | |
378 | invalid_alias = alias; | |
379 | spin_unlock(&alias->d_lock); | |
380 | ||
381 | if (invalid_alias) | |
382 | break; | |
383 | } | |
384 | alias = invalid_alias ?: discon_alias ?: NULL; | |
385 | if (alias) { | |
386 | spin_lock(&alias->d_lock); | |
387 | dget_dlock(alias); | |
388 | spin_unlock(&alias->d_lock); | |
389 | } | |
390 | ll_unlock_dcache(inode); | |
391 | ||
392 | return alias; | |
393 | } | |
394 | ||
395 | /* | |
396 | * Similar to d_splice_alias(), but lustre treats invalid alias | |
397 | * similar to DCACHE_DISCONNECTED, and tries to use it anyway. | |
398 | */ | |
399 | struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de) | |
400 | { | |
401 | struct dentry *new; | |
402 | ||
403 | if (inode) { | |
404 | new = ll_find_alias(inode, de); | |
405 | if (new) { | |
406 | ll_dops_init(new, 1, 1); | |
407 | d_move(new, de); | |
408 | iput(inode); | |
409 | CDEBUG(D_DENTRY, | |
410 | "Reuse dentry %p inode %p refc %d flags %#x\n", | |
193deee1 | 411 | new, new->d_inode, d_count(new), new->d_flags); |
d7e09d03 PT |
412 | return new; |
413 | } | |
414 | } | |
415 | ll_dops_init(de, 1, 1); | |
416 | __d_lustre_invalidate(de); | |
417 | d_add(de, inode); | |
418 | CDEBUG(D_DENTRY, "Add dentry %p inode %p refc %d flags %#x\n", | |
193deee1 | 419 | de, de->d_inode, d_count(de), de->d_flags); |
d7e09d03 PT |
420 | return de; |
421 | } | |
422 | ||
423 | int ll_lookup_it_finish(struct ptlrpc_request *request, | |
424 | struct lookup_intent *it, void *data) | |
425 | { | |
426 | struct it_cb_data *icbd = data; | |
427 | struct dentry **de = icbd->icbd_childp; | |
428 | struct inode *parent = icbd->icbd_parent; | |
429 | struct inode *inode = NULL; | |
430 | __u64 bits = 0; | |
431 | int rc; | |
d7e09d03 PT |
432 | |
433 | /* NB 1 request reference will be taken away by ll_intent_lock() | |
434 | * when I return */ | |
435 | CDEBUG(D_DENTRY, "it %p it_disposition %x\n", it, | |
436 | it->d.lustre.it_disposition); | |
437 | if (!it_disposition(it, DISP_LOOKUP_NEG)) { | |
438 | rc = ll_prep_inode(&inode, request, (*de)->d_sb, it); | |
439 | if (rc) | |
440 | RETURN(rc); | |
441 | ||
442 | ll_set_lock_data(ll_i2sbi(parent)->ll_md_exp, inode, it, &bits); | |
443 | ||
444 | /* We used to query real size from OSTs here, but actually | |
445 | this is not needed. For stat() calls size would be updated | |
446 | from subsequent do_revalidate()->ll_inode_revalidate_it() in | |
447 | 2.4 and | |
448 | vfs_getattr_it->ll_getattr()->ll_inode_revalidate_it() in 2.6 | |
449 | Everybody else who needs correct file size would call | |
450 | ll_glimpse_size or some equivalent themselves anyway. | |
451 | Also see bug 7198. */ | |
452 | } | |
453 | ||
454 | /* Only hash *de if it is unhashed (new dentry). | |
455 | * Atoimc_open may passin hashed dentries for open. | |
456 | */ | |
457 | if (d_unhashed(*de)) | |
458 | *de = ll_splice_alias(inode, *de); | |
459 | ||
460 | if (!it_disposition(it, DISP_LOOKUP_NEG)) { | |
461 | /* we have lookup look - unhide dentry */ | |
462 | if (bits & MDS_INODELOCK_LOOKUP) | |
463 | d_lustre_revalidate(*de); | |
464 | } else if (!it_disposition(it, DISP_OPEN_CREATE)) { | |
465 | /* If file created on server, don't depend on parent UPDATE | |
466 | * lock to unhide it. It is left hidden and next lookup can | |
467 | * find it in ll_splice_alias. | |
468 | */ | |
469 | /* Check that parent has UPDATE lock. */ | |
470 | struct lookup_intent parent_it = { | |
471 | .it_op = IT_GETATTR, | |
472 | .d.lustre.it_lock_handle = 0 }; | |
473 | ||
474 | if (md_revalidate_lock(ll_i2mdexp(parent), &parent_it, | |
475 | &ll_i2info(parent)->lli_fid, NULL)) { | |
476 | d_lustre_revalidate(*de); | |
477 | ll_intent_release(&parent_it); | |
478 | } | |
479 | } | |
480 | ||
481 | RETURN(0); | |
482 | } | |
483 | ||
484 | static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, | |
485 | struct lookup_intent *it, int lookup_flags) | |
486 | { | |
487 | struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; | |
488 | struct dentry *save = dentry, *retval; | |
489 | struct ptlrpc_request *req = NULL; | |
490 | struct md_op_data *op_data; | |
491 | struct it_cb_data icbd; | |
492 | __u32 opc; | |
493 | int rc; | |
d7e09d03 PT |
494 | |
495 | if (dentry->d_name.len > ll_i2sbi(parent)->ll_namelen) | |
496 | RETURN(ERR_PTR(-ENAMETOOLONG)); | |
497 | ||
498 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n", | |
499 | dentry->d_name.len, dentry->d_name.name, parent->i_ino, | |
500 | parent->i_generation, parent, LL_IT2STR(it)); | |
501 | ||
502 | if (d_mountpoint(dentry)) | |
503 | CERROR("Tell Peter, lookup on mtpt, it %s\n", LL_IT2STR(it)); | |
504 | ||
505 | ll_frob_intent(&it, &lookup_it); | |
506 | ||
507 | /* As do_lookup is called before follow_mount, root dentry may be left | |
508 | * not valid, revalidate it here. */ | |
509 | if (parent->i_sb->s_root && (parent->i_sb->s_root->d_inode == parent) && | |
510 | (it->it_op & (IT_OPEN | IT_CREAT))) { | |
511 | rc = ll_inode_revalidate_it(parent->i_sb->s_root, it, | |
512 | MDS_INODELOCK_LOOKUP); | |
513 | if (rc) | |
514 | RETURN(ERR_PTR(rc)); | |
515 | } | |
516 | ||
517 | if (it->it_op == IT_GETATTR) { | |
518 | rc = ll_statahead_enter(parent, &dentry, 0); | |
519 | if (rc == 1) { | |
520 | if (dentry == save) | |
521 | GOTO(out, retval = NULL); | |
522 | GOTO(out, retval = dentry); | |
523 | } | |
524 | } | |
525 | ||
526 | icbd.icbd_childp = &dentry; | |
527 | icbd.icbd_parent = parent; | |
528 | ||
529 | if (it->it_op & IT_CREAT || | |
530 | (it->it_op & IT_OPEN && it->it_create_mode & O_CREAT)) | |
531 | opc = LUSTRE_OPC_CREATE; | |
532 | else | |
533 | opc = LUSTRE_OPC_ANY; | |
534 | ||
535 | op_data = ll_prep_md_op_data(NULL, parent, NULL, dentry->d_name.name, | |
536 | dentry->d_name.len, lookup_flags, opc, | |
537 | NULL); | |
538 | if (IS_ERR(op_data)) | |
539 | RETURN((void *)op_data); | |
540 | ||
541 | /* enforce umask if acl disabled or MDS doesn't support umask */ | |
542 | if (!IS_POSIXACL(parent) || !exp_connect_umask(ll_i2mdexp(parent))) | |
543 | it->it_create_mode &= ~current_umask(); | |
544 | ||
545 | rc = md_intent_lock(ll_i2mdexp(parent), op_data, NULL, 0, it, | |
546 | lookup_flags, &req, ll_md_blocking_ast, 0); | |
547 | ll_finish_md_op_data(op_data); | |
548 | if (rc < 0) | |
549 | GOTO(out, retval = ERR_PTR(rc)); | |
550 | ||
551 | rc = ll_lookup_it_finish(req, it, &icbd); | |
552 | if (rc != 0) { | |
553 | ll_intent_release(it); | |
554 | GOTO(out, retval = ERR_PTR(rc)); | |
555 | } | |
556 | ||
557 | if ((it->it_op & IT_OPEN) && dentry->d_inode && | |
558 | !S_ISREG(dentry->d_inode->i_mode) && | |
559 | !S_ISDIR(dentry->d_inode->i_mode)) { | |
560 | ll_release_openhandle(dentry, it); | |
561 | } | |
562 | ll_lookup_finish_locks(it, dentry); | |
563 | ||
564 | if (dentry == save) | |
565 | GOTO(out, retval = NULL); | |
566 | else | |
567 | GOTO(out, retval = dentry); | |
568 | out: | |
569 | if (req) | |
570 | ptlrpc_req_finished(req); | |
571 | if (it->it_op == IT_GETATTR && (retval == NULL || retval == dentry)) | |
572 | ll_statahead_mark(parent, dentry); | |
573 | return retval; | |
574 | } | |
575 | ||
576 | static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, | |
577 | unsigned int flags) | |
578 | { | |
579 | struct lookup_intent *itp, it = { .it_op = IT_GETATTR }; | |
580 | struct dentry *de; | |
581 | ||
582 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),flags=%u\n", | |
583 | dentry->d_name.len, dentry->d_name.name, parent->i_ino, | |
584 | parent->i_generation, parent, flags); | |
585 | ||
586 | /* Optimize away (CREATE && !OPEN). Let .create handle the race. */ | |
587 | if ((flags & LOOKUP_CREATE ) && !(flags & LOOKUP_OPEN)) { | |
588 | ll_dops_init(dentry, 1, 1); | |
589 | __d_lustre_invalidate(dentry); | |
590 | d_add(dentry, NULL); | |
591 | return NULL; | |
592 | } | |
593 | ||
594 | if (flags & (LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE)) | |
595 | itp = NULL; | |
596 | else | |
597 | itp = ⁢ | |
598 | de = ll_lookup_it(parent, dentry, itp, 0); | |
599 | ||
600 | if (itp != NULL) | |
601 | ll_intent_release(itp); | |
602 | ||
603 | return de; | |
604 | } | |
605 | ||
606 | /* | |
607 | * For cached negative dentry and new dentry, handle lookup/create/open | |
608 | * together. | |
609 | */ | |
610 | static int ll_atomic_open(struct inode *dir, struct dentry *dentry, | |
611 | struct file *file, unsigned open_flags, | |
612 | umode_t mode, int *opened) | |
613 | { | |
614 | struct lookup_intent *it; | |
615 | struct dentry *de; | |
616 | long long lookup_flags = LOOKUP_OPEN; | |
617 | int rc = 0; | |
d7e09d03 PT |
618 | |
619 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),file %p," | |
620 | "open_flags %x,mode %x opened %d\n", | |
621 | dentry->d_name.len, dentry->d_name.name, dir->i_ino, | |
622 | dir->i_generation, dir, file, open_flags, mode, *opened); | |
623 | ||
624 | OBD_ALLOC(it, sizeof(*it)); | |
625 | if (!it) | |
626 | RETURN(-ENOMEM); | |
627 | ||
628 | it->it_op = IT_OPEN; | |
629 | if (mode) { | |
630 | it->it_op |= IT_CREAT; | |
631 | lookup_flags |= LOOKUP_CREATE; | |
632 | } | |
633 | it->it_create_mode = (mode & S_IALLUGO) | S_IFREG; | |
634 | it->it_flags = (open_flags & ~O_ACCMODE) | OPEN_FMODE(open_flags); | |
635 | ||
636 | /* Dentry added to dcache tree in ll_lookup_it */ | |
637 | de = ll_lookup_it(dir, dentry, it, lookup_flags); | |
638 | if (IS_ERR(de)) | |
639 | rc = PTR_ERR(de); | |
640 | else if (de != NULL) | |
641 | dentry = de; | |
642 | ||
643 | if (!rc) { | |
644 | if (it_disposition(it, DISP_OPEN_CREATE)) { | |
645 | /* Dentry instantiated in ll_create_it. */ | |
646 | rc = ll_create_it(dir, dentry, mode, it); | |
647 | if (rc) { | |
648 | /* We dget in ll_splice_alias. */ | |
649 | if (de != NULL) | |
650 | dput(de); | |
651 | goto out_release; | |
652 | } | |
653 | ||
654 | *opened |= FILE_CREATED; | |
655 | } | |
656 | if (dentry->d_inode && it_disposition(it, DISP_OPEN_OPEN)) { | |
657 | /* Open dentry. */ | |
658 | if (S_ISFIFO(dentry->d_inode->i_mode)) { | |
659 | /* We cannot call open here as it would | |
660 | * deadlock. | |
661 | */ | |
662 | if (it_disposition(it, DISP_ENQ_OPEN_REF)) | |
663 | ptlrpc_req_finished( | |
664 | (struct ptlrpc_request *) | |
665 | it->d.lustre.it_data); | |
666 | rc = finish_no_open(file, de); | |
667 | } else { | |
668 | file->private_data = it; | |
669 | rc = finish_open(file, dentry, NULL, opened); | |
670 | /* We dget in ll_splice_alias. finish_open takes | |
671 | * care of dget for fd open. | |
672 | */ | |
673 | if (de != NULL) | |
674 | dput(de); | |
675 | } | |
676 | } else { | |
677 | rc = finish_no_open(file, de); | |
678 | } | |
679 | } | |
680 | ||
681 | out_release: | |
682 | ll_intent_release(it); | |
683 | OBD_FREE(it, sizeof(*it)); | |
684 | ||
685 | RETURN(rc); | |
686 | } | |
687 | ||
688 | ||
689 | /* We depend on "mode" being set with the proper file type/umask by now */ | |
690 | static struct inode *ll_create_node(struct inode *dir, const char *name, | |
691 | int namelen, const void *data, int datalen, | |
692 | int mode, __u64 extra, | |
693 | struct lookup_intent *it) | |
694 | { | |
695 | struct inode *inode = NULL; | |
696 | struct ptlrpc_request *request = NULL; | |
697 | struct ll_sb_info *sbi = ll_i2sbi(dir); | |
698 | int rc; | |
d7e09d03 PT |
699 | |
700 | LASSERT(it && it->d.lustre.it_disposition); | |
701 | ||
702 | LASSERT(it_disposition(it, DISP_ENQ_CREATE_REF)); | |
703 | request = it->d.lustre.it_data; | |
704 | it_clear_disposition(it, DISP_ENQ_CREATE_REF); | |
705 | rc = ll_prep_inode(&inode, request, dir->i_sb, it); | |
706 | if (rc) | |
707 | GOTO(out, inode = ERR_PTR(rc)); | |
708 | ||
709 | LASSERT(ll_d_hlist_empty(&inode->i_dentry)); | |
710 | ||
711 | /* We asked for a lock on the directory, but were granted a | |
712 | * lock on the inode. Since we finally have an inode pointer, | |
713 | * stuff it in the lock. */ | |
714 | CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n", | |
715 | inode, inode->i_ino, inode->i_generation); | |
716 | ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL); | |
d7e09d03 PT |
717 | out: |
718 | ptlrpc_req_finished(request); | |
719 | return inode; | |
720 | } | |
721 | ||
722 | /* | |
723 | * By the time this is called, we already have created the directory cache | |
724 | * entry for the new file, but it is so far negative - it has no inode. | |
725 | * | |
726 | * We defer creating the OBD object(s) until open, to keep the intent and | |
727 | * non-intent code paths similar, and also because we do not have the MDS | |
728 | * inode number before calling ll_create_node() (which is needed for LOV), | |
729 | * so we would need to do yet another RPC to the MDS to store the LOV EA | |
730 | * data on the MDS. If needed, we would pass the PACKED lmm as data and | |
731 | * lmm_size in datalen (the MDS still has code which will handle that). | |
732 | * | |
733 | * If the create succeeds, we fill in the inode information | |
734 | * with d_instantiate(). | |
735 | */ | |
736 | static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode, | |
737 | struct lookup_intent *it) | |
738 | { | |
739 | struct inode *inode; | |
740 | int rc = 0; | |
d7e09d03 PT |
741 | |
742 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n", | |
743 | dentry->d_name.len, dentry->d_name.name, dir->i_ino, | |
744 | dir->i_generation, dir, LL_IT2STR(it)); | |
745 | ||
746 | rc = it_open_error(DISP_OPEN_CREATE, it); | |
747 | if (rc) | |
748 | RETURN(rc); | |
749 | ||
750 | inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, | |
751 | NULL, 0, mode, 0, it); | |
752 | if (IS_ERR(inode)) | |
753 | RETURN(PTR_ERR(inode)); | |
754 | ||
755 | if (filename_is_volatile(dentry->d_name.name, dentry->d_name.len, NULL)) | |
756 | ll_i2info(inode)->lli_volatile = true; | |
757 | ||
758 | d_instantiate(dentry, inode); | |
759 | RETURN(0); | |
760 | } | |
761 | ||
762 | static void ll_update_times(struct ptlrpc_request *request, | |
763 | struct inode *inode) | |
764 | { | |
765 | struct mdt_body *body = req_capsule_server_get(&request->rq_pill, | |
766 | &RMF_MDT_BODY); | |
767 | ||
768 | LASSERT(body); | |
769 | if (body->valid & OBD_MD_FLMTIME && | |
770 | body->mtime > LTIME_S(inode->i_mtime)) { | |
771 | CDEBUG(D_INODE, "setting ino %lu mtime from %lu to "LPU64"\n", | |
772 | inode->i_ino, LTIME_S(inode->i_mtime), body->mtime); | |
773 | LTIME_S(inode->i_mtime) = body->mtime; | |
774 | } | |
775 | if (body->valid & OBD_MD_FLCTIME && | |
776 | body->ctime > LTIME_S(inode->i_ctime)) | |
777 | LTIME_S(inode->i_ctime) = body->ctime; | |
778 | } | |
779 | ||
780 | static int ll_new_node(struct inode *dir, struct qstr *name, | |
781 | const char *tgt, int mode, int rdev, | |
782 | struct dentry *dchild, __u32 opc) | |
783 | { | |
784 | struct ptlrpc_request *request = NULL; | |
785 | struct md_op_data *op_data; | |
786 | struct inode *inode = NULL; | |
787 | struct ll_sb_info *sbi = ll_i2sbi(dir); | |
788 | int tgt_len = 0; | |
789 | int err; | |
790 | ||
d7e09d03 PT |
791 | if (unlikely(tgt != NULL)) |
792 | tgt_len = strlen(tgt) + 1; | |
793 | ||
794 | op_data = ll_prep_md_op_data(NULL, dir, NULL, name->name, | |
795 | name->len, 0, opc, NULL); | |
796 | if (IS_ERR(op_data)) | |
797 | GOTO(err_exit, err = PTR_ERR(op_data)); | |
798 | ||
799 | err = md_create(sbi->ll_md_exp, op_data, tgt, tgt_len, mode, | |
4b1a25f0 PT |
800 | from_kuid(&init_user_ns, current_fsuid()), |
801 | from_kgid(&init_user_ns, current_fsgid()), | |
d7e09d03 PT |
802 | cfs_curproc_cap_pack(), rdev, &request); |
803 | ll_finish_md_op_data(op_data); | |
804 | if (err) | |
805 | GOTO(err_exit, err); | |
806 | ||
807 | ll_update_times(request, dir); | |
808 | ||
809 | if (dchild) { | |
810 | err = ll_prep_inode(&inode, request, dchild->d_sb, NULL); | |
811 | if (err) | |
812 | GOTO(err_exit, err); | |
813 | ||
814 | d_instantiate(dchild, inode); | |
815 | } | |
d7e09d03 PT |
816 | err_exit: |
817 | ptlrpc_req_finished(request); | |
818 | ||
819 | return err; | |
820 | } | |
821 | ||
822 | static int ll_mknod_generic(struct inode *dir, struct qstr *name, int mode, | |
823 | unsigned rdev, struct dentry *dchild) | |
824 | { | |
825 | int err; | |
d7e09d03 PT |
826 | |
827 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p) mode %o dev %x\n", | |
828 | name->len, name->name, dir->i_ino, dir->i_generation, dir, | |
829 | mode, rdev); | |
830 | ||
831 | if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir))) | |
832 | mode &= ~current_umask(); | |
833 | ||
834 | switch (mode & S_IFMT) { | |
835 | case 0: | |
836 | mode |= S_IFREG; /* for mode = 0 case, fallthrough */ | |
837 | case S_IFREG: | |
838 | case S_IFCHR: | |
839 | case S_IFBLK: | |
840 | case S_IFIFO: | |
841 | case S_IFSOCK: | |
842 | err = ll_new_node(dir, name, NULL, mode, rdev, dchild, | |
843 | LUSTRE_OPC_MKNOD); | |
844 | break; | |
845 | case S_IFDIR: | |
846 | err = -EPERM; | |
847 | break; | |
848 | default: | |
849 | err = -EINVAL; | |
850 | } | |
851 | ||
852 | if (!err) | |
853 | ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_MKNOD, 1); | |
854 | ||
855 | RETURN(err); | |
856 | } | |
857 | ||
858 | /* | |
859 | * Plain create. Intent create is handled in atomic_open. | |
860 | */ | |
861 | static int ll_create_nd(struct inode *dir, struct dentry *dentry, | |
862 | umode_t mode, bool want_excl) | |
863 | { | |
864 | int rc; | |
865 | ||
866 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)," | |
867 | "flags=%u, excl=%d\n", | |
868 | dentry->d_name.len, dentry->d_name.name, dir->i_ino, | |
869 | dir->i_generation, dir, mode, want_excl); | |
870 | ||
871 | rc = ll_mknod_generic(dir, &dentry->d_name, mode, 0, dentry); | |
872 | ||
873 | ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_CREATE, 1); | |
874 | ||
875 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s, unhashed %d\n", | |
876 | dentry->d_name.len, dentry->d_name.name, d_unhashed(dentry)); | |
877 | ||
878 | return rc; | |
879 | } | |
880 | ||
881 | static int ll_symlink_generic(struct inode *dir, struct qstr *name, | |
882 | const char *tgt, struct dentry *dchild) | |
883 | { | |
884 | int err; | |
d7e09d03 PT |
885 | |
886 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),target=%.*s\n", | |
887 | name->len, name->name, dir->i_ino, dir->i_generation, | |
888 | dir, 3000, tgt); | |
889 | ||
890 | err = ll_new_node(dir, name, (char *)tgt, S_IFLNK | S_IRWXUGO, | |
891 | 0, dchild, LUSTRE_OPC_SYMLINK); | |
892 | ||
893 | if (!err) | |
894 | ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_SYMLINK, 1); | |
895 | ||
896 | RETURN(err); | |
897 | } | |
898 | ||
899 | static int ll_link_generic(struct inode *src, struct inode *dir, | |
900 | struct qstr *name, struct dentry *dchild) | |
901 | { | |
902 | struct ll_sb_info *sbi = ll_i2sbi(dir); | |
903 | struct ptlrpc_request *request = NULL; | |
904 | struct md_op_data *op_data; | |
905 | int err; | |
906 | ||
d7e09d03 PT |
907 | CDEBUG(D_VFSTRACE, |
908 | "VFS Op: inode=%lu/%u(%p), dir=%lu/%u(%p), target=%.*s\n", | |
909 | src->i_ino, src->i_generation, src, dir->i_ino, | |
910 | dir->i_generation, dir, name->len, name->name); | |
911 | ||
912 | op_data = ll_prep_md_op_data(NULL, src, dir, name->name, name->len, | |
913 | 0, LUSTRE_OPC_ANY, NULL); | |
914 | if (IS_ERR(op_data)) | |
915 | RETURN(PTR_ERR(op_data)); | |
916 | ||
917 | err = md_link(sbi->ll_md_exp, op_data, &request); | |
918 | ll_finish_md_op_data(op_data); | |
919 | if (err) | |
920 | GOTO(out, err); | |
921 | ||
922 | ll_update_times(request, dir); | |
923 | ll_stats_ops_tally(sbi, LPROC_LL_LINK, 1); | |
d7e09d03 PT |
924 | out: |
925 | ptlrpc_req_finished(request); | |
926 | RETURN(err); | |
927 | } | |
928 | ||
929 | static int ll_mkdir_generic(struct inode *dir, struct qstr *name, | |
930 | int mode, struct dentry *dchild) | |
931 | ||
932 | { | |
933 | int err; | |
d7e09d03 PT |
934 | |
935 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", | |
936 | name->len, name->name, dir->i_ino, dir->i_generation, dir); | |
937 | ||
938 | if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir))) | |
939 | mode &= ~current_umask(); | |
940 | mode = (mode & (S_IRWXUGO|S_ISVTX)) | S_IFDIR; | |
941 | err = ll_new_node(dir, name, NULL, mode, 0, dchild, LUSTRE_OPC_MKDIR); | |
942 | ||
943 | if (!err) | |
944 | ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_MKDIR, 1); | |
945 | ||
946 | RETURN(err); | |
947 | } | |
948 | ||
949 | /* Try to find the child dentry by its name. | |
950 | If found, put the result fid into @fid. */ | |
951 | static void ll_get_child_fid(struct inode * dir, struct qstr *name, | |
952 | struct lu_fid *fid) | |
953 | { | |
954 | struct dentry *parent, *child; | |
955 | ||
956 | parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_alias); | |
957 | child = d_lookup(parent, name); | |
958 | if (child) { | |
959 | if (child->d_inode) | |
960 | *fid = *ll_inode2fid(child->d_inode); | |
961 | dput(child); | |
962 | } | |
963 | } | |
964 | ||
965 | static int ll_rmdir_generic(struct inode *dir, struct dentry *dparent, | |
966 | struct dentry *dchild, struct qstr *name) | |
967 | { | |
968 | struct ptlrpc_request *request = NULL; | |
969 | struct md_op_data *op_data; | |
970 | int rc; | |
d7e09d03 PT |
971 | |
972 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", | |
973 | name->len, name->name, dir->i_ino, dir->i_generation, dir); | |
974 | ||
975 | if (unlikely(ll_d_mountpoint(dparent, dchild, name))) | |
976 | RETURN(-EBUSY); | |
977 | ||
978 | op_data = ll_prep_md_op_data(NULL, dir, NULL, name->name, name->len, | |
979 | S_IFDIR, LUSTRE_OPC_ANY, NULL); | |
980 | if (IS_ERR(op_data)) | |
981 | RETURN(PTR_ERR(op_data)); | |
982 | ||
983 | ll_get_child_fid(dir, name, &op_data->op_fid3); | |
984 | op_data->op_fid2 = op_data->op_fid3; | |
985 | rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); | |
986 | ll_finish_md_op_data(op_data); | |
987 | if (rc == 0) { | |
988 | ll_update_times(request, dir); | |
989 | ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_RMDIR, 1); | |
990 | } | |
991 | ||
992 | ptlrpc_req_finished(request); | |
993 | RETURN(rc); | |
994 | } | |
995 | ||
996 | /** | |
997 | * Remove dir entry | |
998 | **/ | |
999 | int ll_rmdir_entry(struct inode *dir, char *name, int namelen) | |
1000 | { | |
1001 | struct ptlrpc_request *request = NULL; | |
1002 | struct md_op_data *op_data; | |
1003 | int rc; | |
d7e09d03 PT |
1004 | |
1005 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", | |
1006 | namelen, name, dir->i_ino, dir->i_generation, dir); | |
1007 | ||
1008 | op_data = ll_prep_md_op_data(NULL, dir, NULL, name, strlen(name), | |
1009 | S_IFDIR, LUSTRE_OPC_ANY, NULL); | |
1010 | if (IS_ERR(op_data)) | |
1011 | RETURN(PTR_ERR(op_data)); | |
1012 | op_data->op_cli_flags |= CLI_RM_ENTRY; | |
1013 | rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); | |
1014 | ll_finish_md_op_data(op_data); | |
1015 | if (rc == 0) { | |
1016 | ll_update_times(request, dir); | |
1017 | ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_RMDIR, 1); | |
1018 | } | |
1019 | ||
1020 | ptlrpc_req_finished(request); | |
1021 | RETURN(rc); | |
1022 | } | |
1023 | ||
1024 | int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir) | |
1025 | { | |
1026 | struct mdt_body *body; | |
1027 | struct lov_mds_md *eadata; | |
1028 | struct lov_stripe_md *lsm = NULL; | |
1029 | struct obd_trans_info oti = { 0 }; | |
1030 | struct obdo *oa; | |
1031 | struct obd_capa *oc = NULL; | |
1032 | int rc; | |
d7e09d03 PT |
1033 | |
1034 | /* req is swabbed so this is safe */ | |
1035 | body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); | |
1036 | if (!(body->valid & OBD_MD_FLEASIZE)) | |
1037 | RETURN(0); | |
1038 | ||
1039 | if (body->eadatasize == 0) { | |
1040 | CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n"); | |
1041 | GOTO(out, rc = -EPROTO); | |
1042 | } | |
1043 | ||
1044 | /* The MDS sent back the EA because we unlinked the last reference | |
1045 | * to this file. Use this EA to unlink the objects on the OST. | |
1046 | * It's opaque so we don't swab here; we leave it to obd_unpackmd() to | |
1047 | * check it is complete and sensible. */ | |
1048 | eadata = req_capsule_server_sized_get(&request->rq_pill, &RMF_MDT_MD, | |
1049 | body->eadatasize); | |
1050 | LASSERT(eadata != NULL); | |
1051 | ||
1052 | rc = obd_unpackmd(ll_i2dtexp(dir), &lsm, eadata, body->eadatasize); | |
1053 | if (rc < 0) { | |
1054 | CERROR("obd_unpackmd: %d\n", rc); | |
1055 | GOTO(out, rc); | |
1056 | } | |
1057 | LASSERT(rc >= sizeof(*lsm)); | |
1058 | ||
1059 | OBDO_ALLOC(oa); | |
1060 | if (oa == NULL) | |
1061 | GOTO(out_free_memmd, rc = -ENOMEM); | |
1062 | ||
1063 | oa->o_oi = lsm->lsm_oi; | |
1064 | oa->o_mode = body->mode & S_IFMT; | |
1065 | oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP; | |
1066 | ||
1067 | if (body->valid & OBD_MD_FLCOOKIE) { | |
1068 | oa->o_valid |= OBD_MD_FLCOOKIE; | |
1069 | oti.oti_logcookies = | |
1070 | req_capsule_server_sized_get(&request->rq_pill, | |
1071 | &RMF_LOGCOOKIES, | |
1072 | sizeof(struct llog_cookie) * | |
1073 | lsm->lsm_stripe_count); | |
1074 | if (oti.oti_logcookies == NULL) { | |
1075 | oa->o_valid &= ~OBD_MD_FLCOOKIE; | |
1076 | body->valid &= ~OBD_MD_FLCOOKIE; | |
1077 | } | |
1078 | } | |
1079 | ||
1080 | if (body->valid & OBD_MD_FLOSSCAPA) { | |
1081 | rc = md_unpack_capa(ll_i2mdexp(dir), request, &RMF_CAPA2, &oc); | |
1082 | if (rc) | |
1083 | GOTO(out_free_memmd, rc); | |
1084 | } | |
1085 | ||
1086 | rc = obd_destroy(NULL, ll_i2dtexp(dir), oa, lsm, &oti, | |
1087 | ll_i2mdexp(dir), oc); | |
1088 | capa_put(oc); | |
1089 | if (rc) | |
1090 | CERROR("obd destroy objid "DOSTID" error %d\n", | |
1091 | POSTID(&lsm->lsm_oi), rc); | |
1092 | out_free_memmd: | |
1093 | obd_free_memmd(ll_i2dtexp(dir), &lsm); | |
1094 | OBDO_FREE(oa); | |
1095 | out: | |
1096 | return rc; | |
1097 | } | |
1098 | ||
1099 | /* ll_unlink_generic() doesn't update the inode with the new link count. | |
1100 | * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there | |
1101 | * is any lock existing. They will recycle dentries and inodes based upon locks | |
1102 | * too. b=20433 */ | |
1103 | static int ll_unlink_generic(struct inode *dir, struct dentry *dparent, | |
1104 | struct dentry *dchild, struct qstr *name) | |
1105 | { | |
1106 | struct ptlrpc_request *request = NULL; | |
1107 | struct md_op_data *op_data; | |
1108 | int rc; | |
d7e09d03 PT |
1109 | CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", |
1110 | name->len, name->name, dir->i_ino, dir->i_generation, dir); | |
1111 | ||
1112 | /* | |
1113 | * XXX: unlink bind mountpoint maybe call to here, | |
1114 | * just check it as vfs_unlink does. | |
1115 | */ | |
1116 | if (unlikely(ll_d_mountpoint(dparent, dchild, name))) | |
1117 | RETURN(-EBUSY); | |
1118 | ||
1119 | op_data = ll_prep_md_op_data(NULL, dir, NULL, name->name, | |
1120 | name->len, 0, LUSTRE_OPC_ANY, NULL); | |
1121 | if (IS_ERR(op_data)) | |
1122 | RETURN(PTR_ERR(op_data)); | |
1123 | ||
1124 | ll_get_child_fid(dir, name, &op_data->op_fid3); | |
1125 | op_data->op_fid2 = op_data->op_fid3; | |
1126 | rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); | |
1127 | ll_finish_md_op_data(op_data); | |
1128 | if (rc) | |
1129 | GOTO(out, rc); | |
1130 | ||
1131 | ll_update_times(request, dir); | |
1132 | ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_UNLINK, 1); | |
1133 | ||
1134 | rc = ll_objects_destroy(request, dir); | |
1135 | out: | |
1136 | ptlrpc_req_finished(request); | |
1137 | RETURN(rc); | |
1138 | } | |
1139 | ||
1140 | static int ll_rename_generic(struct inode *src, struct dentry *src_dparent, | |
1141 | struct dentry *src_dchild, struct qstr *src_name, | |
1142 | struct inode *tgt, struct dentry *tgt_dparent, | |
1143 | struct dentry *tgt_dchild, struct qstr *tgt_name) | |
1144 | { | |
1145 | struct ptlrpc_request *request = NULL; | |
1146 | struct ll_sb_info *sbi = ll_i2sbi(src); | |
1147 | struct md_op_data *op_data; | |
1148 | int err; | |
29aaf496 | 1149 | |
d7e09d03 PT |
1150 | CDEBUG(D_VFSTRACE,"VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s," |
1151 | "tgt_dir=%lu/%u(%p)\n", src_name->len, src_name->name, | |
1152 | src->i_ino, src->i_generation, src, tgt_name->len, | |
1153 | tgt_name->name, tgt->i_ino, tgt->i_generation, tgt); | |
1154 | ||
1155 | if (unlikely(ll_d_mountpoint(src_dparent, src_dchild, src_name) || | |
1156 | ll_d_mountpoint(tgt_dparent, tgt_dchild, tgt_name))) | |
1157 | RETURN(-EBUSY); | |
1158 | ||
1159 | op_data = ll_prep_md_op_data(NULL, src, tgt, NULL, 0, 0, | |
1160 | LUSTRE_OPC_ANY, NULL); | |
1161 | if (IS_ERR(op_data)) | |
1162 | RETURN(PTR_ERR(op_data)); | |
1163 | ||
1164 | ll_get_child_fid(src, src_name, &op_data->op_fid3); | |
1165 | ll_get_child_fid(tgt, tgt_name, &op_data->op_fid4); | |
1166 | err = md_rename(sbi->ll_md_exp, op_data, | |
1167 | src_name->name, src_name->len, | |
1168 | tgt_name->name, tgt_name->len, &request); | |
1169 | ll_finish_md_op_data(op_data); | |
1170 | if (!err) { | |
1171 | ll_update_times(request, src); | |
1172 | ll_update_times(request, tgt); | |
1173 | ll_stats_ops_tally(sbi, LPROC_LL_RENAME, 1); | |
1174 | err = ll_objects_destroy(request, src); | |
1175 | } | |
1176 | ||
1177 | ptlrpc_req_finished(request); | |
1178 | ||
1179 | RETURN(err); | |
1180 | } | |
1181 | ||
1182 | static int ll_mknod(struct inode *dir, struct dentry *dchild, ll_umode_t mode, | |
1183 | dev_t rdev) | |
1184 | { | |
1185 | return ll_mknod_generic(dir, &dchild->d_name, mode, | |
1186 | old_encode_dev(rdev), dchild); | |
1187 | } | |
1188 | ||
1189 | static int ll_unlink(struct inode * dir, struct dentry *dentry) | |
1190 | { | |
1191 | return ll_unlink_generic(dir, NULL, dentry, &dentry->d_name); | |
1192 | } | |
1193 | ||
1194 | static int ll_mkdir(struct inode *dir, struct dentry *dentry, ll_umode_t mode) | |
1195 | { | |
1196 | return ll_mkdir_generic(dir, &dentry->d_name, mode, dentry); | |
1197 | } | |
1198 | ||
1199 | static int ll_rmdir(struct inode *dir, struct dentry *dentry) | |
1200 | { | |
1201 | return ll_rmdir_generic(dir, NULL, dentry, &dentry->d_name); | |
1202 | } | |
1203 | ||
1204 | static int ll_symlink(struct inode *dir, struct dentry *dentry, | |
1205 | const char *oldname) | |
1206 | { | |
1207 | return ll_symlink_generic(dir, &dentry->d_name, oldname, dentry); | |
1208 | } | |
1209 | ||
1210 | static int ll_link(struct dentry *old_dentry, struct inode *dir, | |
1211 | struct dentry *new_dentry) | |
1212 | { | |
1213 | return ll_link_generic(old_dentry->d_inode, dir, &new_dentry->d_name, | |
1214 | new_dentry); | |
1215 | } | |
1216 | ||
1217 | static int ll_rename(struct inode *old_dir, struct dentry *old_dentry, | |
1218 | struct inode *new_dir, struct dentry *new_dentry) | |
1219 | { | |
1220 | int err; | |
1221 | err = ll_rename_generic(old_dir, NULL, | |
1222 | old_dentry, &old_dentry->d_name, | |
1223 | new_dir, NULL, new_dentry, | |
1224 | &new_dentry->d_name); | |
1225 | if (!err) { | |
1226 | d_move(old_dentry, new_dentry); | |
1227 | } | |
1228 | return err; | |
1229 | } | |
1230 | ||
1231 | struct inode_operations ll_dir_inode_operations = { | |
1232 | .mknod = ll_mknod, | |
1233 | .atomic_open = ll_atomic_open, | |
1234 | .lookup = ll_lookup_nd, | |
1235 | .create = ll_create_nd, | |
1236 | /* We need all these non-raw things for NFSD, to not patch it. */ | |
1237 | .unlink = ll_unlink, | |
1238 | .mkdir = ll_mkdir, | |
1239 | .rmdir = ll_rmdir, | |
1240 | .symlink = ll_symlink, | |
1241 | .link = ll_link, | |
1242 | .rename = ll_rename, | |
1243 | .setattr = ll_setattr, | |
1244 | .getattr = ll_getattr, | |
1245 | .permission = ll_inode_permission, | |
1246 | .setxattr = ll_setxattr, | |
1247 | .getxattr = ll_getxattr, | |
1248 | .listxattr = ll_listxattr, | |
1249 | .removexattr = ll_removexattr, | |
1250 | .get_acl = ll_get_acl, | |
1251 | }; | |
1252 | ||
1253 | struct inode_operations ll_special_inode_operations = { | |
1254 | .setattr = ll_setattr, | |
1255 | .getattr = ll_getattr, | |
1256 | .permission = ll_inode_permission, | |
1257 | .setxattr = ll_setxattr, | |
1258 | .getxattr = ll_getxattr, | |
1259 | .listxattr = ll_listxattr, | |
1260 | .removexattr = ll_removexattr, | |
1261 | .get_acl = ll_get_acl, | |
1262 | }; |