Blame view

fs/nfs/nfs3proc.c 22.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
  /*
   *  linux/fs/nfs/nfs3proc.c
   *
   *  Client-side NFSv3 procedures stubs.
   *
   *  Copyright (C) 1997, Olaf Kirch
   */
  
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
  #include <linux/errno.h>
  #include <linux/string.h>
  #include <linux/sunrpc/clnt.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
13
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
  #include <linux/nfs.h>
  #include <linux/nfs3.h>
  #include <linux/nfs_fs.h>
  #include <linux/nfs_page.h>
  #include <linux/lockd/bind.h>
b7fa0554c   Andreas Gruenbacher   [PATCH] NFS: Add ...
19
  #include <linux/nfs_mount.h>
d310310cb   Jeff Layton   Freezer / sunrpc ...
20
  #include <linux/freezer.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21

006ea73e5   Chuck Lever   NFS: add hooks to...
22
  #include "iostat.h"
f7b422b17   David Howells   NFS: Split fs/nfs...
23
  #include "internal.h"
006ea73e5   Chuck Lever   NFS: add hooks to...
24

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  #define NFSDBG_FACILITY		NFSDBG_PROC
b68d69b8c   Jeff Layton   nfs: handle NFSv3...
26
  /* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
  static int
  nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  	int res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
  	do {
  		res = rpc_call_sync(clnt, msg, flags);
b68d69b8c   Jeff Layton   nfs: handle NFSv3...
33
  		if (res != -EJUKEBOX && res != -EKEYEXPIRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  			break;
d310310cb   Jeff Layton   Freezer / sunrpc ...
35
  		freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  		res = -ERESTARTSYS;
150030b78   Matthew Wilcox   NFS: Switch from ...
37
  	} while (!fatal_signal_pending(current));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
  	return res;
  }
dead28da8   Chuck Lever   SUNRPC: eliminate...
40
  #define rpc_call_sync(clnt, msg, flags)	nfs3_rpc_wrapper(clnt, msg, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
  
  static int
006ea73e5   Chuck Lever   NFS: add hooks to...
43
  nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  {
b68d69b8c   Jeff Layton   nfs: handle NFSv3...
45
  	if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  		return 0;
b68d69b8c   Jeff Layton   nfs: handle NFSv3...
47
48
  	if (task->tk_status == -EJUKEBOX)
  		nfs_inc_stats(inode, NFSIOS_DELAY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
  	task->tk_status = 0;
  	rpc_restart_call(task);
  	rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  static int
03c217339   J. Bruce Fields   NFSv3: try get_ro...
55
56
  do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
  		 struct nfs_fsinfo *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  {
dead28da8   Chuck Lever   SUNRPC: eliminate...
58
59
60
61
62
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_FSINFO],
  		.rpc_argp	= fhandle,
  		.rpc_resp	= info,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  	int	status;
3110ff804   Harvey Harrison   nfs: replace rema...
64
65
  	dprintk("%s: call  fsinfo
  ", __func__);
0e574af1b   Trond Myklebust   NFS: Cleanup init...
66
  	nfs_fattr_init(info->fattr);
dead28da8   Chuck Lever   SUNRPC: eliminate...
67
  	status = rpc_call_sync(client, &msg, 0);
3110ff804   Harvey Harrison   nfs: replace rema...
68
69
  	dprintk("%s: reply fsinfo: %d
  ", __func__, status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  	if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
dead28da8   Chuck Lever   SUNRPC: eliminate...
71
72
73
  		msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
  		msg.rpc_resp = info->fattr;
  		status = rpc_call_sync(client, &msg, 0);
3110ff804   Harvey Harrison   nfs: replace rema...
74
75
  		dprintk("%s: reply getattr: %d
  ", __func__, status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
80
  	}
  	return status;
  }
  
  /*
54ceac451   David Howells   NFS: Share NFS su...
81
   * Bare-bones access to getattr: this is for nfs_get_root/nfs_get_sb
03c217339   J. Bruce Fields   NFSv3: try get_ro...
82
83
84
85
86
87
88
89
   */
  static int
  nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  		   struct nfs_fsinfo *info)
  {
  	int	status;
  
  	status = do_proc_get_root(server->client, fhandle, info);
5006a76cc   David Howells   NFS: Eliminate cl...
90
91
  	if (status && server->nfs_client->cl_rpcclient != server->client)
  		status = do_proc_get_root(server->nfs_client->cl_rpcclient, fhandle, info);
03c217339   J. Bruce Fields   NFSv3: try get_ro...
92
93
94
95
  	return status;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
99
100
101
   * One function for each procedure in the NFS protocol.
   */
  static int
  nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
  		struct nfs_fattr *fattr)
  {
dead28da8   Chuck Lever   SUNRPC: eliminate...
102
103
104
105
106
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_GETATTR],
  		.rpc_argp	= fhandle,
  		.rpc_resp	= fattr,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
