xref: /openbmc/linux/fs/nfs/nfs4file.c (revision 4bce6fce)
1 /*
2  *  linux/fs/nfs/file.c
3  *
4  *  Copyright (C) 1992  Rick Sladkey
5  */
6 #include <linux/fs.h>
7 #include <linux/falloc.h>
8 #include <linux/nfs_fs.h>
9 #include "internal.h"
10 #include "fscache.h"
11 #include "pnfs.h"
12 
13 #include "nfstrace.h"
14 
15 #ifdef CONFIG_NFS_V4_2
16 #include "nfs42.h"
17 #endif
18 
19 #define NFSDBG_FACILITY		NFSDBG_FILE
20 
21 static int
22 nfs4_file_open(struct inode *inode, struct file *filp)
23 {
24 	struct nfs_open_context *ctx;
25 	struct dentry *dentry = filp->f_path.dentry;
26 	struct dentry *parent = NULL;
27 	struct inode *dir;
28 	unsigned openflags = filp->f_flags;
29 	struct iattr attr;
30 	int opened = 0;
31 	int err;
32 
33 	/*
34 	 * If no cached dentry exists or if it's negative, NFSv4 handled the
35 	 * opens in ->lookup() or ->create().
36 	 *
37 	 * We only get this far for a cached positive dentry.  We skipped
38 	 * revalidation, so handle it here by dropping the dentry and returning
39 	 * -EOPENSTALE.  The VFS will retry the lookup/create/open.
40 	 */
41 
42 	dprintk("NFS: open file(%pd2)\n", dentry);
43 
44 	if ((openflags & O_ACCMODE) == 3)
45 		openflags--;
46 
47 	/* We can't create new files here */
48 	openflags &= ~(O_CREAT|O_EXCL);
49 
50 	parent = dget_parent(dentry);
51 	dir = d_inode(parent);
52 
53 	ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
54 	err = PTR_ERR(ctx);
55 	if (IS_ERR(ctx))
56 		goto out;
57 
58 	attr.ia_valid = ATTR_OPEN;
59 	if (openflags & O_TRUNC) {
60 		attr.ia_valid |= ATTR_SIZE;
61 		attr.ia_size = 0;
62 		nfs_sync_inode(inode);
63 	}
64 
65 	inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr, &opened);
66 	if (IS_ERR(inode)) {
67 		err = PTR_ERR(inode);
68 		switch (err) {
69 		case -EPERM:
70 		case -EACCES:
71 		case -EDQUOT:
72 		case -ENOSPC:
73 		case -EROFS:
74 			goto out_put_ctx;
75 		default:
76 			goto out_drop;
77 		}
78 	}
79 	if (inode != d_inode(dentry))
80 		goto out_drop;
81 
82 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
83 	nfs_file_set_open_context(filp, ctx);
84 	nfs_fscache_open_file(inode, filp);
85 	err = 0;
86 
87 out_put_ctx:
88 	put_nfs_open_context(ctx);
89 out:
90 	dput(parent);
91 	return err;
92 
93 out_drop:
94 	d_drop(dentry);
95 	err = -EOPENSTALE;
96 	goto out_put_ctx;
97 }
98 
99 static int
100 nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
101 {
102 	int ret;
103 	struct inode *inode = file_inode(file);
104 
105 	trace_nfs_fsync_enter(inode);
106 
107 	nfs_inode_dio_wait(inode);
108 	do {
109 		ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
110 		if (ret != 0)
111 			break;
112 		mutex_lock(&inode->i_mutex);
113 		ret = nfs_file_fsync_commit(file, start, end, datasync);
114 		if (!ret)
115 			ret = pnfs_sync_inode(inode, !!datasync);
116 		mutex_unlock(&inode->i_mutex);
117 		/*
118 		 * If nfs_file_fsync_commit detected a server reboot, then
119 		 * resend all dirty pages that might have been covered by
120 		 * the NFS_CONTEXT_RESEND_WRITES flag
121 		 */
122 		start = 0;
123 		end = LLONG_MAX;
124 	} while (ret == -EAGAIN);
125 
126 	trace_nfs_fsync_exit(inode, ret);
127 	return ret;
128 }
129 
130 #ifdef CONFIG_NFS_V4_2
131 static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
132 {
133 	loff_t ret;
134 
135 	switch (whence) {
136 	case SEEK_HOLE:
137 	case SEEK_DATA:
138 		ret = nfs42_proc_llseek(filep, offset, whence);
139 		if (ret != -ENOTSUPP)
140 			return ret;
141 	default:
142 		return nfs_file_llseek(filep, offset, whence);
143 	}
144 }
145 
146 static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t len)
147 {
148 	struct inode *inode = file_inode(filep);
149 	long ret;
150 
151 	if (!S_ISREG(inode->i_mode))
152 		return -EOPNOTSUPP;
153 
154 	if ((mode != 0) && (mode != (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)))
155 		return -EOPNOTSUPP;
156 
157 	ret = inode_newsize_ok(inode, offset + len);
158 	if (ret < 0)
159 		return ret;
160 
161 	if (mode & FALLOC_FL_PUNCH_HOLE)
162 		return nfs42_proc_deallocate(filep, offset, len);
163 	return nfs42_proc_allocate(filep, offset, len);
164 }
165 #endif /* CONFIG_NFS_V4_2 */
166 
167 const struct file_operations nfs4_file_operations = {
168 #ifdef CONFIG_NFS_V4_2
169 	.llseek		= nfs4_file_llseek,
170 #else
171 	.llseek		= nfs_file_llseek,
172 #endif
173 	.read_iter	= nfs_file_read,
174 	.write_iter	= nfs_file_write,
175 	.mmap		= nfs_file_mmap,
176 	.open		= nfs4_file_open,
177 	.flush		= nfs_file_flush,
178 	.release	= nfs_file_release,
179 	.fsync		= nfs4_file_fsync,
180 	.lock		= nfs_lock,
181 	.flock		= nfs_flock,
182 	.splice_read	= nfs_file_splice_read,
183 	.splice_write	= iter_file_splice_write,
184 #ifdef CONFIG_NFS_V4_2
185 	.fallocate	= nfs42_fallocate,
186 #endif /* CONFIG_NFS_V4_2 */
187 	.check_flags	= nfs_check_flags,
188 	.setlease	= simple_nosetlease,
189 };
190