OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [nfs/] [nfs2xdr.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/fs/nfs/nfs2xdr.c
3
 *
4
 * XDR functions to encode/decode NFS RPC arguments and results.
5
 *
6
 * Copyright (C) 1992, 1993, 1994  Rick Sladkey
7
 * Copyright (C) 1996 Olaf Kirch
8
 * 04 Aug 1998  Ion Badulescu <ionut@cs.columbia.edu>
9
 *              FIFO's need special handling in NFSv2
10
 */
11
 
12
#include <linux/param.h>
13
#include <linux/sched.h>
14
#include <linux/mm.h>
15
#include <linux/slab.h>
16
#include <linux/utsname.h>
17
#include <linux/errno.h>
18
#include <linux/string.h>
19
#include <linux/in.h>
20
#include <linux/pagemap.h>
21
#include <linux/proc_fs.h>
22
#include <linux/sunrpc/clnt.h>
23
#include <linux/nfs.h>
24
#include <linux/nfs2.h>
25
#include <linux/nfs_fs.h>
26
 
27
#define NFSDBG_FACILITY         NFSDBG_XDR
28
/* #define NFS_PARANOIA 1 */
29
 
30
extern int                      nfs_stat_to_errno(int stat);
31
 
32
/* Mapping from NFS error code to "errno" error code. */
33
#define errno_NFSERR_IO         EIO
34
 
35
/*
36
 * Declare the space requirements for NFS arguments and replies as
37
 * number of 32bit-words
38
 */
39
#define NFS_fhandle_sz          8
40
#define NFS_sattr_sz            8
41
#define NFS_filename_sz         1+(NFS2_MAXNAMLEN>>2)
42
#define NFS_path_sz             1+(NFS2_MAXPATHLEN>>2)
43
#define NFS_fattr_sz            17
44
#define NFS_info_sz             5
45
#define NFS_entry_sz            NFS_filename_sz+3
46
 
47
#define NFS_enc_void_sz         0
48
#define NFS_diropargs_sz        NFS_fhandle_sz+NFS_filename_sz
49
#define NFS_sattrargs_sz        NFS_fhandle_sz+NFS_sattr_sz
50
#define NFS_readlinkargs_sz     NFS_fhandle_sz
51
#define NFS_readargs_sz         NFS_fhandle_sz+3
52
#define NFS_writeargs_sz        NFS_fhandle_sz+4
53
#define NFS_createargs_sz       NFS_diropargs_sz+NFS_sattr_sz
54
#define NFS_renameargs_sz       NFS_diropargs_sz+NFS_diropargs_sz
55
#define NFS_linkargs_sz         NFS_fhandle_sz+NFS_diropargs_sz
56
#define NFS_symlinkargs_sz      NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz
57
#define NFS_readdirargs_sz      NFS_fhandle_sz+2
58
 
59
#define NFS_dec_void_sz         0
60
#define NFS_attrstat_sz         1+NFS_fattr_sz
61
#define NFS_diropres_sz         1+NFS_fhandle_sz+NFS_fattr_sz
62
#define NFS_readlinkres_sz      1
63
#define NFS_readres_sz          1+NFS_fattr_sz+1
64
#define NFS_writeres_sz         NFS_attrstat_sz
65
#define NFS_stat_sz             1
66
#define NFS_readdirres_sz       1
67
#define NFS_statfsres_sz        1+NFS_info_sz
68
 
69
/*
70
 * Common NFS XDR functions as inlines
71
 */
72
static inline u32 *
73
xdr_encode_fhandle(u32 *p, struct nfs_fh *fhandle)
74
{
75
        memcpy(p, fhandle->data, NFS2_FHSIZE);
76
        return p + XDR_QUADLEN(NFS2_FHSIZE);
77
}
78
 
79
static inline u32 *
80
xdr_decode_fhandle(u32 *p, struct nfs_fh *fhandle)
81
{
82
        /* Zero handle first to allow comparisons */
83
        memset(fhandle, 0, sizeof(*fhandle));
84
        /* NFSv2 handles have a fixed length */
85
        fhandle->size = NFS2_FHSIZE;
86
        memcpy(fhandle->data, p, NFS2_FHSIZE);
87
        return p + XDR_QUADLEN(NFS2_FHSIZE);
88
}
89
 
90
static inline u32*
91
xdr_decode_time(u32 *p, u64 *timep)
92
{
93
        u64 tmp = (u64)ntohl(*p++) << 32;
94
        *timep = tmp + (u64)ntohl(*p++);
95
        return p;
96
}
97
 
98
static u32 *
99
xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
100
{
101
        fattr->type = (enum nfs_ftype) ntohl(*p++);
102
        fattr->mode = ntohl(*p++);
103
        fattr->nlink = ntohl(*p++);
104
        fattr->uid = ntohl(*p++);
105
        fattr->gid = ntohl(*p++);
106
        fattr->size = ntohl(*p++);
107
        fattr->du.nfs2.blocksize = ntohl(*p++);
108
        fattr->rdev = ntohl(*p++);
109
        fattr->du.nfs2.blocks = ntohl(*p++);
110
        fattr->fsid = ntohl(*p++);
111
        fattr->fileid = ntohl(*p++);
112
        p = xdr_decode_time(p, &fattr->atime);
113
        p = xdr_decode_time(p, &fattr->mtime);
114
        p = xdr_decode_time(p, &fattr->ctime);
115
        fattr->valid |= NFS_ATTR_FATTR;
116
        if (fattr->type == NFCHR && fattr->rdev == NFS2_FIFO_DEV) {
117
                fattr->type = NFFIFO;
118
                fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
119
                fattr->rdev = 0;
120
        }
121
        return p;
122
}
123
 
124
#define SATTR(p, attr, flag, field) \
125
        *p++ = (attr->ia_valid & flag) ? htonl(attr->field) : ~(u32) 0
126
static inline u32 *
127
xdr_encode_sattr(u32 *p, struct iattr *attr)
128
{
129
        SATTR(p, attr, ATTR_MODE, ia_mode);
130
        SATTR(p, attr, ATTR_UID, ia_uid);
131
        SATTR(p, attr, ATTR_GID, ia_gid);
132
        SATTR(p, attr, ATTR_SIZE, ia_size);
133
 
134
        if (attr->ia_valid & (ATTR_ATIME|ATTR_ATIME_SET)) {
135
                *p++ = htonl(attr->ia_atime);
136
                *p++ = 0;
137
        } else {
138
                *p++ = ~(u32) 0;
139
                *p++ = ~(u32) 0;
140
        }
141
 
142
        if (attr->ia_valid & (ATTR_MTIME|ATTR_MTIME_SET)) {
143
                *p++ = htonl(attr->ia_mtime);
144
                *p++ = 0;
145
        } else {
146
                *p++ = ~(u32) 0;
147
                *p++ = ~(u32) 0;
148
        }
149
        return p;
150
}
151
#undef SATTR
152
 
153
/*
154
 * NFS encode functions
155
 */
156
/*
157
 * Encode void argument
158
 */
159
static int
160
nfs_xdr_enc_void(struct rpc_rqst *req, u32 *p, void *dummy)
161
{
162
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
163
        return 0;
164
}
165
 
166
/*
167
 * Encode file handle argument
168
 * GETATTR, READLINK, STATFS
169
 */
170
static int
171
nfs_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh)
172
{
173
        p = xdr_encode_fhandle(p, fh);
174
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
175
        return 0;
176
}
177
 