109
110
  	int	status;
  
  	dprintk("NFS call  getattr
  ");
0e574af1b   Trond Myklebust   NFS: Cleanup init...
111
  	nfs_fattr_init(fattr);
dead28da8   Chuck Lever   SUNRPC: eliminate...
112
  	status = rpc_call_sync(server->client, &msg, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  	dprintk("NFS reply getattr: %d
  ", status);
  	return status;
  }
  
  static int
  nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
  			struct iattr *sattr)
  {
  	struct inode *inode = dentry->d_inode;
  	struct nfs3_sattrargs	arg = {
  		.fh		= NFS_FH(inode),
  		.sattr		= sattr,
  	};
dead28da8   Chuck Lever   SUNRPC: eliminate...
127
128
129
130
131
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_SETATTR],
  		.rpc_argp	= &arg,
  		.rpc_resp	= fattr,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
135
  	int	status;
  
  	dprintk("NFS call  setattr
  ");
659bfcd6d   Trond Myklebust   NFS: Fix the ftru...
136
137
  	if (sattr->ia_valid & ATTR_FILE)
  		msg.rpc_cred = nfs_file_cred(sattr->ia_file);
0e574af1b   Trond Myklebust   NFS: Cleanup init...
138
  	nfs_fattr_init(fattr);
dead28da8   Chuck Lever   SUNRPC: eliminate...
139
  	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
65e4308d2   Trond Myklebust   [PATCH] NFS: Ensu...
140
141
  	if (status == 0)
  		nfs_setattr_update_inode(inode, sattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
147
  	dprintk("NFS reply setattr: %d
  ", status);
  	return status;
  }
  
  static int
7c5130588   Bryan Schumaker   NFS: lookup suppo...
148
  nfs3_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
  		 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
156
  	struct nfs3_diropargs	arg = {
  		.fh		= NFS_FH(dir),
  		.name		= name->name,
  		.len		= name->len
  	};
  	struct nfs3_diropres	res = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
  		.fh		= fhandle,
  		.fattr		= fattr
  	};
dead28da8   Chuck Lever   SUNRPC: eliminate...
160
161
162
163
164
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_LOOKUP],
  		.rpc_argp	= &arg,
  		.rpc_resp	= &res,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
167
168
  	int			status;
  
  	dprintk("NFS call  lookup %s
  ", name->name);
e1fb4d05d   Trond Myklebust   NFS: Reduce the s...
169
170
171
  	res.dir_attr = nfs_alloc_fattr();
  	if (res.dir_attr == NULL)
  		return -ENOMEM;
0e574af1b   Trond Myklebust   NFS: Cleanup init...
172
  	nfs_fattr_init(fattr);
dead28da8   Chuck Lever   SUNRPC: eliminate...
173
  	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
e1fb4d05d   Trond Myklebust   NFS: Reduce the s...
174
  	nfs_refresh_inode(dir, res.dir_attr);
dead28da8   Chuck Lever   SUNRPC: eliminate...
175
176
177
178
179
180
  	if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
  		msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
  		msg.rpc_argp = fhandle;
  		msg.rpc_resp = fattr;
  		status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
  	}
e1fb4d05d   Trond Myklebust   NFS: Reduce the s...
181
  	nfs_free_fattr(res.dir_attr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
  	dprintk("NFS reply lookup: %d
  ", status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
186
187
188
  	return status;
  }
  
  static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
191
  	struct nfs3_accessargs	arg = {
  		.fh		= NFS_FH(inode),
  	};
c407d41a1   Trond Myklebust   NFSv4: Reduce sta...
192
  	struct nfs3_accessres	res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
195
196
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_ACCESS],
  		.rpc_argp	= &arg,
  		.rpc_resp	= &res,
dead28da8   Chuck Lever   SUNRPC: eliminate...
197
  		.rpc_cred	= entry->cred,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
  	};
  	int mode = entry->mask;
