linux/fs/orangefs/file.c
<<
>>
Prefs
   1/*
   2 * (C) 2001 Clemson University and The University of Chicago
   3 *
   4 * See COPYING in top-level directory.
   5 */
   6
   7/*
   8 *  Linux VFS file operations.
   9 */
  10
  11#include "protocol.h"
  12#include "orangefs-kernel.h"
  13#include "orangefs-bufmap.h"
  14#include <linux/fs.h>
  15#include <linux/pagemap.h>
  16
  17static int flush_racache(struct inode *inode)
  18{
  19        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  20        struct orangefs_kernel_op_s *new_op;
  21        int ret;
  22
  23        gossip_debug(GOSSIP_UTILS_DEBUG,
  24            "%s: %pU: Handle is %pU | fs_id %d\n", __func__,
  25            get_khandle_from_ino(inode), &orangefs_inode->refn.khandle,
  26            orangefs_inode->refn.fs_id);
  27
  28        new_op = op_alloc(ORANGEFS_VFS_OP_RA_FLUSH);
  29        if (!new_op)
  30                return -ENOMEM;
  31        new_op->upcall.req.ra_cache_flush.refn = orangefs_inode->refn;
  32
  33        ret = service_operation(new_op, "orangefs_flush_racache",
  34            get_interruptible_flag(inode));
  35
  36        gossip_debug(GOSSIP_UTILS_DEBUG, "%s: got return value of %d\n",
  37            __func__, ret);
  38
  39        op_release(new_op);
  40        return ret;
  41}
  42
  43/*
  44 * Copy to client-core's address space from the buffers specified
  45 * by the iovec upto total_size bytes.
  46 * NOTE: the iovector can either contain addresses which
  47 *       can futher be kernel-space or user-space addresses.
  48 *       or it can pointers to struct page's
  49 */
  50static int precopy_buffers(int buffer_index,
  51                           struct iov_iter *iter,
  52                           size_t total_size)
  53{
  54        int ret = 0;
  55        /*
  56         * copy data from application/kernel by pulling it out
  57         * of the iovec.
  58         */
  59
  60
  61        if (total_size) {
  62                ret = orangefs_bufmap_copy_from_iovec(iter,
  63                                                      buffer_index,
  64                                                      total_size);
  65                if (ret < 0)
  66                gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
  67                           __func__,
  68                           (long)ret);
  69        }
  70
  71        if (ret < 0)
  72                gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
  73                        __func__,
  74                        (long)ret);
  75        return ret;
  76}
  77
  78/*
  79 * Copy from client-core's address space to the buffers specified
  80 * by the iovec upto total_size bytes.
  81 * NOTE: the iovector can either contain addresses which
  82 *       can futher be kernel-space or user-space addresses.
  83 *       or it can pointers to struct page's
  84 */
  85static int postcopy_buffers(int buffer_index,
  86                            struct iov_iter *iter,
  87                            size_t total_size)
  88{
  89        int ret = 0;
  90        /*
  91         * copy data to application/kernel by pushing it out to
  92         * the iovec. NOTE; target buffers can be addresses or
  93         * struct page pointers.
  94         */
  95        if (total_size) {
  96                ret = orangefs_bufmap_copy_to_iovec(iter,
  97                                                    buffer_index,
  98                                                    total_size);
  99                if (ret < 0)
 100                        gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n",
 101                                __func__,
 102                                (long)ret);
 103        }
 104        return ret;
 105}
 106
 107/*
 108 * Post and wait for the I/O upcall to finish
 109 */
 110static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
 111                loff_t *offset, struct iov_iter *iter,
 112                size_t total_size, loff_t readahead_size)
 113{
 114        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
 115        struct orangefs_khandle *handle = &orangefs_inode->refn.khandle;
 116        struct orangefs_kernel_op_s *new_op = NULL;
 117        int buffer_index = -1;
 118        ssize_t ret;
 119
 120        new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO);
 121        if (!new_op)
 122                return -ENOMEM;
 123
 124        /* synchronous I/O */
 125        new_op->upcall.req.io.readahead_size = readahead_size;
 126        new_op->upcall.req.io.io_type = type;
 127        new_op->upcall.req.io.refn = orangefs_inode->refn;
 128
 129populate_shared_memory:
 130        /* get a shared buffer index */
 131        buffer_index = orangefs_bufmap_get();
 132        if (buffer_index < 0) {
 133                ret = buffer_index;
 134                gossip_debug(GOSSIP_FILE_DEBUG,
 135                             "%s: orangefs_bufmap_get failure (%zd)\n",
 136                             __func__, ret);
 137                goto out;
 138        }
 139        gossip_debug(GOSSIP_FILE_DEBUG,
 140                     "%s(%pU): GET op %p -> buffer_index %d\n",
 141                     __func__,
 142                     handle,
 143                     new_op,
 144                     buffer_index);
 145
 146        new_op->uses_shared_memory = 1;
 147        new_op->upcall.req.io.buf_index = buffer_index;
 148        new_op->upcall.req.io.count = total_size;
 149        new_op->upcall.req.io.offset = *offset;
 150
 151        gossip_debug(GOSSIP_FILE_DEBUG,
 152                     "%s(%pU): offset: %llu total_size: %zd\n",
 153                     __func__,
 154                     handle,
 155                     llu(*offset),
 156                     total_size);
 157        /*
 158         * Stage 1: copy the buffers into client-core's address space
 159         * precopy_buffers only pertains to writes.
 160         */
 161        if (type == ORANGEFS_IO_WRITE) {
 162                ret = precopy_buffers(buffer_index,
 163                                      iter,
 164                                      total_size);
 165                if (ret < 0)
 166                        goto out;
 167        }
 168
 169        gossip_debug(GOSSIP_FILE_DEBUG,
 170                     "%s(%pU): Calling post_io_request with tag (%llu)\n",
 171                     __func__,
 172                     handle,
 173                     llu(new_op->tag));
 174
 175        /* Stage 2: Service the I/O operation */
 176        ret = service_operation(new_op,
 177                                type == ORANGEFS_IO_WRITE ?
 178                                        "file_write" :
 179                                        "file_read",
 180                                get_interruptible_flag(inode));
 181
 182        /*
 183         * If service_operation() returns -EAGAIN #and# the operation was
 184         * purged from orangefs_request_list or htable_ops_in_progress, then
 185         * we know that the client was restarted, causing the shared memory
 186         * area to be wiped clean.  To restart a  write operation in this
 187         * case, we must re-copy the data from the user's iovec to a NEW
 188         * shared memory location. To restart a read operation, we must get
 189         * a new shared memory location.
 190         */
 191        if (ret == -EAGAIN && op_state_purged(new_op)) {
 192                orangefs_bufmap_put(buffer_index);
 193                buffer_index = -1;
 194                if (type == ORANGEFS_IO_WRITE)
 195                        iov_iter_revert(iter, total_size);
 196                gossip_debug(GOSSIP_FILE_DEBUG,
 197                             "%s:going to repopulate_shared_memory.\n",
 198                             __func__);
 199                goto populate_shared_memory;
 200        }
 201
 202        if (ret < 0) {
 203                if (ret == -EINTR) {
 204                        /*
 205                         * We can't return EINTR if any data was written,
 206                         * it's not POSIX. It is minimally acceptable
 207                         * to give a partial write, the way NFS does.
 208                         *
 209                         * It would be optimal to return all or nothing,
 210                         * but if a userspace write is bigger than
 211                         * an IO buffer, and the interrupt occurs
 212                         * between buffer writes, that would not be
 213                         * possible.
 214                         */
 215                        switch (new_op->op_state - OP_VFS_STATE_GIVEN_UP) {
 216                        /*
 217                         * If the op was waiting when the interrupt
 218                         * occurred, then the client-core did not
 219                         * trigger the write.
 220                         */
 221                        case OP_VFS_STATE_WAITING:
 222                                if (*offset == 0)
 223                                        ret = -EINTR;
 224                                else
 225                                        ret = 0;
 226                                break;
 227                        /* 
 228                         * If the op was in progress when the interrupt
 229                         * occurred, then the client-core was able to
 230                         * trigger the write.
 231                         */
 232                        case OP_VFS_STATE_INPROGR:
 233                                ret = total_size;
 234                                break;
 235                        default:
 236                                gossip_err("%s: unexpected op state :%d:.\n",
 237                                           __func__,
 238                                           new_op->op_state);
 239                                ret = 0;
 240                                break;
 241                        }
 242                        gossip_debug(GOSSIP_FILE_DEBUG,
 243                                     "%s: got EINTR, state:%d: %p\n",
 244                                     __func__,
 245                                     new_op->op_state,
 246                                     new_op);
 247                } else {
 248                        gossip_err("%s: error in %s handle %pU, returning %zd\n",
 249                                __func__,
 250                                type == ORANGEFS_IO_READ ?
 251                                        "read from" : "write to",
 252                                handle, ret);
 253                }
 254                if (orangefs_cancel_op_in_progress(new_op))
 255                        return ret;
 256
 257                goto out;
 258        }
 259
 260        /*
 261         * Stage 3: Post copy buffers from client-core's address space
 262         * postcopy_buffers only pertains to reads.
 263         */
 264        if (type == ORANGEFS_IO_READ) {
 265                ret = postcopy_buffers(buffer_index,
 266                                       iter,
 267                                       new_op->downcall.resp.io.amt_complete);
 268                if (ret < 0)
 269                        goto out;
 270        }
 271        gossip_debug(GOSSIP_FILE_DEBUG,
 272            "%s(%pU): Amount %s, returned by the sys-io call:%d\n",
 273            __func__,
 274            handle,
 275            type == ORANGEFS_IO_READ ?  "read" : "written",
 276            (int)new_op->downcall.resp.io.amt_complete);
 277
 278        ret = new_op->downcall.resp.io.amt_complete;
 279
 280out:
 281        if (buffer_index >= 0) {
 282                orangefs_bufmap_put(buffer_index);
 283                gossip_debug(GOSSIP_FILE_DEBUG,
 284                             "%s(%pU): PUT buffer_index %d\n",
 285                             __func__, handle, buffer_index);
 286                buffer_index = -1;
 287        }
 288        op_release(new_op);
 289        return ret;
 290}
 291
 292/*
 293 * Common entry point for read/write/readv/writev
 294 * This function will dispatch it to either the direct I/O
 295 * or buffered I/O path depending on the mount options and/or
 296 * augmented/extended metadata attached to the file.
 297 * Note: File extended attributes override any mount options.
 298 */
 299static ssize_t do_readv_writev(enum ORANGEFS_io_type type, struct file *file,
 300                loff_t *offset, struct iov_iter *iter)
 301{
 302        struct inode *inode = file->f_mapping->host;
 303        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
 304        struct orangefs_khandle *handle = &orangefs_inode->refn.khandle;
 305        size_t count = iov_iter_count(iter);
 306        ssize_t total_count = 0;
 307        ssize_t ret = -EINVAL;
 308
 309        gossip_debug(GOSSIP_FILE_DEBUG,
 310                "%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n",
 311                __func__,
 312                handle,
 313                (int)count);
 314
 315        if (type == ORANGEFS_IO_WRITE) {
 316                gossip_debug(GOSSIP_FILE_DEBUG,
 317                             "%s(%pU): proceeding with offset : %llu, "
 318                             "size %d\n",
 319                             __func__,
 320                             handle,
 321                             llu(*offset),
 322                             (int)count);
 323        }
 324
 325        if (count == 0) {
 326                ret = 0;
 327                goto out;
 328        }
 329
 330        while (iov_iter_count(iter)) {
 331                size_t each_count = iov_iter_count(iter);
 332                size_t amt_complete;
 333
 334                /* how much to transfer in this loop iteration */
 335                if (each_count > orangefs_bufmap_size_query())
 336                        each_count = orangefs_bufmap_size_query();
 337
 338                gossip_debug(GOSSIP_FILE_DEBUG,
 339                             "%s(%pU): size of each_count(%d)\n",
 340                             __func__,
 341                             handle,
 342                             (int)each_count);
 343                gossip_debug(GOSSIP_FILE_DEBUG,
 344                             "%s(%pU): BEFORE wait_for_io: offset is %d\n",
 345                             __func__,
 346                             handle,
 347                             (int)*offset);
 348
 349                ret = wait_for_direct_io(type, inode, offset, iter,
 350                                each_count, 0);
 351                gossip_debug(GOSSIP_FILE_DEBUG,
 352                             "%s(%pU): return from wait_for_io:%d\n",
 353                             __func__,
 354                             handle,
 355                             (int)ret);
 356
 357                if (ret < 0)
 358                        goto out;
 359
 360                *offset += ret;
 361                total_count += ret;
 362                amt_complete = ret;
 363
 364                gossip_debug(GOSSIP_FILE_DEBUG,
 365                             "%s(%pU): AFTER wait_for_io: offset is %d\n",
 366                             __func__,
 367                             handle,
 368                             (int)*offset);
 369
 370                /*
 371                 * if we got a short I/O operations,
 372                 * fall out and return what we got so far
 373                 */
 374                if (amt_complete < each_count)
 375                        break;
 376        } /*end while */
 377
 378out:
 379        if (total_count > 0)
 380                ret = total_count;
 381        if (ret > 0) {
 382                if (type == ORANGEFS_IO_READ) {
 383                        file_accessed(file);
 384                } else {
 385                        SetMtimeFlag(orangefs_inode);
 386                        inode->i_mtime = current_time(inode);
 387                        mark_inode_dirty_sync(inode);
 388                }
 389        }
 390
 391        gossip_debug(GOSSIP_FILE_DEBUG,
 392                     "%s(%pU): Value(%d) returned.\n",
 393                     __func__,
 394                     handle,
 395                     (int)ret);
 396
 397        return ret;
 398}
 399
 400/*
 401 * Read data from a specified offset in a file (referenced by inode).
 402 * Data may be placed either in a user or kernel buffer.
 403 */
 404ssize_t orangefs_inode_read(struct inode *inode,
 405                            struct iov_iter *iter,
 406                            loff_t *offset,
 407                            loff_t readahead_size)
 408{
 409        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
 410        size_t count = iov_iter_count(iter);
 411        size_t bufmap_size;
 412        ssize_t ret = -EINVAL;
 413
 414        orangefs_stats.reads++;
 415
 416        bufmap_size = orangefs_bufmap_size_query();
 417        if (count > bufmap_size) {
 418                gossip_debug(GOSSIP_FILE_DEBUG,
 419                             "%s: count is too large (%zd/%zd)!\n",
 420                             __func__, count, bufmap_size);
 421                return -EINVAL;
 422        }
 423
 424        gossip_debug(GOSSIP_FILE_DEBUG,
 425                     "%s(%pU) %zd@%llu\n",
 426                     __func__,
 427                     &orangefs_inode->refn.khandle,
 428                     count,
 429                     llu(*offset));
 430
 431        ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, offset, iter,
 432                        count, readahead_size);
 433        if (ret > 0)
 434                *offset += ret;
 435
 436        gossip_debug(GOSSIP_FILE_DEBUG,
 437                     "%s(%pU): Value(%zd) returned.\n",
 438                     __func__,
 439                     &orangefs_inode->refn.khandle,
 440                     ret);
 441
 442        return ret;
 443}
 444
 445static ssize_t orangefs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 446{
 447        struct file *file = iocb->ki_filp;
 448        loff_t pos = *(&iocb->ki_pos);
 449        ssize_t rc = 0;
 450
 451        BUG_ON(iocb->private);
 452
 453        gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_read_iter\n");
 454
 455        orangefs_stats.reads++;
 456
 457        rc = do_readv_writev(ORANGEFS_IO_READ, file, &pos, iter);
 458        iocb->ki_pos = pos;
 459
 460        return rc;
 461}
 462
 463static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 464{
 465        struct file *file = iocb->ki_filp;
 466        loff_t pos;
 467        ssize_t rc;
 468
 469        BUG_ON(iocb->private);
 470
 471        gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_write_iter\n");
 472
 473        inode_lock(file->f_mapping->host);
 474
 475        /* Make sure generic_write_checks sees an up to date inode size. */
 476        if (file->f_flags & O_APPEND) {
 477                rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1,
 478                    STATX_SIZE);
 479                if (rc == -ESTALE)
 480                        rc = -EIO;
 481                if (rc) {
 482                        gossip_err("%s: orangefs_inode_getattr failed, "
 483                            "rc:%zd:.\n", __func__, rc);
 484                        goto out;
 485                }
 486        }
 487
 488        if (file->f_pos > i_size_read(file->f_mapping->host))
 489                orangefs_i_size_write(file->f_mapping->host, file->f_pos);
 490
 491        rc = generic_write_checks(iocb, iter);
 492
 493        if (rc <= 0) {
 494                gossip_err("%s: generic_write_checks failed, rc:%zd:.\n",
 495                           __func__, rc);
 496                goto out;
 497        }
 498
 499        /*
 500         * if we are appending, generic_write_checks would have updated
 501         * pos to the end of the file, so we will wait till now to set
 502         * pos...
 503         */
 504        pos = *(&iocb->ki_pos);
 505
 506        rc = do_readv_writev(ORANGEFS_IO_WRITE,
 507                             file,
 508                             &pos,
 509                             iter);
 510        if (rc < 0) {
 511                gossip_err("%s: do_readv_writev failed, rc:%zd:.\n",
 512                           __func__, rc);
 513                goto out;
 514        }
 515
 516        iocb->ki_pos = pos;
 517        orangefs_stats.writes++;
 518
 519out:
 520
 521        inode_unlock(file->f_mapping->host);
 522        return rc;
 523}
 524
 525/*
 526 * Perform a miscellaneous operation on a file.
 527 */
 528static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 529{
 530        int ret = -ENOTTY;
 531        __u64 val = 0;
 532        unsigned long uval;
 533
 534        gossip_debug(GOSSIP_FILE_DEBUG,
 535                     "orangefs_ioctl: called with cmd %d\n",
 536                     cmd);
 537
 538        /*
 539         * we understand some general ioctls on files, such as the immutable
 540         * and append flags
 541         */
 542        if (cmd == FS_IOC_GETFLAGS) {
 543                val = 0;
 544                ret = orangefs_inode_getxattr(file_inode(file),
 545                                              "user.pvfs2.meta_hint",
 546                                              &val, sizeof(val));
 547                if (ret < 0 && ret != -ENODATA)
 548                        return ret;
 549                else if (ret == -ENODATA)
 550                        val = 0;
 551                uval = val;
 552                gossip_debug(GOSSIP_FILE_DEBUG,
 553                             "orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n",
 554                             (unsigned long long)uval);
 555                return put_user(uval, (int __user *)arg);
 556        } else if (cmd == FS_IOC_SETFLAGS) {
 557                ret = 0;
 558                if (get_user(uval, (int __user *)arg))
 559                        return -EFAULT;
 560                /*
 561                 * ORANGEFS_MIRROR_FL is set internally when the mirroring mode
 562                 * is turned on for a file. The user is not allowed to turn
 563                 * on this bit, but the bit is present if the user first gets
 564                 * the flags and then updates the flags with some new
 565                 * settings. So, we ignore it in the following edit. bligon.
 566                 */
 567                if ((uval & ~ORANGEFS_MIRROR_FL) &
 568                    (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) {
 569                        gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n");
 570                        return -EINVAL;
 571                }
 572                val = uval;
 573                gossip_debug(GOSSIP_FILE_DEBUG,
 574                             "orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n",
 575                             (unsigned long long)val);
 576                ret = orangefs_inode_setxattr(file_inode(file),
 577                                              "user.pvfs2.meta_hint",
 578                                              &val, sizeof(val), 0);
 579        }
 580
 581        return ret;
 582}
 583
 584/*
 585 * Memory map a region of a file.
 586 */
 587static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma)
 588{
 589        gossip_debug(GOSSIP_FILE_DEBUG,
 590                     "orangefs_file_mmap: called on %s\n",
 591                     (file ?
 592                        (char *)file->f_path.dentry->d_name.name :
 593                        (char *)"Unknown"));
 594
 595        /* set the sequential readahead hint */
 596        vma->vm_flags |= VM_SEQ_READ;
 597        vma->vm_flags &= ~VM_RAND_READ;
 598
 599        /* Use readonly mmap since we cannot support writable maps. */
 600        return generic_file_readonly_mmap(file, vma);
 601}
 602
 603#define mapping_nrpages(idata) ((idata)->nrpages)
 604
 605/*
 606 * Called to notify the module that there are no more references to
 607 * this file (i.e. no processes have it open).
 608 *
 609 * \note Not called when each file is closed.
 610 */
 611static int orangefs_file_release(struct inode *inode, struct file *file)
 612{
 613        gossip_debug(GOSSIP_FILE_DEBUG,
 614                     "orangefs_file_release: called on %pD\n",
 615                     file);
 616
 617        orangefs_flush_inode(inode);
 618
 619        /*
 620         * remove all associated inode pages from the page cache and
 621         * readahead cache (if any); this forces an expensive refresh of
 622         * data for the next caller of mmap (or 'get_block' accesses)
 623         */
 624        if (file_inode(file) &&
 625            file_inode(file)->i_mapping &&
 626            mapping_nrpages(&file_inode(file)->i_data)) {
 627                if (orangefs_features & ORANGEFS_FEATURE_READAHEAD) {
 628                        gossip_debug(GOSSIP_INODE_DEBUG,
 629                            "calling flush_racache on %pU\n",
 630                            get_khandle_from_ino(inode));
 631                        flush_racache(inode);
 632                        gossip_debug(GOSSIP_INODE_DEBUG,
 633                            "flush_racache finished\n");
 634                }
 635                truncate_inode_pages(file_inode(file)->i_mapping,
 636                                     0);
 637        }
 638        return 0;
 639}
 640
 641/*
 642 * Push all data for a specific file onto permanent storage.
 643 */
 644static int orangefs_fsync(struct file *file,
 645                       loff_t start,
 646                       loff_t end,
 647                       int datasync)
 648{
 649        int ret = -EINVAL;
 650        struct orangefs_inode_s *orangefs_inode =
 651                ORANGEFS_I(file_inode(file));
 652        struct orangefs_kernel_op_s *new_op = NULL;
 653
 654        /* required call */
 655        filemap_write_and_wait_range(file->f_mapping, start, end);
 656
 657        new_op = op_alloc(ORANGEFS_VFS_OP_FSYNC);
 658        if (!new_op)
 659                return -ENOMEM;
 660        new_op->upcall.req.fsync.refn = orangefs_inode->refn;
 661
 662        ret = service_operation(new_op,
 663                        "orangefs_fsync",
 664                        get_interruptible_flag(file_inode(file)));
 665
 666        gossip_debug(GOSSIP_FILE_DEBUG,
 667                     "orangefs_fsync got return value of %d\n",
 668                     ret);
 669
 670        op_release(new_op);
 671
 672        orangefs_flush_inode(file_inode(file));
 673        return ret;
 674}
 675
 676/*
 677 * Change the file pointer position for an instance of an open file.
 678 *
 679 * \note If .llseek is overriden, we must acquire lock as described in
 680 *       Documentation/filesystems/Locking.
 681 *
 682 * Future upgrade could support SEEK_DATA and SEEK_HOLE but would
 683 * require much changes to the FS
 684 */
 685static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin)
 686{
 687        int ret = -EINVAL;
 688        struct inode *inode = file_inode(file);
 689
 690        if (origin == SEEK_END) {
 691                /*
 692                 * revalidate the inode's file size.
 693                 * NOTE: We are only interested in file size here,
 694                 * so we set mask accordingly.
 695                 */
 696                ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1,
 697                    STATX_SIZE);
 698                if (ret == -ESTALE)
 699                        ret = -EIO;
 700                if (ret) {
 701                        gossip_debug(GOSSIP_FILE_DEBUG,
 702                                     "%s:%s:%d calling make bad inode\n",
 703                                     __FILE__,
 704                                     __func__,
 705                                     __LINE__);
 706                        return ret;
 707                }
 708        }
 709
 710        gossip_debug(GOSSIP_FILE_DEBUG,
 711                     "orangefs_file_llseek: offset is %ld | origin is %d"
 712                     " | inode size is %lu\n",
 713                     (long)offset,
 714                     origin,
 715                     (unsigned long)i_size_read(inode));
 716
 717        return generic_file_llseek(file, offset, origin);
 718}
 719
 720/*
 721 * Support local locks (locks that only this kernel knows about)
 722 * if Orangefs was mounted -o local_lock.
 723 */
 724static int orangefs_lock(struct file *filp, int cmd, struct file_lock *fl)
 725{
 726        int rc = -EINVAL;
 727
 728        if (ORANGEFS_SB(file_inode(filp)->i_sb)->flags & ORANGEFS_OPT_LOCAL_LOCK) {
 729                if (cmd == F_GETLK) {
 730                        rc = 0;
 731                        posix_test_lock(filp, fl);
 732                } else {
 733                        rc = posix_lock_file(filp, fl, NULL);
 734                }
 735        }
 736
 737        return rc;
 738}
 739
 740/** ORANGEFS implementation of VFS file operations */
 741const struct file_operations orangefs_file_operations = {
 742        .llseek         = orangefs_file_llseek,
 743        .read_iter      = orangefs_file_read_iter,
 744        .write_iter     = orangefs_file_write_iter,
 745        .lock           = orangefs_lock,
 746        .unlocked_ioctl = orangefs_ioctl,
 747        .mmap           = orangefs_file_mmap,
 748        .open           = generic_file_open,
 749        .release        = orangefs_file_release,
 750        .fsync          = orangefs_fsync,
 751};
 752