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