178
/*
179
 * Encode SETATTR arguments
180
 */
181
static int
182
nfs_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs_sattrargs *args)
183
{
184
        p = xdr_encode_fhandle(p, args->fh);
185
        p = xdr_encode_sattr(p, args->sattr);
186
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
187
        return 0;
188
}
189
 
190
/*
191
 * Encode directory ops argument
192
 * LOOKUP, REMOVE, RMDIR
193
 */
194
static int
195
nfs_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs_diropargs *args)
196
{
197
        p = xdr_encode_fhandle(p, args->fh);
198
        p = xdr_encode_array(p, args->name, args->len);
199
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
200
        return 0;
201
}
202
 
203
/*
204
 * Arguments to a READ call. Since we read data directly into the page
205
 * cache, we also set up the reply iovec here so that iov[1] points
206
 * exactly to the page we want to fetch.
207
 */
208
static int
209
nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
210
{
211
        struct rpc_auth *auth = req->rq_task->tk_auth;
212
        unsigned int replen;
213
        u32 offset = (u32)args->offset;
214
        u32 count = args->count;
215
 
216
        p = xdr_encode_fhandle(p, args->fh);
217
        *p++ = htonl(offset);
218
        *p++ = htonl(count);
219
        *p++ = htonl(count);
220
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
221
 
222
        /* Inline the page array */
223
        replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
224
        xdr_inline_pages(&req->rq_rcv_buf, replen,
225
                         args->pages, args->pgbase, count);
226
        return 0;
227
}
228
 