c407d41a1   Trond Myklebust   NFSv4: Reduce sta...
200
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
  
  	dprintk("NFS call  access
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  
  	if (mode & MAY_READ)
  		arg.access |= NFS3_ACCESS_READ;
  	if (S_ISDIR(inode->i_mode)) {
  		if (mode & MAY_WRITE)
  			arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE;
  		if (mode & MAY_EXEC)
  			arg.access |= NFS3_ACCESS_LOOKUP;
  	} else {
  		if (mode & MAY_WRITE)
  			arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND;
  		if (mode & MAY_EXEC)
  			arg.access |= NFS3_ACCESS_EXECUTE;
  	}
c407d41a1   Trond Myklebust   NFSv4: Reduce sta...
218
219
220
221
  
  	res.fattr = nfs_alloc_fattr();
  	if (res.fattr == NULL)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
c407d41a1   Trond Myklebust   NFSv4: Reduce sta...
223
  	nfs_refresh_inode(inode, res.fattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
226
227
228
229
230
231
232
  	if (status == 0) {
  		entry->mask = 0;
  		if (res.access & NFS3_ACCESS_READ)
  			entry->mask |= MAY_READ;
  		if (res.access & (NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE))
  			entry->mask |= MAY_WRITE;
  		if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
  			entry->mask |= MAY_EXEC;
  	}
c407d41a1   Trond Myklebust   NFSv4: Reduce sta...
233
234
  	nfs_free_fattr(res.fattr);
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
237
238
239
240
241
242
  	dprintk("NFS reply access: %d
  ", status);
  	return status;
  }
  
  static int nfs3_proc_readlink(struct inode *inode, struct page *page,
  		unsigned int pgbase, unsigned int pglen)
  {
3b14d6542   Trond Myklebust   NFS: Reduce stack...
243
  	struct nfs_fattr	*fattr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
246
247
248
249
  	struct nfs3_readlinkargs args = {
  		.fh		= NFS_FH(inode),
  		.pgbase		= pgbase,
  		.pglen		= pglen,
  		.pages		= &page
  	};
dead28da8   Chuck Lever   SUNRPC: eliminate...
250
251
252
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_READLINK],
  		.rpc_argp	= &args,
dead28da8   Chuck Lever   SUNRPC: eliminate...
253
  	};
3b14d6542   Trond Myklebust   NFS: Reduce stack...
254
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
256
257
  
  	dprintk("NFS call  readlink
  ");
3b14d6542   Trond Myklebust   NFS: Reduce stack...
258
259
260
261
  	fattr = nfs_alloc_fattr();
  	if (fattr == NULL)
  		goto out;
  	msg.rpc_resp = fattr;
dead28da8   Chuck Lever   SUNRPC: eliminate...
262
  	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
3b14d6542   Trond Myklebust   NFS: Reduce stack...
263
264
265
  	nfs_refresh_inode(inode, fattr);
  	nfs_free_fattr(fattr);
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
268
269
  	dprintk("NFS reply readlink: %d
  ", status);
  	return status;
  }
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
  struct nfs3_createdata {
  	struct rpc_message msg;
  	union {
  		struct nfs3_createargs create;
  		struct nfs3_mkdirargs mkdir;
  		struct nfs3_symlinkargs symlink;
  		struct nfs3_mknodargs mknod;
  	} arg;
  	struct nfs3_diropres res;
  	struct nfs_fh fh;
  	struct nfs_fattr fattr;
  	struct nfs_fattr dir_attr;
  };
  
  static struct nfs3_createdata *nfs3_alloc_createdata(void)
  {
  	struct nfs3_createdata *data;
  
  	data = kzalloc(sizeof(*data), GFP_KERNEL);
  	if (data != NULL) {
  		data->msg.rpc_argp = &data->arg;
  		data->msg.rpc_resp = &data->res;
  		data->res.fh = &data->fh;
  		data->res.fattr = &data->fattr;
  		data->res.dir_attr = &data->dir_attr;
  		nfs_fattr_init(data->res.fattr);
  		nfs_fattr_init(data->res.dir_attr);
  	}
  	return data;
  }
  
  static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data)
  {
  	int status;
  
  	status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0);
  	nfs_post_op_update_inode(dir, data->res.dir_attr);
  	if (status == 0)
  		status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
  	return status;
  }
  
  static void nfs3_free_createdata(struct nfs3_createdata *data)
  {
  	kfree(data);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
317
  /*
   * Create a regular file.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
320
   */
  static int
  nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
c0204fd2b   Trond Myklebust   NFS: Clean up nfs...
321
  		 int flags, struct nfs_open_context *ctx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  {
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
323
  	struct nfs3_createdata *data;
d3fb61207   Al Viro   switch posix_acl_...
324
  	umode_t mode = sattr->ia_mode;
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
325
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
327
328
  
  	dprintk("NFS call  create %s
  ", dentry->d_name.name);
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
329
330
331
332
333
334
335
336
337
338
339
340
  
  	data = nfs3_alloc_createdata();
  	if (data == NULL)
  		goto out;
  
  	data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_CREATE];
  	data->arg.create.fh = NFS_FH(dir);
  	data->arg.create.name = dentry->d_name.name;
  	data->arg.create.len = dentry->d_name.len;
  	data->arg.create.sattr = sattr;
  
  	data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
  	if (flags & O_EXCL) {
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
342
343
344
  		data->arg.create.createmode  = NFS3_CREATE_EXCLUSIVE;
  		data->arg.create.verifier[0] = jiffies;
  		data->arg.create.verifier[1] = current->pid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
  	}
ce3b0f8d5   Al Viro   New helper - curr...
346
  	sattr->ia_mode &= ~current_umask();
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
347

0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
348
349
  	for (;;) {
  		status = nfs3_do_create(dir, dentry, data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350

0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
351
352
353
354
355
  		if (status != -ENOTSUPP)
  			break;
  		/* If the server doesn't support the exclusive creation
  		 * semantics, try again with simple 'guarded' mode. */
  		switch (data->arg.create.createmode) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
  			case NFS3_CREATE_EXCLUSIVE:
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
357
  				data->arg.create.createmode = NFS3_CREATE_GUARDED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
359
360
  				break;
  
  			case NFS3_CREATE_GUARDED:
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
361
  				data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
364
365
366
  				break;
  
  			case NFS3_CREATE_UNCHECKED:
  				goto out;
  		}
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
367
368
  		nfs_fattr_init(data->res.dir_attr);
  		nfs_fattr_init(data->res.fattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
372
373
374
  	if (status != 0)
  		goto out;
  
  	/* When we created the file with exclusive semantics, make
  	 * sure we set the attributes afterwards. */
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
375
  	if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
377
378
379
380
381
382
383
384
385
386
  		dprintk("NFS call  setattr (post-create)
  ");
  
  		if (!(sattr->ia_valid & ATTR_ATIME_SET))
  			sattr->ia_valid |= ATTR_ATIME;
  		if (!(sattr->ia_valid & ATTR_MTIME_SET))
  			sattr->ia_valid |= ATTR_MTIME;
  
  		/* Note: we could use a guarded setattr here, but I'm
  		 * not sure this buys us anything (and I'd have
  		 * to revamp the NFSv3 XDR code) */
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
387
388
  		status = nfs3_proc_setattr(dentry, data->res.fattr, sattr);
  		nfs_post_op_update_inode(dentry->d_inode, data->res.fattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
  		dprintk("NFS reply setattr (post-create): %d
  ", status);
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
391
392
  		if (status != 0)
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
  	}
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
394
  	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  out:
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
396
  	nfs3_free_createdata(data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
399
400
401
402
403
404
  	dprintk("NFS reply create: %d
  ", status);
  	return status;
  }
  
  static int
  nfs3_proc_remove(struct inode *dir, struct qstr *name)
  {
4fdc17b2a   Trond Myklebust   NFS: Introduce st...
405
406
407
408
  	struct nfs_removeargs arg = {
  		.fh = NFS_FH(dir),
  		.name.len = name->len,
  		.name.name = name->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  	};
4fdc17b2a   Trond Myklebust   NFS: Introduce st...
410
411
412
413
414
  	struct nfs_removeres res;
  	struct rpc_message msg = {
  		.rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE],
  		.rpc_argp = &arg,
  		.rpc_resp = &res,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  	};
d346890be   Trond Myklebust   NFS: Reduce stack...
416
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
418
419
  
  	dprintk("NFS call  remove %s
  ", name->name);
d346890be   Trond Myklebust   NFS: Reduce stack...
420
421
422
  	res.dir_attr = nfs_alloc_fattr();
  	if (res.dir_attr == NULL)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
d346890be   Trond Myklebust   NFS: Reduce stack...
424
425
426
  	nfs_post_op_update_inode(dir, res.dir_attr);
  	nfs_free_fattr(res.dir_attr);
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
428
429
430
  	dprintk("NFS reply remove: %d
  ", status);
  	return status;
  }
e4eff1a62   Trond Myklebust   SUNRPC: Clean up ...
431
432
  static void
  nfs3_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  	msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
436
437
  }
  
  static int
e4eff1a62   Trond Myklebust   SUNRPC: Clean up ...
438
  nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
  {
e4eff1a62   Trond Myklebust   SUNRPC: Clean up ...
440
441
442
443
  	struct nfs_removeres *res;
  	if (nfs3_async_handle_jukebox(task, dir))
  		return 0;
  	res = task->tk_msg.rpc_resp;
d346890be   Trond Myklebust   NFS: Reduce stack...
444
  	nfs_post_op_update_inode(dir, res->dir_attr);
e4eff1a62   Trond Myklebust   SUNRPC: Clean up ...
445
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  }
d3d4152a5   Jeff Layton   nfs: make sillyre...
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  static void
  nfs3_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
  {
  	msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
  }
  
  static int
  nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
  		      struct inode *new_dir)
  {
  	struct nfs_renameres *res;
  
  	if (nfs3_async_handle_jukebox(task, old_dir))
  		return 0;
  	res = task->tk_msg.rpc_resp;
  
  	nfs_post_op_update_inode(old_dir, res->old_fattr);
  	nfs_post_op_update_inode(new_dir, res->new_fattr);
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
468
469
470
  static int
  nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
  		 struct inode *new_dir, struct qstr *new_name)
  {
920769f03   Jeff Layton   nfs: standardize ...
471
472
473
474
475
  	struct nfs_renameargs	arg = {
  		.old_dir	= NFS_FH(old_dir),
  		.old_name	= old_name,
  		.new_dir	= NFS_FH(new_dir),
  		.new_name	= new_name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
  	};
e8582a8b9   Jeff Layton   nfs: standardize ...
477
  	struct nfs_renameres res;
dead28da8   Chuck Lever   SUNRPC: eliminate...
478
479
480
481
482
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_RENAME],
  		.rpc_argp	= &arg,
  		.rpc_resp	= &res,
  	};
011fff723   Trond Myklebust   NFS: Reduce stack...
483
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
485
486
  
  	dprintk("NFS call  rename %s -> %s
  ", old_name->name, new_name->name);
011fff723   Trond Myklebust   NFS: Reduce stack...
487

e8582a8b9   Jeff Layton   nfs: standardize ...
488
489
490
  	res.old_fattr = nfs_alloc_fattr();
  	res.new_fattr = nfs_alloc_fattr();
  	if (res.old_fattr == NULL || res.new_fattr == NULL)
011fff723   Trond Myklebust   NFS: Reduce stack...
491
  		goto out;
dead28da8   Chuck Lever   SUNRPC: eliminate...
492
  	status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
e8582a8b9   Jeff Layton   nfs: standardize ...
493
494
  	nfs_post_op_update_inode(old_dir, res.old_fattr);
  	nfs_post_op_update_inode(new_dir, res.new_fattr);
011fff723   Trond Myklebust   NFS: Reduce stack...
495
  out:
e8582a8b9   Jeff Layton   nfs: standardize ...
496
497
  	nfs_free_fattr(res.old_fattr);
  	nfs_free_fattr(res.new_fattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
500
501
502
503
504
505
  	dprintk("NFS reply rename: %d
  ", status);
  	return status;
  }
  
  static int
  nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
507
508
509
510
511
  	struct nfs3_linkargs	arg = {
  		.fromfh		= NFS_FH(inode),
  		.tofh		= NFS_FH(dir),
  		.toname		= name->name,
  		.tolen		= name->len
  	};
136f2627c   Trond Myklebust   NFS: Reduce the s...
512
  	struct nfs3_linkres	res;
dead28da8   Chuck Lever   SUNRPC: eliminate...
513
514
515
516
517
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_LINK],
  		.rpc_argp	= &arg,
  		.rpc_resp	= &res,
  	};
136f2627c   Trond Myklebust   NFS: Reduce the s...
518
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
520
521
  
  	dprintk("NFS call  link %s
  ", name->name);
136f2627c   Trond Myklebust   NFS: Reduce the s...
522
523
524
525
  	res.fattr = nfs_alloc_fattr();
  	res.dir_attr = nfs_alloc_fattr();
  	if (res.fattr == NULL || res.dir_attr == NULL)
  		goto out;
dead28da8   Chuck Lever   SUNRPC: eliminate...
526
  	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
136f2627c   Trond Myklebust   NFS: Reduce the s...
527
528
529
530
531
  	nfs_post_op_update_inode(dir, res.dir_attr);
  	nfs_post_op_update_inode(inode, res.fattr);
  out:
  	nfs_free_fattr(res.dir_attr);
  	nfs_free_fattr(res.fattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
537
  	dprintk("NFS reply link: %d
  ", status);
  	return status;
  }
  
  static int
94a6d7532   Chuck Lever   NFS: Use cached p...
538
539
  nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
  		  unsigned int len, struct iattr *sattr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
  {
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
541
542
  	struct nfs3_createdata *data;
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543

94a6d7532   Chuck Lever   NFS: Use cached p...
544
  	if (len > NFS3_MAXPATHLEN)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
  		return -ENAMETOOLONG;
4f390c152   Chuck Lever   NFS: Fix double d...
546

94a6d7532   Chuck Lever   NFS: Use cached p...
547
548
  	dprintk("NFS call  symlink %s
  ", dentry->d_name.name);
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
549
550
  	data = nfs3_alloc_createdata();
  	if (data == NULL)
4f390c152   Chuck Lever   NFS: Fix double d...
551
  		goto out;
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
552
553
554
555
556
557
558
559
560
561
562
  	data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK];
  	data->arg.symlink.fromfh = NFS_FH(dir);
  	data->arg.symlink.fromname = dentry->d_name.name;
  	data->arg.symlink.fromlen = dentry->d_name.len;
  	data->arg.symlink.pages = &page;
  	data->arg.symlink.pathlen = len;
  	data->arg.symlink.sattr = sattr;
  
  	status = nfs3_do_create(dir, dentry, data);
  
  	nfs3_free_createdata(data);
4f390c152   Chuck Lever   NFS: Fix double d...
563
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564
565
566
567
568
569
570
571
  	dprintk("NFS reply symlink: %d
  ", status);
  	return status;
  }
  
  static int
  nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
  {
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
572
  	struct nfs3_createdata *data;
d3fb61207   Al Viro   switch posix_acl_...
573
  	umode_t mode = sattr->ia_mode;
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
574
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
576
577
  
  	dprintk("NFS call  mkdir %s
  ", dentry->d_name.name);
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
578

ce3b0f8d5   Al Viro   New helper - curr...
579
  	sattr->ia_mode &= ~current_umask();
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
580

0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
581
582
  	data = nfs3_alloc_createdata();
  	if (data == NULL)
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
583
  		goto out;
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
584
585
586
587
588
589
590
591
  
  	data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR];
  	data->arg.mkdir.fh = NFS_FH(dir);
  	data->arg.mkdir.name = dentry->d_name.name;
  	data->arg.mkdir.len = dentry->d_name.len;
  	data->arg.mkdir.sattr = sattr;
  
  	status = nfs3_do_create(dir, dentry, data);
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
592
593
  	if (status != 0)
  		goto out;
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
594

055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
595
596
  	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
  out:
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
597
  	nfs3_free_createdata(data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
600
601
602
603
604
605
  	dprintk("NFS reply mkdir: %d
  ", status);
  	return status;
  }
  
  static int
  nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
  {
39967ddf1   Trond Myklebust   NFS: Reduce the s...
606
  	struct nfs_fattr	*dir_attr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
609
610
611
  	struct nfs3_diropargs	arg = {
  		.fh		= NFS_FH(dir),
  		.name		= name->name,
  		.len		= name->len
  	};
dead28da8   Chuck Lever   SUNRPC: eliminate...
612
613
614
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_RMDIR],
  		.rpc_argp	= &arg,
dead28da8   Chuck Lever   SUNRPC: eliminate...
615
  	};
39967ddf1   Trond Myklebust   NFS: Reduce the s...
616
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
618
619
  
  	dprintk("NFS call  rmdir %s
  ", name->name);
39967ddf1   Trond Myklebust   NFS: Reduce the s...
620
621
622
623
624
  	dir_attr = nfs_alloc_fattr();
  	if (dir_attr == NULL)
  		goto out;
  
  	msg.rpc_resp = dir_attr;
dead28da8   Chuck Lever   SUNRPC: eliminate...
625
  	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
39967ddf1   Trond Myklebust   NFS: Reduce the s...
626
627
628
  	nfs_post_op_update_inode(dir, dir_attr);
  	nfs_free_fattr(dir_attr);
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
  	dprintk("NFS reply rmdir: %d
  ", status);
  	return status;
  }
  
  /*
   * The READDIR implementation is somewhat hackish - we pass the user buffer
   * to the encode function, which installs it in the receive iovec.
   * The decode function itself doesn't perform any decoding, it just makes
   * sure the reply is syntactically correct.
   *
   * Also note that this implementation handles both plain readdir and
   * readdirplus.
   */
  static int
  nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
56e4ebf87   Bryan Schumaker   NFS: readdir with...
645
  		  u64 cookie, struct page **pages, unsigned int count, int plus)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
  {
  	struct inode		*dir = dentry->d_inode;
bc4785cd4   Al Viro   [PATCH] nfs: veri...
648
  	__be32			*verf = NFS_COOKIEVERF(dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649
650
651
652
653
654
  	struct nfs3_readdirargs	arg = {
  		.fh		= NFS_FH(dir),
  		.cookie		= cookie,
  		.verf		= {verf[0], verf[1]},
  		.plus		= plus,
  		.count		= count,
56e4ebf87   Bryan Schumaker   NFS: readdir with...
655
  		.pages		= pages
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
  	};
  	struct nfs3_readdirres	res = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
660
661
662
663
664
665
666
  		.verf		= verf,
  		.plus		= plus
  	};
  	struct rpc_message	msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_READDIR],
  		.rpc_argp	= &arg,
  		.rpc_resp	= &res,
  		.rpc_cred	= cred
  	};
aa49b4cf7   Trond Myklebust   NFS: Reduce stack...
667
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
670
671
672
673
674
  	if (plus)
  		msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
  
  	dprintk("NFS call  readdir%s %d
  ",
  			plus? "plus" : "", (unsigned int) cookie);
aa49b4cf7   Trond Myklebust   NFS: Reduce stack...
675
676
677
  	res.dir_attr = nfs_alloc_fattr();
  	if (res.dir_attr == NULL)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
  	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
c48129983   Trond Myklebust   NFS: Fix atime re...
679
680
  
  	nfs_invalidate_atime(dir);
aa49b4cf7   Trond Myklebust   NFS: Reduce stack...
681
  	nfs_refresh_inode(dir, res.dir_attr);
c48129983   Trond Myklebust   NFS: Fix atime re...
682

aa49b4cf7   Trond Myklebust   NFS: Reduce stack...
683
684
  	nfs_free_fattr(res.dir_attr);
  out:
d141d9743   Chuck Lever   NFS: Fix NFSv3 de...
685
686
687
  	dprintk("NFS reply readdir%s: %d
  ",
  			plus? "plus" : "", status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
689
690
691
692
693
694
  	return status;
  }
  
  static int
  nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
  		dev_t rdev)
  {
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
695
  	struct nfs3_createdata *data;
d3fb61207   Al Viro   switch posix_acl_...
696
  	umode_t mode = sattr->ia_mode;
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
697
  	int status = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
699
700
701
  
  	dprintk("NFS call  mknod %s %u:%u
  ", dentry->d_name.name,
  			MAJOR(rdev), MINOR(rdev));
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
702

ce3b0f8d5   Al Viro   New helper - curr...
703
  	sattr->ia_mode &= ~current_umask();
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
704

0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
705
706
  	data = nfs3_alloc_createdata();
  	if (data == NULL)
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
707
  		goto out;
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
  
  	data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD];
  	data->arg.mknod.fh = NFS_FH(dir);
  	data->arg.mknod.name = dentry->d_name.name;
  	data->arg.mknod.len = dentry->d_name.len;
  	data->arg.mknod.sattr = sattr;
  	data->arg.mknod.rdev = rdev;
  
  	switch (sattr->ia_mode & S_IFMT) {
  	case S_IFBLK:
  		data->arg.mknod.type = NF3BLK;
  		break;
  	case S_IFCHR:
  		data->arg.mknod.type = NF3CHR;
  		break;
  	case S_IFIFO:
  		data->arg.mknod.type = NF3FIFO;
  		break;
  	case S_IFSOCK:
  		data->arg.mknod.type = NF3SOCK;
  		break;
  	default:
  		status = -EINVAL;
  		goto out;
  	}
  
  	status = nfs3_do_create(dir, dentry, data);
055ffbea0   Andreas Gruenbacher   [PATCH] NFS: Fix ...
735
736
737
738
  	if (status != 0)
  		goto out;
  	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
  out:
0b4aae7aa   Trond Myklebust   NFS: Reduce the s...
739
  	nfs3_free_createdata(data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
740
741
742
743
744
745
746
747
748
  	dprintk("NFS reply mknod: %d
  ", status);
  	return status;
  }
  
  static int
  nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
  		 struct nfs_fsstat *stat)
  {
dead28da8   Chuck Lever   SUNRPC: eliminate...
749
750
751
752
753
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_FSSTAT],
  		.rpc_argp	= fhandle,
  		.rpc_resp	= stat,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
757
  	int	status;
  
  	dprintk("NFS call  fsstat
  ");
0e574af1b   Trond Myklebust   NFS: Cleanup init...
758
  	nfs_fattr_init(stat->fattr);
dead28da8   Chuck Lever   SUNRPC: eliminate...
759
  	status = rpc_call_sync(server->client, &msg, 0);
d141d9743   Chuck Lever   NFS: Fix NFSv3 de...
760
761
  	dprintk("NFS reply fsstat: %d
  ", status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
763
764
765
  	return status;
  }
  
  static int
37ca8f5c6   EG Keizer   nfs: authenticate...
766
  do_proc_fsinfo(struct rpc_clnt *client, struct nfs_fh *fhandle,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
768
  		 struct nfs_fsinfo *info)
  {
dead28da8   Chuck Lever   SUNRPC: eliminate...
769
770
771
772
773
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_FSINFO],
  		.rpc_argp	= fhandle,
  		.rpc_resp	= info,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
774
775
776
777
  	int	status;
  
  	dprintk("NFS call  fsinfo
  ");
0e574af1b   Trond Myklebust   NFS: Cleanup init...
778
  	nfs_fattr_init(info->fattr);
37ca8f5c6   EG Keizer   nfs: authenticate...
779
  	status = rpc_call_sync(client, &msg, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
781
782
783
  	dprintk("NFS reply fsinfo: %d
  ", status);
  	return status;
  }
37ca8f5c6   EG Keizer   nfs: authenticate...
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
  /*
   * Bare-bones access to fsinfo: this is for nfs_get_root/nfs_get_sb via
   * nfs_create_server
   */
  static int
  nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
  		   struct nfs_fsinfo *info)
  {
  	int	status;
  
  	status = do_proc_fsinfo(server->client, fhandle, info);
  	if (status && server->nfs_client->cl_rpcclient != server->client)
  		status = do_proc_fsinfo(server->nfs_client->cl_rpcclient, fhandle, info);
  	return status;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799
800
801
802
  static int
  nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
  		   struct nfs_pathconf *info)
  {
dead28da8   Chuck Lever   SUNRPC: eliminate...
803
804
805
806
807
  	struct rpc_message msg = {
  		.rpc_proc	= &nfs3_procedures[NFS3PROC_PATHCONF],
  		.rpc_argp	= fhandle,
  		.rpc_resp	= info,
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
809
810
811
  	int	status;
  
  	dprintk("NFS call  pathconf
  ");
0e574af1b   Trond Myklebust   NFS: Cleanup init...
812
  	nfs_fattr_init(info->fattr);
dead28da8   Chuck Lever   SUNRPC: eliminate...
813
  	status = rpc_call_sync(server->client, &msg, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
814
815
816
817
  	dprintk("NFS reply pathconf: %d
  ", status);
  	return status;
  }
ec06c096e   Trond Myklebust   NFS: Cleanup of N...
818
  static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
  {
006ea73e5   Chuck Lever   NFS: add hooks to...
820
  	if (nfs3_async_handle_jukebox(task, data->inode))
ec06c096e   Trond Myklebust   NFS: Cleanup of N...
821
  		return -EAGAIN;
8850df999   Trond Myklebust   NFS: Fix atime re...
822
823
824
  
  	nfs_invalidate_atime(data->inode);
  	nfs_refresh_inode(data->inode, &data->fattr);
ec06c096e   Trond Myklebust   NFS: Cleanup of N...
825
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826
  }
bdc7f021f   Trond Myklebust   NFS: Clean up the...
827
  static void nfs3_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
  {
bdc7f021f   Trond Myklebust   NFS: Clean up the...
829
  	msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830
  }
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
831
  static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
832
  {
006ea73e5   Chuck Lever   NFS: add hooks to...
833
  	if (nfs3_async_handle_jukebox(task, data->inode))
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
834
  		return -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835
  	if (task->tk_status >= 0)
70ca88521   Trond Myklebust   NFS: Fake up 'wcc...
836
  		nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
837
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
  }
bdc7f021f   Trond Myklebust   NFS: Clean up the...
839
  static void nfs3_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
  {
bdc7f021f   Trond Myklebust   NFS: Clean up the...
841
  	msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
  }
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
843
  static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
  {
006ea73e5   Chuck Lever   NFS: add hooks to...
845
  	if (nfs3_async_handle_jukebox(task, data->inode))
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
846
  		return -EAGAIN;
9e08a3c5a   Trond Myklebust   NFS: Use nfs_refr...
847
  	nfs_refresh_inode(data->inode, data->res.fattr);
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
848
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
  }
bdc7f021f   Trond Myklebust   NFS: Clean up the...
850
  static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
  {
bdc7f021f   Trond Myklebust   NFS: Clean up the...
852
  	msg->rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
855
856
857
  }
  
  static int
  nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
  {
1093a60ef   Chuck Lever   NLM/NFS: Use cach...
858
859
860
  	struct inode *inode = filp->f_path.dentry->d_inode;
  
  	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
  }
509de8111   David Howells   NFS: Add extra co...
862
  const struct nfs_rpc_ops nfs_v3_clientops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
864
  	.version	= 3,			/* protocol version */
  	.dentry_ops	= &nfs_dentry_operations,
b7fa0554c   Andreas Gruenbacher   [PATCH] NFS: Add ...
865
866
  	.dir_inode_ops	= &nfs3_dir_inode_operations,
  	.file_inode_ops	= &nfs3_file_inode_operations,
1788ea6e3   Jeff Layton   nfs: when attempt...
867
  	.file_ops	= &nfs_file_operations,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
869
870
871
872
873
  	.getroot	= nfs3_proc_get_root,
  	.getattr	= nfs3_proc_getattr,
  	.setattr	= nfs3_proc_setattr,
  	.lookup		= nfs3_proc_lookup,
  	.access		= nfs3_proc_access,
  	.readlink	= nfs3_proc_readlink,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
876
877
878
  	.create		= nfs3_proc_create,
  	.remove		= nfs3_proc_remove,
  	.unlink_setup	= nfs3_proc_unlink_setup,
  	.unlink_done	= nfs3_proc_unlink_done,
  	.rename		= nfs3_proc_rename,
d3d4152a5   Jeff Layton   nfs: make sillyre...
879
880
  	.rename_setup	= nfs3_proc_rename_setup,
  	.rename_done	= nfs3_proc_rename_done,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
881
882
883
884
885
886
887
888
889
890
891
  	.link		= nfs3_proc_link,
  	.symlink	= nfs3_proc_symlink,
  	.mkdir		= nfs3_proc_mkdir,
  	.rmdir		= nfs3_proc_rmdir,
  	.readdir	= nfs3_proc_readdir,
  	.mknod		= nfs3_proc_mknod,
  	.statfs		= nfs3_proc_statfs,
  	.fsinfo		= nfs3_proc_fsinfo,
  	.pathconf	= nfs3_proc_pathconf,
  	.decode_dirent	= nfs3_decode_dirent,
  	.read_setup	= nfs3_proc_read_setup,
ec06c096e   Trond Myklebust   NFS: Cleanup of N...
892
  	.read_done	= nfs3_read_done,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893
  	.write_setup	= nfs3_proc_write_setup,
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
894
  	.write_done	= nfs3_write_done,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
895
  	.commit_setup	= nfs3_proc_commit_setup,
788e7a89a   Trond Myklebust   NFS: Cleanup of N...
896
  	.commit_done	= nfs3_commit_done,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
  	.lock		= nfs3_proc_lock,
5c6a9f7d9   Andreas Gruenbacher   [PATCH] NFS: Cach...
898
  	.clear_acl_cache = nfs3_forget_cached_acls,
7fe5c398f   Trond Myklebust   NFS: Optimise NFS...
899
  	.close_context	= nfs_close_context,
45a52a020   Andy Adamson   NFS move nfs_clie...
900
  	.init_client	= nfs_init_client,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
  };