orangefs: do not return successful read when the client-core disappeared
[linux-block.git] / fs / orangefs / inode.c
CommitLineData
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
18static 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 62static 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
95static 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 104static 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 120static 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
128static 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 138static 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 149static 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 205int __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
237again:
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 262out:
afd9fb2a
MB
263 return ret;
264}
265
266/*
267 * Change attributes of an object referenced by dentry.
268 */
269int 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);
279out:
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
288int 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
317int 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 334int 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 351static 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 361static 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 392static 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 402static 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 415static 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
434struct 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
477struct 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
516out_iput:
517 iput(inode);
518 return ERR_PTR(error);
519}