2 * linux/fs/nfs/nfs3proc.c
4 * Client-side NFSv3 procedures stubs.
6 * Copyright (C) 1997, Olaf Kirch
10 #include <linux/utsname.h>
11 #include <linux/errno.h>
12 #include <linux/string.h>
13 #include <linux/sunrpc/clnt.h>
14 #include <linux/nfs.h>
15 #include <linux/nfs3.h>
16 #include <linux/nfs_fs.h>
18 #define NFSDBG_FACILITY NFSDBG_PROC
21 * Bare-bones access to getattr: this is for nfs_read_super.
24 nfs3_proc_get_root(struct nfs_server
*server
, struct nfs_fh
*fhandle
,
25 struct nfs_fattr
*fattr
)
29 dprintk("NFS call getroot\n");
31 status
= rpc_call(server
->client
, NFS3PROC_GETATTR
, fhandle
, fattr
, 0);
32 dprintk("NFS reply getroot\n");
37 * One function for each procedure in the NFS protocol.
40 nfs3_proc_getattr(struct dentry
*dentry
, struct nfs_fattr
*fattr
)
44 dprintk("NFS call getattr\n");
46 status
= rpc_call(NFS_CLIENT(dentry
->d_inode
), NFS3PROC_GETATTR
,
47 NFS_FH(dentry
), fattr
, 0);
48 dprintk("NFS reply getattr\n");
53 nfs3_proc_setattr(struct dentry
*dentry
, struct nfs_fattr
*fattr
,
56 struct nfs3_sattrargs arg
= { NFS_FH(dentry
), sattr
, 0, 0 };
59 dprintk("NFS call setattr\n");
61 status
= rpc_call(NFS_CLIENT(dentry
->d_inode
), NFS3PROC_SETATTR
, &arg
, fattr
, 0);
62 dprintk("NFS reply setattr\n");
67 nfs3_proc_lookup(struct dentry
*dir
, struct qstr
*name
,
68 struct nfs_fh
*fhandle
, struct nfs_fattr
*fattr
)
70 struct nfs_fattr dir_attr
;
71 struct nfs3_diropargs arg
= { NFS_FH(dir
), name
->name
, name
->len
};
72 struct nfs3_diropres res
= { &dir_attr
, fhandle
, fattr
};
75 dprintk("NFS call lookup %s\n", name
->name
);
78 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_LOOKUP
, &arg
, &res
, 0);
79 if (status
>= 0 && !(fattr
->valid
& NFS_ATTR_FATTR
))
80 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_GETATTR
,
82 dprintk("NFS reply lookup: %d\n", status
);
83 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
88 nfs3_proc_access(struct dentry
*dentry
, int mode
, int ruid
)
90 struct nfs_fattr fattr
;
91 struct nfs3_accessargs arg
= { NFS_FH(dentry
), 0 };
92 struct nfs3_accessres res
= { &fattr
, 0 };
95 dprintk("NFS call access\n");
99 arg
.access
|= NFS3_ACCESS_READ
;
100 if (S_ISDIR(dentry
->d_inode
->i_mode
)) {
101 if (mode
& MAY_WRITE
)
102 arg
.access
|= NFS3_ACCESS_MODIFY
| NFS3_ACCESS_EXTEND
| NFS3_ACCESS_DELETE
;
104 arg
.access
|= NFS3_ACCESS_LOOKUP
;
106 if (mode
& MAY_WRITE
)
107 arg
.access
|= NFS3_ACCESS_MODIFY
| NFS3_ACCESS_EXTEND
;
109 arg
.access
|= NFS3_ACCESS_EXECUTE
;
111 flags
= (ruid
) ? RPC_CALL_REALUID
: 0;
112 status
= rpc_call(NFS_CLIENT(dentry
->d_inode
), NFS3PROC_ACCESS
, &arg
, &res
, flags
);
113 nfs_refresh_inode(dentry
->d_inode
, &fattr
);
114 dprintk("NFS reply access\n");
116 if (status
== 0 && (arg
.access
& res
.access
) != arg
.access
)
122 nfs3_proc_readlink(struct dentry
*dentry
, void *buffer
, unsigned int buflen
)
124 struct nfs_fattr fattr
;
125 struct nfs3_readlinkargs args
= { NFS_FH(dentry
), buffer
, buflen
};
126 struct nfs3_readlinkres res
= { &fattr
, buffer
, buflen
};
129 dprintk("NFS call readlink\n");
131 status
= rpc_call(NFS_CLIENT(dentry
->d_inode
), NFS3PROC_READLINK
,
133 nfs_refresh_inode(dentry
->d_inode
, &fattr
);
134 dprintk("NFS reply readlink: %d\n", status
);
139 nfs3_proc_read(struct file
*file
, struct nfs_fattr
*fattr
, int flags
,
140 loff_t offset
, unsigned int count
, void *buffer
, int *eofp
)
142 struct dentry
*dentry
= file
->f_dentry
;
143 struct rpc_cred
*cred
= nfs_file_cred(file
);
144 struct nfs_readargs arg
= { NFS_FH(dentry
), offset
, count
, 1,
145 {{buffer
, count
}, {0,0}, {0,0}, {0,0},
146 {0,0}, {0,0}, {0,0}, {0,0}} };
147 struct nfs_readres res
= { fattr
, count
, 0 };
148 struct rpc_message msg
= { NFS3PROC_READ
, &arg
, &res
, cred
};
151 dprintk("NFS call read %d @ %Ld\n", count
, (long long)offset
);
153 status
= rpc_call_sync(NFS_CLIENT(dentry
->d_inode
), &msg
, flags
);
154 dprintk("NFS reply read: %d\n", status
);
160 nfs3_proc_write(struct file
*file
, struct nfs_fattr
*fattr
, int flags
,
161 loff_t offset
, unsigned int count
,
162 void *buffer
, struct nfs_writeverf
*verf
)
164 struct dentry
*dentry
= file
->f_dentry
;
165 struct rpc_cred
*cred
= nfs_file_cred(file
);
166 struct nfs_writeargs arg
= { NFS_FH(dentry
), offset
, count
,
168 {{buffer
, count
}, {0,0}, {0,0}, {0,0},
169 {0,0}, {0,0}, {0,0}, {0,0}} };
170 struct nfs_writeres res
= { fattr
, verf
, 0 };
171 struct rpc_message msg
= { NFS3PROC_WRITE
, &arg
, &res
, cred
};
172 int status
, rpcflags
= 0;
174 dprintk("NFS call write %d @ %Ld\n", count
, (long long)offset
);
176 if (flags
& NFS_RW_SWAP
)
177 rpcflags
|= NFS_RPC_SWAPFLAGS
;
178 arg
.stable
= (flags
& NFS_RW_SYNC
) ? NFS_FILE_SYNC
: NFS_UNSTABLE
;
180 status
= rpc_call_sync(NFS_CLIENT(dentry
->d_inode
), &msg
, rpcflags
);
182 dprintk("NFS reply read: %d\n", status
);
183 return status
< 0? status
: res
.count
;
187 * Create a regular file.
188 * For now, we don't implement O_EXCL.
191 nfs3_proc_create(struct dentry
*dir
, struct qstr
*name
, struct iattr
*sattr
,
192 int flags
, struct nfs_fh
*fhandle
, struct nfs_fattr
*fattr
)
194 struct nfs_fattr dir_attr
;
195 struct nfs3_createargs arg
= { NFS_FH(dir
), name
->name
, name
->len
,
196 sattr
, 0, { 0, 0 } };
197 struct nfs3_diropres res
= { &dir_attr
, fhandle
, fattr
};
200 dprintk("NFS call create %s\n", name
->name
);
201 arg
.createmode
= NFS3_CREATE_UNCHECKED
;
202 if (flags
& O_EXCL
) {
203 arg
.createmode
= NFS3_CREATE_EXCLUSIVE
;
204 arg
.verifier
[0] = jiffies
;
205 arg
.verifier
[1] = current
->pid
;
211 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_CREATE
, &arg
, &res
, 0);
212 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
214 /* If the server doesn't support the exclusive creation semantics,
215 * try again with simple 'guarded' mode. */
216 if (status
== NFSERR_NOTSUPP
) {
217 switch (arg
.createmode
) {
218 case NFS3_CREATE_EXCLUSIVE
:
219 arg
.createmode
= NFS3_CREATE_GUARDED
;
222 case NFS3_CREATE_GUARDED
:
223 arg
.createmode
= NFS3_CREATE_UNCHECKED
;
226 case NFS3_CREATE_UNCHECKED
:
233 dprintk("NFS reply create: %d\n", status
);
235 /* When we created the file with exclusive semantics, make
236 * sure we set the attributes afterwards. */
237 if (status
== 0 && arg
.createmode
== NFS3_CREATE_EXCLUSIVE
) {
238 struct nfs3_sattrargs arg
= { fhandle
, sattr
, 0, 0 };
239 dprintk("NFS call setattr (post-create)\n");
241 /* Note: we could use a guarded setattr here, but I'm
242 * not sure this buys us anything (and I'd have
243 * to revamp the NFSv3 XDR code) */
245 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_SETATTR
,
247 dprintk("NFS reply setattr (post-create): %d\n", status
);
254 nfs3_proc_remove(struct dentry
*dir
, struct qstr
*name
)
256 struct nfs_fattr dir_attr
;
257 struct nfs3_diropargs arg
= { NFS_FH(dir
), name
->name
, name
->len
};
258 struct rpc_message msg
= { NFS3PROC_REMOVE
, &arg
, &dir_attr
, NULL
};
261 dprintk("NFS call remove %s\n", name
->name
);
263 status
= rpc_call_sync(NFS_CLIENT(dir
->d_inode
), &msg
, 0);
264 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
265 dprintk("NFS reply remove: %d\n", status
);
270 nfs3_proc_rename(struct dentry
*old_dir
, struct qstr
*old_name
,
271 struct dentry
*new_dir
, struct qstr
*new_name
)
273 struct nfs_fattr old_dir_attr
, new_dir_attr
;
274 struct nfs3_renameargs arg
= { NFS_FH(old_dir
),
275 old_name
->name
, old_name
->len
,
277 new_name
->name
, new_name
->len
};
278 struct nfs3_renameres res
= { &old_dir_attr
, &new_dir_attr
};
281 dprintk("NFS call rename %s -> %s\n", old_name
->name
, new_name
->name
);
282 old_dir_attr
.valid
= 0;
283 new_dir_attr
.valid
= 0;
284 status
= rpc_call(NFS_CLIENT(old_dir
->d_inode
), NFS3PROC_RENAME
, &arg
, &res
, 0);
285 nfs_refresh_inode(old_dir
->d_inode
, &old_dir_attr
);
286 nfs_refresh_inode(new_dir
->d_inode
, &new_dir_attr
);
287 dprintk("NFS reply rename: %d\n", status
);
292 nfs3_proc_link(struct dentry
*dentry
, struct dentry
*dir
, struct qstr
*name
)
294 struct nfs_fattr dir_attr
, fattr
;
295 struct nfs3_linkargs arg
= { NFS_FH(dentry
), NFS_FH(dir
),
296 name
->name
, name
->len
};
297 struct nfs3_linkres res
= { &dir_attr
, &fattr
};
300 dprintk("NFS call link %s\n", name
->name
);
303 status
= rpc_call(NFS_CLIENT(dentry
->d_inode
), NFS3PROC_LINK
, &arg
, &res
, 0);
304 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
305 nfs_refresh_inode(dentry
->d_inode
, &fattr
);
306 dprintk("NFS reply link: %d\n", status
);
311 nfs3_proc_symlink(struct dentry
*dir
, struct qstr
*name
, struct qstr
*path
,
312 struct iattr
*sattr
, struct nfs_fh
*fhandle
,
313 struct nfs_fattr
*fattr
)
315 struct nfs_fattr dir_attr
;
316 struct nfs3_symlinkargs arg
= { NFS_FH(dir
), name
->name
, name
->len
,
317 path
->name
, path
->len
, sattr
};
318 struct nfs3_diropres res
= { &dir_attr
, fhandle
, fattr
};
321 dprintk("NFS call symlink %s -> %s\n", name
->name
, path
->name
);
324 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_SYMLINK
, &arg
, &res
, 0);
325 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
326 dprintk("NFS reply symlink: %d\n", status
);
331 nfs3_proc_mkdir(struct dentry
*dir
, struct qstr
*name
, struct iattr
*sattr
,
332 struct nfs_fh
*fhandle
, struct nfs_fattr
*fattr
)
334 struct nfs_fattr dir_attr
;
335 struct nfs3_createargs arg
= { NFS_FH(dir
), name
->name
, name
->len
,
336 sattr
, 0, { 0, 0 } };
337 struct nfs3_diropres res
= { &dir_attr
, fhandle
, fattr
};
340 dprintk("NFS call mkdir %s\n", name
->name
);
343 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_MKDIR
, &arg
, &res
, 0);
344 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
345 dprintk("NFS reply mkdir: %d\n", status
);
350 nfs3_proc_rmdir(struct dentry
*dir
, struct qstr
*name
)
352 struct nfs_fattr dir_attr
;
353 struct nfs3_diropargs arg
= { NFS_FH(dir
), name
->name
, name
->len
};
356 dprintk("NFS call rmdir %s\n", name
->name
);
358 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_RMDIR
, &arg
, &dir_attr
, 0);
359 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
360 dprintk("NFS reply rmdir: %d\n", status
);
365 * The READDIR implementation is somewhat hackish - we pass the user buffer
366 * to the encode function, which installs it in the receive iovec.
367 * The decode function itself doesn't perform any decoding, it just makes
368 * sure the reply is syntactically correct.
370 * Also note that this implementation handles both plain readdir and
374 nfs3_proc_readdir(struct file
*file
, u64 cookie
, void *entry
,
375 unsigned int size
, int plus
)
377 struct dentry
*dir
= file
->f_dentry
;
378 struct rpc_cred
*cred
= nfs_file_cred(file
);
379 struct nfs_fattr dir_attr
;
380 struct nfs3_readdirargs arg
= { NFS_FH(dir
), cookie
, {0, 0}, 0, 0, 0 };
381 struct nfs3_readdirres res
= { &dir_attr
, 0, 0, 0, 0 };
382 struct rpc_message msg
= { NFS3PROC_READDIR
, &arg
, &res
, cred
};
383 u32
*verf
= NFS_COOKIEVERF(dir
->d_inode
);
388 arg
.verf
[0] = verf
[0];
389 arg
.verf
[1] = verf
[1];
397 msg
.rpc_proc
= NFS3PROC_READDIRPLUS
;
399 dprintk("NFS call readdir%s %d\n",
400 plus
? "plus" : "", (unsigned int) cookie
);
403 status
= rpc_call_sync(NFS_CLIENT(dir
->d_inode
), &msg
, 0);
404 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
405 dprintk("NFS reply readdir: %d\n", status
);
410 nfs3_proc_mknod(struct dentry
*dir
, struct qstr
*name
, struct iattr
*sattr
,
411 dev_t rdev
, struct nfs_fh
*fh
, struct nfs_fattr
*fattr
)
413 struct nfs_fattr dir_attr
;
414 struct nfs3_mknodargs arg
= { NFS_FH(dir
), name
->name
, name
->len
, 0,
416 struct nfs3_diropres res
= { &dir_attr
, fh
, fattr
};
419 switch (sattr
->ia_mode
& S_IFMT
) {
420 case S_IFBLK
: arg
.type
= NF3BLK
; break;
421 case S_IFCHR
: arg
.type
= NF3CHR
; break;
422 case S_IFIFO
: arg
.type
= NF3FIFO
; break;
423 case S_IFSOCK
: arg
.type
= NF3SOCK
; break;
424 default: return -EINVAL
;
427 dprintk("NFS call mknod %s %x\n", name
->name
, rdev
);
430 status
= rpc_call(NFS_CLIENT(dir
->d_inode
), NFS3PROC_MKNOD
, &arg
, &res
, 0);
431 nfs_refresh_inode(dir
->d_inode
, &dir_attr
);
432 dprintk("NFS reply mknod: %d\n", status
);
437 * This is a combo call of fsstat and fsinfo
440 nfs3_proc_statfs(struct nfs_server
*server
, struct nfs_fh
*fhandle
,
441 struct nfs_fsinfo
*info
)
445 dprintk("NFS call fsstat\n");
446 memset((char *)info
, 0, sizeof(*info
));
447 status
= rpc_call(server
->client
, NFS3PROC_FSSTAT
, fhandle
, info
, 0);
450 status
= rpc_call(server
->client
, NFS3PROC_FSINFO
, fhandle
, info
, 0);
453 dprintk("NFS reply statfs: %d\n", status
);
457 extern u32
*nfs3_decode_dirent(u32
*, struct nfs_entry
*, int);
459 struct nfs_rpc_ops nfs_v3_clientops
= {
460 3, /* protocol version */