229
/*
230
 * Decode READ reply
231
 */
232
static int
233
nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
234
{
235
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
236
        struct iovec *iov = req->rq_rvec;
237
        int     status, count, recvd, hdrlen;
238
 
239
        if ((status = ntohl(*p++)))
240
                return -nfs_stat_to_errno(status);
241
        p = xdr_decode_fattr(p, res->fattr);
242
 
243
        count = ntohl(*p++);
244
        res->eof = 0;
245
        if (rcvbuf->page_len) {
246
                u32 end = page_offset(rcvbuf->pages[0]) + rcvbuf->page_base + count;
247
                if (end >= res->fattr->size)
248
                        res->eof = 1;
249
        }
250
        hdrlen = (u8 *) p - (u8 *) iov->iov_base;
251
        if (iov->iov_len < hdrlen) {
252
                printk(KERN_WARNING "NFS: READ reply header overflowed:"
253
                                "length %d > %Zu\n", hdrlen, iov->iov_len);
254
                return -errno_NFSERR_IO;
255
        } else if (iov->iov_len != hdrlen) {
256
                dprintk("NFS: READ header is short. iovec will be shifted.\n");
257
                xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
258
        }
259
 
260
        recvd = req->rq_received - hdrlen;
261
        if (count > recvd) {
262
                printk(KERN_WARNING "NFS: server cheating in read reply: "
263
                        "count %d > recvd %d\n", count, recvd);
264
                count = recvd;
265
                res->eof = 0;
266
        }
267
 
268
        dprintk("RPC:      readres OK count %d\n", count);
269
        if (count < res->count)
270
                res->count = count;
271
 
272
        return count;
273
}
274
 
275
 
276
/*
277
 * Write arguments. Splice the buffer to be written into the iovec.
278
 */
279
static int
280
nfs_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
281
{
282
        struct xdr_buf *sndbuf = &req->rq_snd_buf;
283
        u32 offset = (u32)args->offset;
284
        u32 count = args->count;
285
 
286
        p = xdr_encode_fhandle(p, args->fh);
287
        *p++ = htonl(offset);
288
        *p++ = htonl(offset);
289
        *p++ = htonl(count);
290
        *p++ = htonl(count);
291
        sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
292
 
293
        /* Copy the page array */
294
        xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
295
        return 0;
296
}
297
 
298
/*
299
 * Encode create arguments
300
 * CREATE, MKDIR
301
 */
302
static int
303
nfs_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs_createargs *args)
304
{
305
        p = xdr_encode_fhandle(p, args->fh);
306
        p = xdr_encode_array(p, args->name, args->len);
307
        p = xdr_encode_sattr(p, args->sattr);
308
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
309
        return 0;
310
}
311
 
312
/*
313
 * Encode RENAME arguments
314
 */
315
static int
316
nfs_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs_renameargs *args)
317
{
318
        p = xdr_encode_fhandle(p, args->fromfh);
319
        p = xdr_encode_array(p, args->fromname, args->fromlen);
320
        p = xdr_encode_fhandle(p, args->tofh);
321
        p = xdr_encode_array(p, args->toname, args->tolen);
322
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
323
        return 0;
324
}
325
 
326
/*
327
 * Encode LINK arguments
328
 */
329
static int
330
nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args)
331
{
332
        p = xdr_encode_fhandle(p, args->fromfh);
333
        p = xdr_encode_fhandle(p, args->tofh);
334
        p = xdr_encode_array(p, args->toname, args->tolen);
335
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
336
        return 0;
337
}
338
 
339
/*
340
 * Encode SYMLINK arguments
341
 */
342
static int
343
nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args)
344
{
345
        p = xdr_encode_fhandle(p, args->fromfh);
346
        p = xdr_encode_array(p, args->fromname, args->fromlen);
347
        p = xdr_encode_array(p, args->topath, args->tolen);
348
        p = xdr_encode_sattr(p, args->sattr);
349
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
350
        return 0;
351
}
352
 
353
/*
354
 * Encode arguments to readdir call
355
 */
