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 inode
*inode
, struct nfs_fattr
*fattr
)
44 dprintk("NFS call getattr\n");
46 status
= rpc_call(NFS_CLIENT(inode
), NFS3PROC_GETATTR
,
47 NFS_FH(inode
), fattr
, 0);
48 dprintk("NFS reply getattr\n");
53 nfs3_proc_setattr(struct inode
*inode
, struct nfs_fattr
*fattr
,
56 struct nfs3_sattrargs arg
= { NFS_FH(inode
), sattr
, 0, 0 };
59 dprintk("NFS call setattr\n");
61 status
= rpc_call(NFS_CLIENT(inode
), NFS3PROC_SETATTR
, &arg
, fattr
, 0);
62 dprintk("NFS reply setattr\n");
67 nfs3_proc_lookup(struct inode
*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
), NFS3PROC_LOOKUP
, &arg
, &res
, 0);
79 if (status
>= 0 && !(fattr
->valid
& NFS_ATTR_FATTR
))
80 status
= rpc_call(NFS_CLIENT(dir
), NFS3PROC_GETATTR
,
82 dprintk("NFS reply lookup: %d\n", status
);
83 nfs_refresh_inode(dir
, &dir_attr
);
88 nfs3_proc_access(struct inode
*inode
, int mode
, int ruid
)
90 struct nfs_fattr fattr
;
91 struct nfs3_accessargs arg
= { NFS_FH(inode
), 0 };
92 struct nfs3_accessres res
= { &fattr
, 0 };
95 dprintk("NFS call access\n");
99 arg
.access
|= NFS3_ACCESS_READ
;
100 if (S_ISDIR(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(inode
), NFS3PROC_ACCESS
, &arg
, &res
, flags
);
113 nfs_refresh_inode(inode
, &fattr
);
114 dprintk("NFS reply access\n");
116 if (status
== 0 && (arg
.access
& res
.access
) != arg
.access
)
122 nfs3_proc_readlink(struct inode
*inode
, void *buffer
, unsigned int buflen
)
124 struct nfs_fattr fattr
;
125 struct nfs3_readlinkargs args
= { NFS_FH(inode
), buffer
, buflen
};
126 struct nfs3_readlinkres res
= { &fattr
, buffer
, buflen
};
129 dprintk("NFS call readlink\n");
131 status
= rpc_call(NFS_CLIENT(inode
), NFS3PROC_READLINK
,
133 nfs_refresh_inode(inode
, &fattr
);
134 dprintk("NFS reply readlink: %d\n", status
);
139 nfs3_proc_read(struct inode
*inode
, struct rpc_cred
*cred
,
140 struct nfs_fattr
*fattr
, int flags
,
141 loff_t offset
, unsigned int count
, void *buffer
, int *eofp
)
143 struct nfs_readargs arg
= { NFS_FH(inode
), offset
, count
, 1,
144 {{buffer
, count
}, {0,0}, {0,0}, {0,0},
145 {0,0}, {0,0}, {0,0}, {0,0}} };
146 struct nfs_readres res
= { fattr
, count
, 0 };
147 struct rpc_message msg
= { NFS3PROC_READ
, &arg
, &res
, cred
};
150 dprintk("NFS call read %d @ %Ld\n", count
, (long long)offset
);
152 status
= rpc_call_sync(NFS_CLIENT(inode
), &msg
, flags
);
153 dprintk("NFS reply read: %d\n", status
);
159 nfs3_proc_write(struct inode
*inode
, struct rpc_cred
*cred
,
160 struct nfs_fattr
*fattr
, int flags
,
161 loff_t offset
, unsigned int count
,
162 void *buffer
, struct nfs_writeverf
*verf
)
164 struct nfs_writeargs arg
= { NFS_FH(inode
), offset
, count
,
166 {{buffer
, count
}, {0,0}, {0,0}, {0,0},
167 {0,0}, {0,0}, {0,0}, {0,0}} };
168 struct nfs_writeres res
= { fattr
, verf
, 0 };
169 struct rpc_message msg
= { NFS3PROC_WRITE
, &arg
, &res
, cred
};
170 int status
, rpcflags
= 0;
172 dprintk("NFS call write %d @ %Ld\n", count
, (long long)offset
);
174 if (flags
& NFS_RW_SWAP
)
175 rpcflags
|= NFS_RPC_SWAPFLAGS
;
176 arg
.stable
= (flags
& NFS_RW_SYNC
) ? NFS_FILE_SYNC
: NFS_UNSTABLE
;
178 status
= rpc_call_sync(NFS_CLIENT(inode
), &msg
, rpcflags
);
180 dprintk("NFS reply read: %d\n", status
);
181 return status
< 0? status
: res
.count
;
185 * Create a regular file.
186 * For now, we don't implement O_EXCL.
189 nfs3_proc_create(struct inode
*dir
, struct qstr
*name
, struct iattr
*sattr
,
190 int flags
, struct nfs_fh
*fhandle
, struct nfs_fattr
*fattr
)
192 struct nfs_fattr dir_attr
;
193 struct nfs3_createargs arg
= { NFS_FH(dir
), name
->name
, name
->len
,
194 sattr
, 0, { 0, 0 } };
195 struct nfs3_diropres res
= { &dir_attr
, fhandle
, fattr
};
198 dprintk("NFS call create %s\n", name
->name
);
199 arg
.createmode
= NFS3_CREATE_UNCHECKED
;
200 if (flags
& O_EXCL
) {
201 arg
.createmode
= NFS3_CREATE_EXCLUSIVE
;
202 arg
.verifier
[0] = jiffies
;
203 arg
.verifier
[1] = current
->pid
;
209 status
= rpc_call(NFS_CLIENT(dir
), NFS3PROC_CREATE
, &arg
, &res
, 0);
210 nfs_refresh_inode(dir
, &dir_attr
);
212 /* If the server doesn't support the exclusive creation semantics,
213 * try again with simple 'guarded' mode. */
214 if (status
== NFSERR_NOTSUPP
) {
215 switch (arg
.createmode
) {
216 case NFS3_CREATE_EXCLUSIVE
:
217 arg
.createmode
= NFS3_CREATE_GUARDED
;
220 case NFS3_CREATE_GUARDED
:
221 arg
.createmode
= NFS3_CREATE_UNCHECKED
;
224 case NFS3_CREATE_UNCHECKED
:
231 dprintk("NFS reply create: %d\n", status
);
233 /* When we created the file with exclusive semantics, make
234 * sure we set the attributes afterwards. */
235 if (status
== 0 && arg
.createmode
== NFS3_CREATE_EXCLUSIVE
) {
236 struct nfs3_sattrargs arg
= { fhandle
, sattr
, 0, 0 };
237 dprintk("NFS call setattr (post-create)\n");
239 /* Note: we could use a guarded setattr here, but I'm
240 * not sure this buys us anything (and I'd have
241 * to revamp the NFSv3 XDR code) */
243 status
= rpc_call(NFS_CLIENT(dir
), NFS3PROC_SETATTR
,
245 dprintk("NFS reply setattr (post-create): %d\n", status
);
252 nfs3_proc_remove(struct inode
*dir
, struct qstr
*name
)
254 struct nfs_fattr dir_attr
;
255 struct nfs3_diropargs arg
= { NFS_FH(dir
), name
->name
, name
->len
};
256 struct rpc_message msg
= { NFS3PROC_REMOVE
, &arg
, &dir_attr
, NULL
};
259 dprintk("NFS call remove %s\n", name
->name
);
261 status
= rpc_call_sync(NFS_CLIENT(dir
), &msg
, 0);
262 nfs_refresh_inode(dir
, &dir_attr
);
263 dprintk("NFS reply remove: %d\n", status
);
268 nfs3_proc_unlink_setup(struct rpc_message
*msg
, struct dentry
*dir
, struct qstr
*name
)
270 struct nfs3_diropargs
*arg
;
271 struct nfs_fattr
*res
;
273 arg
= (struct nfs3_diropargs
*)kmalloc(sizeof(*arg
)+sizeof(*res
), GFP_KERNEL
);
276 res
= (struct nfs_fattr
*)(arg
+ 1);
277 arg
->fh
= NFS_FH(dir
->d_inode
);
278 arg
->name
= name
->name
;
279 arg
->len
= name
->len
;
281 msg
->rpc_proc
= NFS3PROC_REMOVE
;
288 nfs3_proc_unlink_done(struct dentry
*dir
, struct rpc_message
*msg
)
290 struct nfs_fattr
*dir_attr
;
293 dir_attr
= (struct nfs_fattr
*)msg
->rpc_resp
;
294 nfs_refresh_inode(dir
->d_inode
, dir_attr
);
295 kfree(msg
->rpc_argp
);
300 nfs3_proc_rename(struct inode
*old_dir
, struct qstr
*old_name
,
301 struct inode
*new_dir
, struct qstr
*new_name
)
303 struct nfs_fattr old_dir_attr
, new_dir_attr
;
304 struct nfs3_renameargs arg
= { NFS_FH(old_dir
),
305 old_name
->name
, old_name
->len
,
307 new_name
->name
, new_name
->len
};
308 struct nfs3_renameres res
= { &old_dir_attr
, &new_dir_attr
};
311 dprintk("NFS call rename %s -> %s\n", old_name
->name
, new_name
->name
);
312 old_dir_attr
.valid
= 0;
313 new_dir_attr
.valid
= 0;
314 status
= rpc_call(NFS_CLIENT(old_dir
), NFS3PROC_RENAME
, &arg
, &res
, 0);
315 nfs_refresh_inode(old_dir
, &old_dir_attr
);
316 nfs_refresh_inode(new_dir
, &new_dir_attr
);
317 dprintk("NFS reply rename: %d\n", status
);
322 nfs3_proc_link(struct inode
*inode
, struct inode
*dir
, struct qstr
*name
)
324 struct nfs_fattr dir_attr
, fattr
;
325 struct nfs3_linkargs arg
= { NFS_FH(inode
), NFS_FH(dir
),
326 name
->name
, name
->len
};
327 struct nfs3_linkres res
= { &dir_attr
, &fattr
};
330 dprintk("NFS call link %s\n", name
->name
);
333 status
= rpc_call(NFS_CLIENT(inode
), NFS3PROC_LINK
, &arg
, &res
, 0);
334 nfs_refresh_inode(dir
, &dir_attr
);
335 nfs_refresh_inode(inode
, &fattr
);
336 dprintk("NFS reply link: %d\n", status
);
341 nfs3_proc_symlink(struct inode
*dir
, struct qstr
*name
, struct qstr
*path
,
342 struct iattr
*sattr
, struct nfs_fh
*fhandle
,
343 struct nfs_fattr
*fattr
)
345 struct nfs_fattr dir_attr
;
346 struct nfs3_symlinkargs arg
= { NFS_FH(dir
), name
->name
, name
->len
,
347 path
->name
, path
->len
, sattr
};
348 struct nfs3_diropres res
= { &dir_attr
, fhandle
, fattr
};
351 dprintk("NFS call symlink %s -> %s\n", name
->name
, path
->name
);
354 status
= rpc_call(NFS_CLIENT(dir
), NFS3PROC_SYMLINK
, &arg
, &res
, 0);
355 nfs_refresh_inode(dir
, &dir_attr
);
356 dprintk("NFS reply symlink: %d\n", status
);
361 nfs3_proc_mkdir(struct inode
*dir
, struct qstr
*name
, struct iattr
*sattr
,
362 struct nfs_fh
*fhandle
, struct nfs_fattr
*fattr
)
364 struct nfs_fattr dir_attr
;
365 struct nfs3_createargs arg
= { NFS_FH(dir
), name
->name
, name
->len
,
366 sattr
, 0, { 0, 0 } };
367 struct nfs3_diropres res
= { &dir_attr
, fhandle
, fattr
};
370 dprintk("NFS call mkdir %s\n", name
->name
);
373 status
= rpc_call(NFS_CLIENT(dir
), NFS3PROC_MKDIR
, &arg
, &res
, 0);
374 nfs_refresh_inode(dir
, &dir_attr
);
375 dprintk("NFS reply mkdir: %d\n", status
);
380 nfs3_proc_rmdir(struct inode
*dir
, struct qstr
*name
)
382 struct nfs_fattr dir_attr
;
383 struct nfs3_diropargs arg
= { NFS_FH(dir
), name
->name
, name
->len
};
386 dprintk("NFS call rmdir %s\n", name
->name
);
388 status
= rpc_call(NFS_CLIENT(dir
), NFS3PROC_RMDIR
, &arg
, &dir_attr
, 0);
389 nfs_refresh_inode(dir
, &dir_attr
);
390 dprintk("NFS reply rmdir: %d\n", status
);
395 * The READDIR implementation is somewhat hackish - we pass the user buffer
396 * to the encode function, which installs it in the receive iovec.
397 * The decode function itself doesn't perform any decoding, it just makes
398 * sure the reply is syntactically correct.
400 * Also note that this implementation handles both plain readdir and
404 nfs3_proc_readdir(struct inode
*dir
, struct rpc_cred
*cred
,
405 u64 cookie
, void *entry
,
406 unsigned int size
, int plus
)
408 struct nfs_fattr dir_attr
;
409 struct nfs3_readdirargs arg
= { NFS_FH(dir
), cookie
, {0, 0}, 0, 0, 0 };
410 struct nfs3_readdirres res
= { &dir_attr
, 0, 0, 0, 0 };
411 struct rpc_message msg
= { NFS3PROC_READDIR
, &arg
, &res
, cred
};
412 u32
*verf
= NFS_COOKIEVERF(dir
);
417 arg
.verf
[0] = verf
[0];
418 arg
.verf
[1] = verf
[1];
426 msg
.rpc_proc
= NFS3PROC_READDIRPLUS
;
428 dprintk("NFS call readdir%s %d\n",
429 plus
? "plus" : "", (unsigned int) cookie
);
432 status
= rpc_call_sync(NFS_CLIENT(dir
), &msg
, 0);
433 nfs_refresh_inode(dir
, &dir_attr
);
434 dprintk("NFS reply readdir: %d\n", status
);
439 nfs3_proc_mknod(struct inode
*dir
, struct qstr
*name
, struct iattr
*sattr
,
440 dev_t rdev
, struct nfs_fh
*fh
, struct nfs_fattr
*fattr
)
442 struct nfs_fattr dir_attr
;
443 struct nfs3_mknodargs arg
= { NFS_FH(dir
), name
->name
, name
->len
, 0,
445 struct nfs3_diropres res
= { &dir_attr
, fh
, fattr
};
448 switch (sattr
->ia_mode
& S_IFMT
) {
449 case S_IFBLK
: arg
.type
= NF3BLK
; break;
450 case S_IFCHR
: arg
.type
= NF3CHR
; break;
451 case S_IFIFO
: arg
.type
= NF3FIFO
; break;
452 case S_IFSOCK
: arg
.type
= NF3SOCK
; break;
453 default: return -EINVAL
;
456 dprintk("NFS call mknod %s %x\n", name
->name
, rdev
);
459 status
= rpc_call(NFS_CLIENT(dir
), NFS3PROC_MKNOD
, &arg
, &res
, 0);
460 nfs_refresh_inode(dir
, &dir_attr
);
461 dprintk("NFS reply mknod: %d\n", status
);
466 * This is a combo call of fsstat and fsinfo
469 nfs3_proc_statfs(struct nfs_server
*server
, struct nfs_fh
*fhandle
,
470 struct nfs_fsinfo
*info
)
474 dprintk("NFS call fsstat\n");
475 memset((char *)info
, 0, sizeof(*info
));
476 status
= rpc_call(server
->client
, NFS3PROC_FSSTAT
, fhandle
, info
, 0);
479 status
= rpc_call(server
->client
, NFS3PROC_FSINFO
, fhandle
, info
, 0);
482 dprintk("NFS reply statfs: %d\n", status
);
486 extern u32
*nfs3_decode_dirent(u32
*, struct nfs_entry
*, int);
488 struct nfs_rpc_ops nfs_v3_clientops
= {
489 3, /* protocol version */
501 nfs3_proc_unlink_setup
,
502 nfs3_proc_unlink_done
,