linux/fs/nfs/nfs4file.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/nfs/file.c
   3 *
   4 *  Copyright (C) 1992  Rick Sladkey
   5 */
   6#include <linux/nfs_fs.h>
   7#include "internal.h"
   8#include "pnfs.h"
   9
  10#define NFSDBG_FACILITY         NFSDBG_FILE
  11
  12static int
  13nfs4_file_open(struct inode *inode, struct file *filp)
  14{
  15        struct nfs_open_context *ctx;
  16        struct dentry *dentry = filp->f_path.dentry;
  17        struct dentry *parent = NULL;
  18        struct inode *dir;
  19        unsigned openflags = filp->f_flags;
  20        struct iattr attr;
  21        int err;
  22
  23        BUG_ON(inode != dentry->d_inode);
  24        /*
  25         * If no cached dentry exists or if it's negative, NFSv4 handled the
  26         * opens in ->lookup() or ->create().
  27         *
  28         * We only get this far for a cached positive dentry.  We skipped
  29         * revalidation, so handle it here by dropping the dentry and returning
  30         * -EOPENSTALE.  The VFS will retry the lookup/create/open.
  31         */
  32
  33        dprintk("NFS: open file(%s/%s)\n",
  34                dentry->d_parent->d_name.name,
  35                dentry->d_name.name);
  36
  37        if ((openflags & O_ACCMODE) == 3)
  38                openflags--;
  39
  40        /* We can't create new files here */
  41        openflags &= ~(O_CREAT|O_EXCL);
  42
  43        parent = dget_parent(dentry);
  44        dir = parent->d_inode;
  45
  46        ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
  47        err = PTR_ERR(ctx);
  48        if (IS_ERR(ctx))
  49                goto out;
  50
  51        attr.ia_valid = ATTR_OPEN;
  52        if (openflags & O_TRUNC) {
  53                attr.ia_valid |= ATTR_SIZE;
  54                attr.ia_size = 0;
  55                nfs_wb_all(inode);
  56        }
  57
  58        inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr);
  59        if (IS_ERR(inode)) {
  60                err = PTR_ERR(inode);
  61                switch (err) {
  62                case -EPERM:
  63                case -EACCES:
  64                case -EDQUOT:
  65                case -ENOSPC:
  66                case -EROFS:
  67                        goto out_put_ctx;
  68                default:
  69                        goto out_drop;
  70                }
  71        }
  72        iput(inode);
  73        if (inode != dentry->d_inode)
  74                goto out_drop;
  75
  76        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
  77        nfs_file_set_open_context(filp, ctx);
  78        err = 0;
  79
  80out_put_ctx:
  81        put_nfs_open_context(ctx);
  82out:
  83        dput(parent);
  84        return err;
  85
  86out_drop:
  87        d_drop(dentry);
  88        err = -EOPENSTALE;
  89        goto out_put_ctx;
  90}
  91
  92static int
  93nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
  94{
  95        int ret;
  96        struct inode *inode = file->f_path.dentry->d_inode;
  97
  98        ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
  99        if (ret != 0)
 100                goto out;
 101        mutex_lock(&inode->i_mutex);
 102        ret = nfs_file_fsync_commit(file, start, end, datasync);
 103        if (!ret && !datasync)
 104                /* application has asked for meta-data sync */
 105                ret = pnfs_layoutcommit_inode(inode, true);
 106        mutex_unlock(&inode->i_mutex);
 107out:
 108        return ret;
 109}
 110
 111const struct file_operations nfs4_file_operations = {
 112        .llseek         = nfs_file_llseek,
 113        .read           = do_sync_read,
 114        .write          = do_sync_write,
 115        .aio_read       = nfs_file_read,
 116        .aio_write      = nfs_file_write,
 117        .mmap           = nfs_file_mmap,
 118        .open           = nfs4_file_open,
 119        .flush          = nfs_file_flush,
 120        .release        = nfs_file_release,
 121        .fsync          = nfs4_file_fsync,
 122        .lock           = nfs_lock,
 123        .flock          = nfs_flock,
 124        .splice_read    = nfs_file_splice_read,
 125        .splice_write   = nfs_file_splice_write,
 126        .check_flags    = nfs_check_flags,
 127        .setlease       = nfs_setlease,
 128};
 129
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.