356
static int
357
nfs_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs_readdirargs *args)
358
{
359
        struct rpc_task *task = req->rq_task;
360
        struct rpc_auth *auth = task->tk_auth;
361
        unsigned int replen;
362
        u32 count = args->count;
363
 
364
        /*
365
         * Some servers (e.g. HP OS 9.5) seem to expect the buffer size
366
         * to be in longwords ... check whether to convert the size.
367
         */
368
        if (task->tk_client->cl_flags & NFS_CLNTF_BUFSIZE)
369
                count = count >> 2;
370
 
371
        p = xdr_encode_fhandle(p, args->fh);
372
        *p++ = htonl(args->cookie);
373
        *p++ = htonl(count); /* see above */
374
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
375
 
376
        /* Inline the page array */
377
        replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2;
378
        xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
379
        return 0;
380
}
381
 
382
/*
383
 * Decode the result of a readdir call.
384
 * We're not really decoding anymore, we just leave the buffer untouched
385
 * and only check that it is syntactically correct.
386
 * The real decoding happens in nfs_decode_entry below, called directly
387
 * from nfs_readdir for each entry.
388
 */
389
static int
390
nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
391
{
392
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
393
        struct iovec *iov = rcvbuf->head;
394
        struct page **page;
395
        int hdrlen, recvd;
396
        int status, nr;
397
        unsigned int len, pglen;
398
        u32 *end, *entry;
399
 
400
        if ((status = ntohl(*p++)))
401
                return -nfs_stat_to_errno(status);
402
 
403
        hdrlen = (u8 *) p - (u8 *) iov->iov_base;
404
        if (iov->iov_len < hdrlen) {
405
                printk(KERN_WARNING "NFS: READDIR reply header overflowed:"
406
                                "length %d > %Zu\n", hdrlen, iov->iov_len);
407
                return -errno_NFSERR_IO;
408
        } else if (iov->iov_len != hdrlen) {
409
                dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
410
                xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
411
        }
412
 
413
        pglen = rcvbuf->page_len;
414
        recvd = req->rq_received - hdrlen;
415
        if (pglen > recvd)
416
                pglen = recvd;
417
        page = rcvbuf->pages;
418
        p = kmap(*page);
419
        entry = p;
420
        end = (u32 *)((char *)p + pglen);
421
        for (nr = 0; *p++; nr++) {
422
                if (p + 2 > end)
423
                        goto short_pkt;
424
                p++; /* fileid */
425
                len = ntohl(*p++);
426
                p += XDR_QUADLEN(len) + 1;      /* name plus cookie */
427
                if (len > NFS2_MAXNAMLEN) {
428
                        printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)!\n",
429
                                                len);
430
                        goto err_unmap;
431
                }
432
                if (p + 2 > end)
433
                        goto short_pkt;
434
                entry = p;
435
        }
436
        if (!nr && (entry[0] != 0 || entry[1] == 0))
437
                goto short_pkt;
438
 out:
439
        kunmap(*page);
440
        return nr;
441
 short_pkt:
442
        entry[0] = entry[1] = 0;
443
        /* truncate listing ? */
444
        if (!nr) {
445
                printk(KERN_NOTICE "NFS: readdir reply truncated!\n");
446
                entry[1] = 1;
447
        }
448
        goto out;
449
err_unmap:
450
        kunmap(*page);
451
        return -errno_NFSERR_IO;
452
}
453
 
454
u32 *
455
nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
456
{
457
        if (!*p++) {
458
                if (!*p)
459
                        return ERR_PTR(-EAGAIN);
460
                entry->eof = 1;
461
                return ERR_PTR(-EBADCOOKIE);
462
        }
463
 
464
        entry->ino        = ntohl(*p++);
465
        entry->len        = ntohl(*p++);
466
        entry->name       = (const char *) p;
467
        p                += XDR_QUADLEN(entry->len);
468
        entry->prev_cookie        = entry->cookie;
469
        entry->cookie     = ntohl(*p++);
470
        entry->eof        = !p[0] && p[1];
471
 
472
        return p;
473
}
474
 
475
/*
476
 * NFS XDR decode functions
477
 */
478
/*
479
 * Decode void reply
480
 */
481
static int
482
nfs_xdr_dec_void(struct rpc_rqst *req, u32 *p, void *dummy)
483
{
484
        return 0;
485
}
486
 
487
/*
488
 * Decode simple status reply
489
 */
490
static int
491
nfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy)
492
{
493
        int     status;
494
 
495
        if ((status = ntohl(*p++)) != 0)
496
                status = -nfs_stat_to_errno(status);
497
        return status;
498
}
499
 
500
/*
501
 * Decode attrstat reply
502
 * GETATTR, SETATTR, WRITE
503
 */
