Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nfs4file.c
Go to the documentation of this file.
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 
12 static int
13 nfs4_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 
80 out_put_ctx:
82 out:
83  dput(parent);
84  return err;
85 
86 out_drop:
87  d_drop(dentry);
88  err = -EOPENSTALE;
89  goto out_put_ctx;
90 }
91 
92 static int
93 nfs4_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  do {
99  ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
100  if (ret != 0)
101  break;
102  mutex_lock(&inode->i_mutex);
103  ret = nfs_file_fsync_commit(file, start, end, datasync);
104  if (!ret && !datasync)
105  /* application has asked for meta-data sync */
106  ret = pnfs_layoutcommit_inode(inode, true);
107  mutex_unlock(&inode->i_mutex);
108  /*
109  * If nfs_file_fsync_commit detected a server reboot, then
110  * resend all dirty pages that might have been covered by
111  * the NFS_CONTEXT_RESEND_WRITES flag
112  */
113  start = 0;
114  end = LLONG_MAX;
115  } while (ret == -EAGAIN);
116 
117  return ret;
118 }
119 
121  .llseek = nfs_file_llseek,
122  .read = do_sync_read,
123  .write = do_sync_write,
124  .aio_read = nfs_file_read,
125  .aio_write = nfs_file_write,
126  .mmap = nfs_file_mmap,
127  .open = nfs4_file_open,
128  .flush = nfs_file_flush,
129  .release = nfs_file_release,
130  .fsync = nfs4_file_fsync,
131  .lock = nfs_lock,
132  .flock = nfs_flock,
133  .splice_read = nfs_file_splice_read,
134  .splice_write = nfs_file_splice_write,
135  .check_flags = nfs_check_flags,
136  .setlease = nfs_setlease,
137 };