Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
5db11c21 MM |
2 | /* |
3 | * (C) 2001 Clemson University and The University of Chicago | |
afd9fb2a | 4 | * Copyright 2018 Omnibond Systems, L.L.C. |
5db11c21 MM |
5 | * |
6 | * See COPYING in top-level directory. | |
7 | */ | |
8 | ||
9 | /* | |
10 | * Linux VFS inode operations. | |
11 | */ | |
12 | ||
2f8b5444 | 13 | #include <linux/bvec.h> |
5db11c21 | 14 | #include "protocol.h" |
575e9461 MM |
15 | #include "orangefs-kernel.h" |
16 | #include "orangefs-bufmap.h" | |
5db11c21 | 17 | |
85ac799c MB |
18 | static int orangefs_writepage(struct page *page, struct writeback_control *wbc) |
19 | { | |
20 | struct inode *inode = page->mapping->host; | |
21 | struct iov_iter iter; | |
22 | struct bio_vec bv; | |
23 | size_t len, wlen; | |
24 | ssize_t ret; | |
25 | loff_t off; | |
26 | ||
27 | set_page_writeback(page); | |
28 | ||
29 | off = page_offset(page); | |
30 | len = i_size_read(inode); | |
31 | if (off > len) { | |
32 | /* The file was truncated; there is nothing to write. */ | |
33 | unlock_page(page); | |
34 | end_page_writeback(page); | |
35 | return 0; | |
36 | } | |
37 | if (off + PAGE_SIZE > len) | |
38 | wlen = len - off; | |
39 | else | |
40 | wlen = PAGE_SIZE; | |
41 | ||
42 | bv.bv_page = page; | |
43 | bv.bv_len = wlen; | |
44 | bv.bv_offset = off % PAGE_SIZE; | |
45 | if (wlen == 0) | |
46 | dump_stack(); | |
47 | iov_iter_bvec(&iter, WRITE, &bv, 1, wlen); | |
48 | ||
49 | ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, wlen, | |
50 | len); | |
51 | if (ret < 0) { | |
52 | SetPageError(page); | |
53 | mapping_set_error(page->mapping, ret); | |
54 | } else { | |
55 | ret = 0; | |
56 | } | |
57 | unlock_page(page); | |
58 | end_page_writeback(page); | |
59 | return ret; | |
60 | } | |
61 | ||
a68d9c60 | 62 | static int orangefs_readpage(struct file *file, struct page *page) |
5db11c21 | 63 | { |
5db11c21 | 64 | struct inode *inode = page->mapping->host; |
c453dcfc MB |
65 | struct iov_iter iter; |
66 | struct bio_vec bv; | |
67 | ssize_t ret; | |
68 | loff_t off; | |
69 | ||
70 | off = page_offset(page); | |
71 | bv.bv_page = page; | |
72 | bv.bv_len = PAGE_SIZE; | |
73 | bv.bv_offset = 0; | |
74 | iov_iter_bvec(&iter, READ, &bv, 1, PAGE_SIZE); | |
75 | ||
76 | ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, &off, &iter, | |
77 | PAGE_SIZE, inode->i_size); | |
74f68fce | 78 | /* this will only zero remaining unread portions of the page data */ |
c453dcfc | 79 | iov_iter_zero(~0U, &iter); |
5db11c21 MM |
80 | /* takes care of potential aliasing */ |
81 | flush_dcache_page(page); | |
c453dcfc | 82 | if (ret < 0) { |
5db11c21 MM |
83 | SetPageError(page); |
84 | } else { | |
85 | SetPageUptodate(page); | |
86 | if (PageError(page)) | |
87 | ClearPageError(page); | |
88 | ret = 0; | |
89 | } | |
5db11c21 MM |
90 | /* unlock the page after the ->readpage() routine completes */ |
91 | unlock_page(page); | |
92 | return ret; | |
93 | } | |
94 | ||
85ac799c MB |
95 | static int orangefs_write_end(struct file *file, struct address_space *mapping, |
96 | loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) | |
97 | { | |
98 | int r; | |
99 | r = simple_write_end(file, mapping, pos, len, copied, page, fsdata); | |
100 | mark_inode_dirty_sync(file_inode(file)); | |
101 | return r; | |
102 | } | |
103 | ||
8bb8aefd | 104 | static void orangefs_invalidatepage(struct page *page, |
5db11c21 MM |
105 | unsigned int offset, |
106 | unsigned int length) | |
107 | { | |
108 | gossip_debug(GOSSIP_INODE_DEBUG, | |
8bb8aefd | 109 | "orangefs_invalidatepage called on page %p " |
5db11c21 MM |
110 | "(offset is %u)\n", |
111 | page, | |
112 | offset); | |
113 | ||
114 | ClearPageUptodate(page); | |
115 | ClearPageMappedToDisk(page); | |
116 | return; | |
117 | ||
118 | } | |
119 | ||
8bb8aefd | 120 | static int orangefs_releasepage(struct page *page, gfp_t foo) |
5db11c21 MM |
121 | { |
122 | gossip_debug(GOSSIP_INODE_DEBUG, | |
8bb8aefd | 123 | "orangefs_releasepage called on page %p\n", |
5db11c21 MM |
124 | page); |
125 | return 0; | |
126 | } | |
127 | ||
3903f150 MM |
128 | static ssize_t orangefs_direct_IO(struct kiocb *iocb, |
129 | struct iov_iter *iter) | |
130 | { | |
c453dcfc MB |
131 | struct file *file = iocb->ki_filp; |
132 | loff_t pos = *(&iocb->ki_pos); | |
85ac799c MB |
133 | return do_readv_writev(iov_iter_rw(iter) == WRITE ? |
134 | ORANGEFS_IO_WRITE : ORANGEFS_IO_READ, file, &pos, iter); | |
3903f150 | 135 | } |
5db11c21 | 136 | |
8bb8aefd | 137 | /** ORANGEFS2 implementation of address space operations */ |
bdd6f083 | 138 | static const struct address_space_operations orangefs_address_operations = { |
85ac799c | 139 | .writepage = orangefs_writepage, |
8bb8aefd | 140 | .readpage = orangefs_readpage, |
85ac799c MB |
141 | .set_page_dirty = __set_page_dirty_nobuffers, |
142 | .write_begin = simple_write_begin, | |
143 | .write_end = orangefs_write_end, | |
8bb8aefd YL |
144 | .invalidatepage = orangefs_invalidatepage, |
145 | .releasepage = orangefs_releasepage, | |
3903f150 | 146 | .direct_IO = orangefs_direct_IO, |
5db11c21 MM |
147 | }; |
148 | ||
8bb8aefd | 149 | static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr) |
5db11c21 | 150 | { |
8bb8aefd YL |
151 | struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); |
152 | struct orangefs_kernel_op_s *new_op; | |
fecd86aa | 153 | loff_t orig_size; |
5db11c21 MM |
154 | int ret = -EINVAL; |
155 | ||
156 | gossip_debug(GOSSIP_INODE_DEBUG, | |
157 | "%s: %pU: Handle is %pU | fs_id %d | size is %llu\n", | |
158 | __func__, | |
159 | get_khandle_from_ino(inode), | |
8bb8aefd YL |
160 | &orangefs_inode->refn.khandle, |
161 | orangefs_inode->refn.fs_id, | |
5db11c21 MM |
162 | iattr->ia_size); |
163 | ||
fecd86aa | 164 | /* Ensure that we have a up to date size, so we know if it changed. */ |
8b60785c | 165 | ret = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_SIZE); |
fecd86aa MB |
166 | if (ret == -ESTALE) |
167 | ret = -EIO; | |
168 | if (ret) { | |
169 | gossip_err("%s: orangefs_inode_getattr failed, ret:%d:.\n", | |
170 | __func__, ret); | |
171 | return ret; | |
172 | } | |
173 | orig_size = i_size_read(inode); | |
174 | ||
5db11c21 MM |
175 | truncate_setsize(inode, iattr->ia_size); |
176 | ||
8bb8aefd | 177 | new_op = op_alloc(ORANGEFS_VFS_OP_TRUNCATE); |
5db11c21 MM |
178 | if (!new_op) |
179 | return -ENOMEM; | |
180 | ||
8bb8aefd | 181 | new_op->upcall.req.truncate.refn = orangefs_inode->refn; |
5db11c21 MM |
182 | new_op->upcall.req.truncate.size = (__s64) iattr->ia_size; |
183 | ||
95f5f88f MM |
184 | ret = service_operation(new_op, |
185 | __func__, | |
186 | get_interruptible_flag(inode)); | |
5db11c21 MM |
187 | |
188 | /* | |
189 | * the truncate has no downcall members to retrieve, but | |
190 | * the status value tells us if it went through ok or not | |
191 | */ | |
95f5f88f | 192 | gossip_debug(GOSSIP_INODE_DEBUG, "%s: ret:%d:\n", __func__, ret); |
5db11c21 MM |
193 | |
194 | op_release(new_op); | |
195 | ||
196 | if (ret != 0) | |
197 | return ret; | |
198 | ||
f83140c1 | 199 | if (orig_size != i_size_read(inode)) |
5db11c21 | 200 | iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; |
5db11c21 MM |
201 | |
202 | return ret; | |
203 | } | |
204 | ||
afd9fb2a | 205 | int __orangefs_setattr(struct inode *inode, struct iattr *iattr) |
5db11c21 | 206 | { |
df2d7337 | 207 | int ret; |
5db11c21 | 208 | |
afd9fb2a MB |
209 | if (iattr->ia_valid & ATTR_MODE) { |
210 | if (iattr->ia_mode & (S_ISVTX)) { | |
211 | if (is_root_handle(inode)) { | |
212 | /* | |
213 | * allow sticky bit to be set on root (since | |
214 | * it shows up that way by default anyhow), | |
215 | * but don't show it to the server | |
216 | */ | |
217 | iattr->ia_mode -= S_ISVTX; | |
218 | } else { | |
219 | gossip_debug(GOSSIP_UTILS_DEBUG, | |
220 | "User attempted to set sticky bit on non-root directory; returning EINVAL.\n"); | |
221 | return -EINVAL; | |
222 | } | |
223 | } | |
224 | if (iattr->ia_mode & (S_ISUID)) { | |
225 | gossip_debug(GOSSIP_UTILS_DEBUG, | |
226 | "Attempting to set setuid bit (not supported); returning EINVAL.\n"); | |
227 | return -EINVAL; | |
228 | } | |
229 | } | |
5db11c21 | 230 | |
53950ef5 | 231 | if (iattr->ia_valid & ATTR_SIZE) { |
8bb8aefd | 232 | ret = orangefs_setattr_size(inode, iattr); |
5db11c21 MM |
233 | if (ret) |
234 | goto out; | |
235 | } | |
236 | ||
afd9fb2a MB |
237 | again: |
238 | spin_lock(&inode->i_lock); | |
239 | if (ORANGEFS_I(inode)->attr_valid) { | |
240 | if (uid_eq(ORANGEFS_I(inode)->attr_uid, current_fsuid()) && | |
241 | gid_eq(ORANGEFS_I(inode)->attr_gid, current_fsgid())) { | |
242 | ORANGEFS_I(inode)->attr_valid = iattr->ia_valid; | |
243 | } else { | |
244 | spin_unlock(&inode->i_lock); | |
245 | write_inode_now(inode, 1); | |
246 | goto again; | |
247 | } | |
248 | } else { | |
249 | ORANGEFS_I(inode)->attr_valid = iattr->ia_valid; | |
250 | ORANGEFS_I(inode)->attr_uid = current_fsuid(); | |
251 | ORANGEFS_I(inode)->attr_gid = current_fsgid(); | |
252 | } | |
5db11c21 | 253 | setattr_copy(inode, iattr); |
afd9fb2a | 254 | spin_unlock(&inode->i_lock); |
5db11c21 MM |
255 | mark_inode_dirty(inode); |
256 | ||
df2d7337 | 257 | if (iattr->ia_valid & ATTR_MODE) |
5db11c21 MM |
258 | /* change mod on a file that has ACLs */ |
259 | ret = posix_acl_chmod(inode, inode->i_mode); | |
260 | ||
df2d7337 | 261 | ret = 0; |
5db11c21 | 262 | out: |
afd9fb2a MB |
263 | return ret; |
264 | } | |
265 | ||
266 | /* | |
267 | * Change attributes of an object referenced by dentry. | |
268 | */ | |
269 | int orangefs_setattr(struct dentry *dentry, struct iattr *iattr) | |
270 | { | |
271 | int ret; | |
272 | gossip_debug(GOSSIP_INODE_DEBUG, "__orangefs_setattr: called on %pd\n", | |
273 | dentry); | |
274 | ret = setattr_prepare(dentry, iattr); | |
275 | if (ret) | |
276 | goto out; | |
277 | ret = __orangefs_setattr(d_inode(dentry), iattr); | |
278 | sync_inode_metadata(d_inode(dentry), 1); | |
279 | out: | |
280 | gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n", | |
281 | ret); | |
5db11c21 MM |
282 | return ret; |
283 | } | |
284 | ||
285 | /* | |
286 | * Obtain attributes of an object given a dentry | |
287 | */ | |
a528d35e DH |
288 | int orangefs_getattr(const struct path *path, struct kstat *stat, |
289 | u32 request_mask, unsigned int flags) | |
5db11c21 MM |
290 | { |
291 | int ret = -ENOENT; | |
a528d35e | 292 | struct inode *inode = path->dentry->d_inode; |
5db11c21 MM |
293 | |
294 | gossip_debug(GOSSIP_INODE_DEBUG, | |
5e4f606e MB |
295 | "orangefs_getattr: called on %pd mask %u\n", |
296 | path->dentry, request_mask); | |
5db11c21 | 297 | |
8b60785c MB |
298 | ret = orangefs_inode_getattr(inode, |
299 | request_mask & STATX_SIZE ? ORANGEFS_GETATTR_SIZE : 0); | |
5db11c21 | 300 | if (ret == 0) { |
a528d35e | 301 | generic_fillattr(inode, stat); |
a7d3e78a | 302 | |
5db11c21 | 303 | /* override block size reported to stat */ |
5678b5d6 CH |
304 | if (!(request_mask & STATX_SIZE)) |
305 | stat->result_mask &= ~STATX_SIZE; | |
7f54910f MB |
306 | |
307 | stat->attributes_mask = STATX_ATTR_IMMUTABLE | | |
308 | STATX_ATTR_APPEND; | |
309 | if (inode->i_flags & S_IMMUTABLE) | |
310 | stat->attributes |= STATX_ATTR_IMMUTABLE; | |
311 | if (inode->i_flags & S_APPEND) | |
312 | stat->attributes |= STATX_ATTR_APPEND; | |
5db11c21 MM |
313 | } |
314 | return ret; | |
315 | } | |
316 | ||
933287da MB |
317 | int orangefs_permission(struct inode *inode, int mask) |
318 | { | |
319 | int ret; | |
320 | ||
321 | if (mask & MAY_NOT_BLOCK) | |
322 | return -ECHILD; | |
323 | ||
324 | gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__); | |
325 | ||
326 | /* Make sure the permission (and other common attrs) are up to date. */ | |
8b60785c | 327 | ret = orangefs_inode_getattr(inode, 0); |
933287da MB |
328 | if (ret < 0) |
329 | return ret; | |
330 | ||
331 | return generic_permission(inode, mask); | |
332 | } | |
333 | ||
95582b00 | 334 | int orangefs_update_time(struct inode *inode, struct timespec64 *time, int flags) |
a55f2d86 MB |
335 | { |
336 | struct iattr iattr; | |
337 | gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_update_time: %pU\n", | |
338 | get_khandle_from_ino(inode)); | |
339 | generic_update_time(inode, time, flags); | |
340 | memset(&iattr, 0, sizeof iattr); | |
341 | if (flags & S_ATIME) | |
342 | iattr.ia_valid |= ATTR_ATIME; | |
343 | if (flags & S_CTIME) | |
344 | iattr.ia_valid |= ATTR_CTIME; | |
345 | if (flags & S_MTIME) | |
346 | iattr.ia_valid |= ATTR_MTIME; | |
afd9fb2a | 347 | return __orangefs_setattr(inode, &iattr); |
a55f2d86 MB |
348 | } |
349 | ||
95f5f88f | 350 | /* ORANGEFS2 implementation of VFS inode operations for files */ |
bdd6f083 | 351 | static const struct inode_operations orangefs_file_inode_operations = { |
8bb8aefd YL |
352 | .get_acl = orangefs_get_acl, |
353 | .set_acl = orangefs_set_acl, | |
354 | .setattr = orangefs_setattr, | |
355 | .getattr = orangefs_getattr, | |
8bb8aefd | 356 | .listxattr = orangefs_listxattr, |
933287da | 357 | .permission = orangefs_permission, |
a55f2d86 | 358 | .update_time = orangefs_update_time, |
5db11c21 MM |
359 | }; |
360 | ||
8bb8aefd | 361 | static int orangefs_init_iops(struct inode *inode) |
5db11c21 | 362 | { |
8bb8aefd | 363 | inode->i_mapping->a_ops = &orangefs_address_operations; |
5db11c21 MM |
364 | |
365 | switch (inode->i_mode & S_IFMT) { | |
366 | case S_IFREG: | |
8bb8aefd YL |
367 | inode->i_op = &orangefs_file_inode_operations; |
368 | inode->i_fop = &orangefs_file_operations; | |
5db11c21 MM |
369 | break; |
370 | case S_IFLNK: | |
8bb8aefd | 371 | inode->i_op = &orangefs_symlink_inode_operations; |
5db11c21 MM |
372 | break; |
373 | case S_IFDIR: | |
8bb8aefd YL |
374 | inode->i_op = &orangefs_dir_inode_operations; |
375 | inode->i_fop = &orangefs_dir_operations; | |
5db11c21 MM |
376 | break; |
377 | default: | |
378 | gossip_debug(GOSSIP_INODE_DEBUG, | |
379 | "%s: unsupported mode\n", | |
380 | __func__); | |
381 | return -EINVAL; | |
382 | } | |
383 | ||
384 | return 0; | |
385 | } | |
386 | ||
387 | /* | |
95f5f88f MM |
388 | * Given an ORANGEFS object identifier (fsid, handle), convert it into |
389 | * a ino_t type that will be used as a hash-index from where the handle will | |
5db11c21 MM |
390 | * be searched for in the VFS hash table of inodes. |
391 | */ | |
8bb8aefd | 392 | static inline ino_t orangefs_handle_hash(struct orangefs_object_kref *ref) |
5db11c21 MM |
393 | { |
394 | if (!ref) | |
395 | return 0; | |
8bb8aefd | 396 | return orangefs_khandle_to_ino(&(ref->khandle)); |
5db11c21 MM |
397 | } |
398 | ||
399 | /* | |
400 | * Called to set up an inode from iget5_locked. | |
401 | */ | |
8bb8aefd | 402 | static int orangefs_set_inode(struct inode *inode, void *data) |
5db11c21 | 403 | { |
8bb8aefd | 404 | struct orangefs_object_kref *ref = (struct orangefs_object_kref *) data; |
a4c680a0 MB |
405 | ORANGEFS_I(inode)->refn.fs_id = ref->fs_id; |
406 | ORANGEFS_I(inode)->refn.khandle = ref->khandle; | |
afd9fb2a | 407 | ORANGEFS_I(inode)->attr_valid = 0; |
fc2e2e9c | 408 | hash_init(ORANGEFS_I(inode)->xattr_cache); |
5db11c21 MM |
409 | return 0; |
410 | } | |
411 | ||
412 | /* | |
413 | * Called to determine if handles match. | |
414 | */ | |
8bb8aefd | 415 | static int orangefs_test_inode(struct inode *inode, void *data) |
5db11c21 | 416 | { |
8bb8aefd YL |
417 | struct orangefs_object_kref *ref = (struct orangefs_object_kref *) data; |
418 | struct orangefs_inode_s *orangefs_inode = NULL; | |
5db11c21 | 419 | |
8bb8aefd | 420 | orangefs_inode = ORANGEFS_I(inode); |
95f5f88f MM |
421 | /* test handles and fs_ids... */ |
422 | return (!ORANGEFS_khandle_cmp(&(orangefs_inode->refn.khandle), | |
423 | &(ref->khandle)) && | |
424 | orangefs_inode->refn.fs_id == ref->fs_id); | |
5db11c21 MM |
425 | } |
426 | ||
427 | /* | |
8bb8aefd | 428 | * Front-end to lookup the inode-cache maintained by the VFS using the ORANGEFS |
5db11c21 MM |
429 | * file handle. |
430 | * | |
431 | * @sb: the file system super block instance. | |
95f5f88f | 432 | * @ref: The ORANGEFS object for which we are trying to locate an inode. |
5db11c21 | 433 | */ |
95f5f88f MM |
434 | struct inode *orangefs_iget(struct super_block *sb, |
435 | struct orangefs_object_kref *ref) | |
5db11c21 MM |
436 | { |
437 | struct inode *inode = NULL; | |
438 | unsigned long hash; | |
439 | int error; | |
440 | ||
8bb8aefd | 441 | hash = orangefs_handle_hash(ref); |
95f5f88f MM |
442 | inode = iget5_locked(sb, |
443 | hash, | |
444 | orangefs_test_inode, | |
445 | orangefs_set_inode, | |
446 | ref); | |
b5d72cdc MM |
447 | |
448 | if (!inode) | |
449 | return ERR_PTR(-ENOMEM); | |
450 | ||
451 | if (!(inode->i_state & I_NEW)) | |
5db11c21 MM |
452 | return inode; |
453 | ||
8b60785c | 454 | error = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_NEW); |
5db11c21 MM |
455 | if (error) { |
456 | iget_failed(inode); | |
457 | return ERR_PTR(error); | |
458 | } | |
459 | ||
460 | inode->i_ino = hash; /* needed for stat etc */ | |
8bb8aefd | 461 | orangefs_init_iops(inode); |
5db11c21 MM |
462 | unlock_new_inode(inode); |
463 | ||
464 | gossip_debug(GOSSIP_INODE_DEBUG, | |
465 | "iget handle %pU, fsid %d hash %ld i_ino %lu\n", | |
466 | &ref->khandle, | |
467 | ref->fs_id, | |
468 | hash, | |
469 | inode->i_ino); | |
470 | ||
471 | return inode; | |
472 | } | |
473 | ||
474 | /* | |
475 | * Allocate an inode for a newly created file and insert it into the inode hash. | |
476 | */ | |
8bb8aefd YL |
477 | struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, |
478 | int mode, dev_t dev, struct orangefs_object_kref *ref) | |
5db11c21 | 479 | { |
8bb8aefd | 480 | unsigned long hash = orangefs_handle_hash(ref); |
5db11c21 MM |
481 | struct inode *inode; |
482 | int error; | |
483 | ||
484 | gossip_debug(GOSSIP_INODE_DEBUG, | |
5253487e MM |
485 | "%s:(sb is %p | MAJOR(dev)=%u | MINOR(dev)=%u mode=%o)\n", |
486 | __func__, | |
5db11c21 MM |
487 | sb, |
488 | MAJOR(dev), | |
489 | MINOR(dev), | |
490 | mode); | |
491 | ||
492 | inode = new_inode(sb); | |
493 | if (!inode) | |
56249998 | 494 | return ERR_PTR(-ENOMEM); |
5db11c21 | 495 | |
8bb8aefd | 496 | orangefs_set_inode(inode, ref); |
5db11c21 MM |
497 | inode->i_ino = hash; /* needed for stat etc */ |
498 | ||
8b60785c | 499 | error = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_NEW); |
5db11c21 MM |
500 | if (error) |
501 | goto out_iput; | |
502 | ||
8bb8aefd | 503 | orangefs_init_iops(inode); |
5db11c21 MM |
504 | inode->i_rdev = dev; |
505 | ||
8bb8aefd | 506 | error = insert_inode_locked4(inode, hash, orangefs_test_inode, ref); |
5db11c21 MM |
507 | if (error < 0) |
508 | goto out_iput; | |
509 | ||
510 | gossip_debug(GOSSIP_INODE_DEBUG, | |
511 | "Initializing ACL's for inode %pU\n", | |
512 | get_khandle_from_ino(inode)); | |
8bb8aefd | 513 | orangefs_init_acl(inode, dir); |
5db11c21 MM |
514 | return inode; |
515 | ||
516 | out_iput: | |
517 | iput(inode); | |
518 | return ERR_PTR(error); | |
519 | } |