504
static int
505
nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
506
{
507
        int     status;
508
 
509
        if ((status = ntohl(*p++)))
510
                return -nfs_stat_to_errno(status);
511
        xdr_decode_fattr(p, fattr);
512
        return 0;
513
}
514
 
515
/*
516
 * Decode diropres reply
517
 * LOOKUP, CREATE, MKDIR
518
 */
519
static int
520
nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
521
{
522
        int     status;
523
 
524
        if ((status = ntohl(*p++)))
525
                return -nfs_stat_to_errno(status);
526
        p = xdr_decode_fhandle(p, res->fh);
527
        xdr_decode_fattr(p, res->fattr);
528
        return 0;
529
}
530
 
531
/*
532
 * Encode READLINK args
533
 */
534
static int
535
nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args)
536
{
537
        struct rpc_auth *auth = req->rq_task->tk_auth;
538
        unsigned int replen;
539
        u32 count = args->count - 4;
540
 
541
        p = xdr_encode_fhandle(p, args->fh);
542
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
543
 
544
        /* Inline the page array */
545
        replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
546
        xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
547
        return 0;
548
}
549
 
550
/*
551
 * Decode READLINK reply
552
 */
553
static int
554
nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, void *dummy)
555
{
556
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
557
        struct iovec *iov = rcvbuf->head;
558
        unsigned int hdrlen;
559
        u32     *strlen, len;
560
        char    *string;
561
        int     status;
562
 
563
        if ((status = ntohl(*p++)))
564
                return -nfs_stat_to_errno(status);
565
        hdrlen = (u8 *) p - (u8 *) iov->iov_base;
566
        if (iov->iov_len > hdrlen) {
567
                dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
568
                xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
569
        }
570
 
571
        strlen = (u32*)kmap(rcvbuf->pages[0]);
572
        /* Convert length of symlink */
573
        len = ntohl(*strlen);
574
        if (len > rcvbuf->page_len)
575
                len = rcvbuf->page_len;
576
        *strlen = len;
577
        /* NULL terminate the string we got */
578
        string = (char *)(strlen + 1);
579
        string[len] = 0;
580
        kunmap(rcvbuf->pages[0]);
581
        return 0;
582
}
583
 
584
/*
585
 * Decode WRITE reply
586
 */
587
static int
588
nfs_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
589
{
590
        res->verf->committed = NFS_FILE_SYNC;
591
        return nfs_xdr_attrstat(req, p, res->fattr);
592
}
593
 
594
/*
595
 * Decode STATFS reply
596
 */
597
static int
598
nfs_xdr_statfsres(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res)
599
{
600
        int     status;
601
        u32     xfer_size;
602
 
603
        if ((status = ntohl(*p++)))
604
                return -nfs_stat_to_errno(status);
605
 
606
        /* For NFSv2, we more or less have to guess the preferred
607
         * read/write/readdir sizes from the single 'transfer size'
608
         * value.
609
         */
610
        xfer_size = ntohl(*p++);        /* tsize */
611
        res->rtmax  = 8 * 1024;
612
        res->rtpref = xfer_size;
613
        res->rtmult = xfer_size;
614
        res->wtmax  = 8 * 1024;
615
        res->wtpref = xfer_size;
616
        res->wtmult = xfer_size;
617
        res->dtpref = PAGE_CACHE_SIZE;
618
        res->maxfilesize = 0x7FFFFFFF;  /* just a guess */
619
        res->bsize  = ntohl(*p++);
620
 
621
        res->tbytes = ntohl(*p++) * res->bsize;
622
        res->fbytes = ntohl(*p++) * res->bsize;
623
        res->abytes = ntohl(*p++) * res->bsize;
624
        res->tfiles = 0;
625
        res->ffiles = 0;
626
        res->afiles = 0;
627
        res->namelen = 0;
628
 
629
        return 0;
630
}
631
 
632
/*
633
 * We need to translate between nfs status return values and
634
 * the local errno values which may not be the same.
635
 */
