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