636
static struct {
637
        int stat;
638
        int errno;
639
} nfs_errtbl[] = {
640
        { NFS_OK,               0                },
641
        { NFSERR_PERM,          EPERM           },
642
        { NFSERR_NOENT,         ENOENT          },
643
        { NFSERR_IO,            errno_NFSERR_IO },
644
        { NFSERR_NXIO,          ENXIO           },
645
/*      { NFSERR_EAGAIN,        EAGAIN          }, */
646
        { NFSERR_ACCES,         EACCES          },
647
        { NFSERR_EXIST,         EEXIST          },
648
        { NFSERR_XDEV,          EXDEV           },
649
        { NFSERR_NODEV,         ENODEV          },
650
        { NFSERR_NOTDIR,        ENOTDIR         },
651
        { NFSERR_ISDIR,         EISDIR          },
652
        { NFSERR_INVAL,         EINVAL          },
653
        { NFSERR_FBIG,          EFBIG           },
654
        { NFSERR_NOSPC,         ENOSPC          },
655
        { NFSERR_ROFS,          EROFS           },
656
        { NFSERR_MLINK,         EMLINK          },
657
        { NFSERR_NAMETOOLONG,   ENAMETOOLONG    },
658
        { NFSERR_NOTEMPTY,      ENOTEMPTY       },
659
        { NFSERR_DQUOT,         EDQUOT          },
660
        { NFSERR_STALE,         ESTALE          },
661
        { NFSERR_REMOTE,        EREMOTE         },
662
#ifdef EWFLUSH
663
        { NFSERR_WFLUSH,        EWFLUSH         },
664
#endif
665
        { NFSERR_BADHANDLE,     EBADHANDLE      },
666
        { NFSERR_NOT_SYNC,      ENOTSYNC        },
667
        { NFSERR_BAD_COOKIE,    EBADCOOKIE      },
668
        { NFSERR_NOTSUPP,       ENOTSUPP        },
669
        { NFSERR_TOOSMALL,      ETOOSMALL       },
670
        { NFSERR_SERVERFAULT,   ESERVERFAULT    },
671
        { NFSERR_BADTYPE,       EBADTYPE        },
672
        { NFSERR_JUKEBOX,       EJUKEBOX        },
673
        { -1,                   EIO             }
674
};
675
 
676
/*
677
 * Convert an NFS error code to a local one.
678
 * This one is used jointly by NFSv2 and NFSv3.
679
 */
680
int
681
nfs_stat_to_errno(int stat)
682
{
683
        int i;
684
 
685
        for (i = 0; nfs_errtbl[i].stat != -1; i++) {
686
                if (nfs_errtbl[i].stat == stat)
687
                        return nfs_errtbl[i].errno;
688
        }
689
        printk(KERN_ERR "nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
690
        return nfs_errtbl[i].errno;
691
}
692
 
693
#ifndef MAX
694
# define MAX(a, b)      (((a) > (b))? (a) : (b))
695
#endif
696
 
697
#define PROC(proc, argtype, restype, timer)                             \
698
    { .p_procname =  "nfs_" #proc,                                      \
699
      .p_encode   =  (kxdrproc_t) nfs_xdr_##argtype,                    \
700
      .p_decode   =  (kxdrproc_t) nfs_xdr_##restype,                    \
701
      .p_bufsiz   =  MAX(NFS_##argtype##_sz,NFS_##restype##_sz) << 2,   \
702
      .p_timer    =  timer                                              \
703
    }
704
static struct rpc_procinfo      nfs_procedures[18] = {
705
    PROC(null,          enc_void,       dec_void, 0),
706
    PROC(getattr,       fhandle,        attrstat, 1),
707
    PROC(setattr,       sattrargs,      attrstat, 0),
708
    PROC(root,          enc_void,       dec_void, 0),
709
    PROC(lookup,        diropargs,      diropres, 2),
710
    PROC(readlink,      readlinkargs,   readlinkres, 3),
711
    PROC(read,          readargs,       readres, 3),
712
    PROC(writecache,    enc_void,       dec_void, 0),
713
    PROC(write,         writeargs,      writeres, 4),
714
    PROC(create,        createargs,     diropres, 0),
715
    PROC(remove,        diropargs,      stat, 0),
716
    PROC(rename,        renameargs,     stat, 0),
717
    PROC(link,          linkargs,       stat, 0),
718
    PROC(symlink,       symlinkargs,    stat, 0),
719
    PROC(mkdir,         createargs,     diropres, 0),
720
    PROC(rmdir,         diropargs,      stat, 0),
721
    PROC(readdir,       readdirargs,    readdirres, 3),
722
    PROC(statfs,        fhandle,        statfsres, 0),
723
};
724
 
725
struct rpc_version              nfs_version2 = {
726
        2,
727
        sizeof(nfs_procedures)/sizeof(nfs_procedures[0]),
728
        nfs_procedures
729
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.