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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [nfsd/] [nfsproc.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * nfsproc2.c   Process version 2 NFS requests.
3
 * linux/fs/nfsd/nfs2proc.c
4
 *
5
 * Process version 2 NFS requests.
6
 *
7
 * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
8
 */
9
 
10
#include <linux/linkage.h>
11
#include <linux/sched.h>
12
#include <linux/errno.h>
13
#include <linux/locks.h>
14
#include <linux/fs.h>
15
#include <linux/stat.h>
16
#include <linux/fcntl.h>
17
#include <linux/net.h>
18
#include <linux/in.h>
19
#include <linux/version.h>
20
#include <linux/unistd.h>
21
#include <linux/slab.h>
22
 
23
#include <linux/sunrpc/svc.h>
24
#include <linux/nfsd/nfsd.h>
25
#include <linux/nfsd/cache.h>
26
#include <linux/nfsd/xdr.h>
27
 
28
typedef struct svc_rqst svc_rqst;
29
typedef struct svc_buf  svc_buf;
30
 
31
#define NFSDDBG_FACILITY                NFSDDBG_PROC
32
 
33
 
34
static void
35
svcbuf_reserve(struct svc_buf *buf, u32 **ptr, int *len, int nr)
36
{
37
        *ptr = buf->buf + nr;
38
        *len = buf->buflen - buf->len - nr;
39
}
40
 
41
static int
42
nfsd_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
43
{
44
        return nfs_ok;
45
}
46
 
47
/*
48
 * Get a file's attributes
49
 * N.B. After this call resp->fh needs an fh_put
50
 */
51
static int
52
nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
53
                                          struct nfsd_attrstat *resp)
54
{
55
        dprintk("nfsd: GETATTR  %s\n", SVCFH_fmt(&argp->fh));
56
 
57
        fh_copy(&resp->fh, &argp->fh);
58
        return fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
59
}
60
 
61
/*
62
 * Set a file's attributes
63
 * N.B. After this call resp->fh needs an fh_put
64
 */
65
static int
66
nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
67
                                          struct nfsd_attrstat  *resp)
68
{
69
        dprintk("nfsd: SETATTR  %s, valid=%x, size=%ld\n",
70
                SVCFH_fmt(&argp->fh),
71
                argp->attrs.ia_valid, (long) argp->attrs.ia_size);
72
 
73
        fh_copy(&resp->fh, &argp->fh);
74
        return nfsd_setattr(rqstp, &resp->fh, &argp->attrs,0, (time_t)0);
75
}
76
 
77
/*
78
 * Look up a path name component
79
 * Note: the dentry in the resp->fh may be negative if the file
80
 * doesn't exist yet.
81
 * N.B. After this call resp->fh needs an fh_put
82
 */
83
static int
84
nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
85
                                         struct nfsd_diropres  *resp)
86
{
87
        int     nfserr;
88
 
89
        dprintk("nfsd: LOOKUP   %s %.*s\n",
90
                SVCFH_fmt(&argp->fh), argp->len, argp->name);
91
 
92
        fh_init(&resp->fh, NFS_FHSIZE);
93
        nfserr = nfsd_lookup(rqstp, &argp->fh, argp->name, argp->len,
94
                                 &resp->fh);
95
 
96
        fh_put(&argp->fh);
97
        return nfserr;
98
}
99
 
100
/*
101
 * Read a symlink.
102
 */
103
static int
104
nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_fhandle     *argp,
105
                                           struct nfsd_readlinkres *resp)
106
{
107
        u32             *path;
108
        int             dummy, nfserr;
109
 
110
        dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh));
111
 
112
        /* Reserve room for status and path length */
113
        svcbuf_reserve(&rqstp->rq_resbuf, &path, &dummy, 2);
114
 
115
        /* Read the symlink. */
116
        resp->len = NFS_MAXPATHLEN;
117
        nfserr = nfsd_readlink(rqstp, &argp->fh, (char *) path, &resp->len);
118
 
119
        fh_put(&argp->fh);
120
        return nfserr;
121
}
122
 
123
/*
124
 * Read a portion of a file.
125
 * N.B. After this call resp->fh needs an fh_put
126
 */
127
static int
128
nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
129
                                       struct nfsd_readres  *resp)
130
{
131
        u32 *   buffer;
132
        int     nfserr, avail;
133
 
134
        dprintk("nfsd: READ    %s %d bytes at %d\n",
135
                SVCFH_fmt(&argp->fh),
136
                argp->count, argp->offset);
137
 
138
        /* Obtain buffer pointer for payload. 19 is 1 word for
139
         * status, 17 words for fattr, and 1 word for the byte count.
140
         */
141
        svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &avail, 19);
142
 
143
        if ((avail << 2) < argp->count) {
144
                printk(KERN_NOTICE
145
                        "oversized read request from %08x:%d (%d bytes)\n",
146
                                ntohl(rqstp->rq_addr.sin_addr.s_addr),
147
                                ntohs(rqstp->rq_addr.sin_port),
148
                                argp->count);
149
                argp->count = avail << 2;
150
        }
151
        svc_reserve(rqstp, (19<<2) + argp->count + 4);
152
 
153
        resp->count = argp->count;
154
        nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh),
155
                                  argp->offset,
156
                                  (char *) buffer,
157
                                  &resp->count);
158
 
159
        return nfserr;
160
}
161
 
162
/*
163
 * Write data to a file
164
 * N.B. After this call resp->fh needs an fh_put
165
 */
166
static int
167
nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
168
                                        struct nfsd_attrstat  *resp)
169
{
170
        int     nfserr;
171
        int     stable = 1;
172
 
173
        dprintk("nfsd: WRITE    %s %d bytes at %d\n",
174
                SVCFH_fmt(&argp->fh),
175
                argp->len, argp->offset);
176
 
177
        nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),
178
                                   argp->offset,
179
                                   argp->data,
180
                                   argp->len,
181
                                   &stable);
182
        return nfserr;
183
}
184
 
185
/*
186
 * CREATE processing is complicated. The keyword here is `overloaded.'
187
 * The parent directory is kept locked between the check for existence
188
 * and the actual create() call in compliance with VFS protocols.
189
 * N.B. After this call _both_ argp->fh and resp->fh need an fh_put
190
 */
191
static int
192
nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
193
                                         struct nfsd_diropres   *resp)
194
{
195
        svc_fh          *dirfhp = &argp->fh;
196
        svc_fh          *newfhp = &resp->fh;
197
        struct iattr    *attr = &argp->attrs;
198
        struct inode    *inode;
199
        struct dentry   *dchild;
200
        int             nfserr, type, mode;
201
        dev_t           rdev = NODEV;
202
 
203
        dprintk("nfsd: CREATE   %s %.*s\n",
204
                SVCFH_fmt(dirfhp), argp->len, argp->name);
205
 
206
        /* First verify the parent file handle */
207
        nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, MAY_EXEC);
208
        if (nfserr)
209
                goto done; /* must fh_put dirfhp even on error */
210
 
211
        /* Check for MAY_WRITE in nfsd_create if necessary */
212
 
213
        nfserr = nfserr_acces;
214
        if (!argp->len)
215
                goto done;
216
        nfserr = nfserr_exist;
217
        if (isdotent(argp->name, argp->len))
218
                goto done;
219
        fh_lock(dirfhp);
220
        dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);
221
        if (IS_ERR(dchild)) {
222
                nfserr = nfserrno(PTR_ERR(dchild));
223
                goto out_unlock;
224
        }
225
        fh_init(newfhp, NFS_FHSIZE);
226
        nfserr = fh_compose(newfhp, dirfhp->fh_export, dchild, dirfhp);
227
        if (!nfserr && !dchild->d_inode)
228
                nfserr = nfserr_noent;
229
        if (nfserr) {
230
                if (nfserr != nfserr_noent)
231
                        goto out_unlock;
232
                /*
233
                 * If the new file handle wasn't verified, we can't tell
234
                 * whether the file exists or not. Time to bail ...
235
                 */
236
                nfserr = nfserr_acces;
237
                if (!newfhp->fh_dentry) {
238
                        printk(KERN_WARNING
239
                                "nfsd_proc_create: file handle not verified\n");
240
                        goto out_unlock;
241
                }
242
        }
243
 
244
        inode = newfhp->fh_dentry->d_inode;
245
 
246
        /* Unfudge the mode bits */
247
        if (attr->ia_valid & ATTR_MODE) {
248
                type = attr->ia_mode & S_IFMT;
249
                mode = attr->ia_mode & ~S_IFMT;
250
                if (!type) {
251
                        /* no type, so if target exists, assume same as that,
252
                         * else assume a file */
253
                        if (inode) {
254
                                type = inode->i_mode & S_IFMT;
255
                                switch(type) {
256
                                case S_IFCHR:
257
                                case S_IFBLK:
258
                                        /* reserve rdev for later checking */
259
                                        attr->ia_size = inode->i_rdev;
260
                                        attr->ia_valid |= ATTR_SIZE;
261
 
262
                                        /* FALLTHROUGH */
263
                                case S_IFIFO:
264
                                        /* this is probably a permission check..
265
                                         * at least IRIX implements perm checking on
266
                                         *   echo thing > device-special-file-or-pipe
267
                                         * by doing a CREATE with type==0
268
                                         */
269
                                        nfserr = nfsd_permission(newfhp->fh_export,
270
                                                                 newfhp->fh_dentry,
271
                                                                 MAY_WRITE|_NFSD_IRIX_BOGOSITY);
272
                                        if (nfserr && nfserr != nfserr_rofs)
273
                                                goto out_unlock;
274
                                }
275
                        } else
276
                                type = S_IFREG;
277
                }
278
        } else if (inode) {
279
                type = inode->i_mode & S_IFMT;
280
                mode = inode->i_mode & ~S_IFMT;
281
        } else {
282
                type = S_IFREG;
283
                mode = 0;        /* ??? */
284
        }
285
 
286
        attr->ia_valid |= ATTR_MODE;
287
        attr->ia_mode = mode;
288
 
289
        /* Special treatment for non-regular files according to the
290
         * gospel of sun micro
291
         */
292
        if (type != S_IFREG) {
293
                int     is_borc = 0;
294
                u32     size = attr->ia_size;
295
 
296
                rdev = (dev_t) size;
297
                if (type != S_IFBLK && type != S_IFCHR) {
298
                        rdev = 0;
299
                } else if (type == S_IFCHR && !(attr->ia_valid & ATTR_SIZE)) {
300
                        /* If you think you've seen the worst, grok this. */
301
                        type = S_IFIFO;
302
                } else if (size != rdev) {
303
                        /* dev got truncated because of 16bit Linux dev_t */
304
                        nfserr = nfserr_inval;
305
                        goto out_unlock;
306
                } else {
307
                        /* Okay, char or block special */
308
                        is_borc = 1;
309
                }
310
 
311
                /* we've used the SIZE information, so discard it */
312
                attr->ia_valid &= ~ATTR_SIZE;
313
 
314
                /* Make sure the type and device matches */
315
                nfserr = nfserr_exist;
316
                if (inode && (type != (inode->i_mode & S_IFMT) ||
317
                    (is_borc && inode->i_rdev != rdev)))
318
                        goto out_unlock;
319
        }
320
 
321
        nfserr = 0;
322
        if (!inode) {
323
                /* File doesn't exist. Create it and set attrs */
324
                nfserr = nfsd_create(rqstp, dirfhp, argp->name, argp->len,
325
                                        attr, type, rdev, newfhp);
326
        } else if (type == S_IFREG) {
327
                dprintk("nfsd:   existing %s, valid=%x, size=%ld\n",
328
                        argp->name, attr->ia_valid, (long) attr->ia_size);
329
                /* File already exists. We ignore all attributes except
330
                 * size, so that creat() behaves exactly like
331
                 * open(..., O_CREAT|O_TRUNC|O_WRONLY).
332
                 */
333
                attr->ia_valid &= ATTR_SIZE;
334
                if (attr->ia_valid)
335
                        nfserr = nfsd_setattr(rqstp, newfhp, attr, 0, (time_t)0);
336
        }
337
 
338
out_unlock:
339
        /* We don't really need to unlock, as fh_put does it. */
340
        fh_unlock(dirfhp);
341
 
342
done:
343
        fh_put(dirfhp);
344
        return nfserr;
345
}
346
 
347
static int
348
nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
349
                                         void                  *resp)
350
{
351
        int     nfserr;
352
 
353
        dprintk("nfsd: REMOVE   %s %.*s\n", SVCFH_fmt(&argp->fh),
354
                argp->len, argp->name);
355
 
356
        /* Unlink. -SIFDIR means file must not be a directory */
357
        nfserr = nfsd_unlink(rqstp, &argp->fh, -S_IFDIR, argp->name, argp->len);
358
        fh_put(&argp->fh);
359
        return nfserr;
360
}
361
 
362
static int
363
nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp,
364
                                         void                   *resp)
365
{
366
        int     nfserr;
367
 
368
        dprintk("nfsd: RENAME   %s %.*s -> \n",
369
                SVCFH_fmt(&argp->ffh), argp->flen, argp->fname);
370
        dprintk("nfsd:        ->  %s %.*s\n",
371
                SVCFH_fmt(&argp->tfh), argp->tlen, argp->tname);
372
 
373
        nfserr = nfsd_rename(rqstp, &argp->ffh, argp->fname, argp->flen,
374
                                    &argp->tfh, argp->tname, argp->tlen);
375
        fh_put(&argp->ffh);
376
        fh_put(&argp->tfh);
377
        return nfserr;
378
}
379
 
380
static int
381
nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp,
382
                                void                        *resp)
383
{
384
        int     nfserr;
385
 
386
        dprintk("nfsd: LINK     %s ->\n",
387
                SVCFH_fmt(&argp->ffh));
388
        dprintk("nfsd:    %s %.*s\n",
389
                SVCFH_fmt(&argp->tfh),
390
                argp->tlen,
391
                argp->tname);
392
 
393
        nfserr = nfsd_link(rqstp, &argp->tfh, argp->tname, argp->tlen,
394
                                  &argp->ffh);
395
        fh_put(&argp->ffh);
396
        fh_put(&argp->tfh);
397
        return nfserr;
398
}
399
 
400
static int
401
nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp,
402
                                          void                    *resp)
403
{
404
        struct svc_fh   newfh;
405
        int             nfserr;
406
 
407
        dprintk("nfsd: SYMLINK  %s %.*s -> %.*s\n",
408
                SVCFH_fmt(&argp->ffh), argp->flen, argp->fname,
409
                argp->tlen, argp->tname);
410
 
411
        fh_init(&newfh, NFS_FHSIZE);
412
        /*
413
         * Create the link, look up new file and set attrs.
414
         */
415
        nfserr = nfsd_symlink(rqstp, &argp->ffh, argp->fname, argp->flen,
416
                                                 argp->tname, argp->tlen,
417
                                                 &newfh, &argp->attrs);
418
 
419
 
420
        fh_put(&argp->ffh);
421
        fh_put(&newfh);
422
        return nfserr;
423
}
424
 
425
/*
426
 * Make directory. This operation is not idempotent.
427
 * N.B. After this call resp->fh needs an fh_put
428
 */
429
static int
430
nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
431
                                        struct nfsd_diropres   *resp)
432
{
433
        int     nfserr;
434
 
435
        dprintk("nfsd: MKDIR    %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
436
 
437
        if (resp->fh.fh_dentry) {
438
                printk(KERN_WARNING
439
                        "nfsd_proc_mkdir: response already verified??\n");
440
        }
441
 
442
        argp->attrs.ia_valid &= ~ATTR_SIZE;
443
        fh_init(&resp->fh, NFS_FHSIZE);
444
        nfserr = nfsd_create(rqstp, &argp->fh, argp->name, argp->len,
445
                                    &argp->attrs, S_IFDIR, 0, &resp->fh);
446
        fh_put(&argp->fh);
447
        return nfserr;
448
}
449
 
450
/*
451
 * Remove a directory
452
 */
453
static int
454
nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
455
                                        void                  *resp)
456
{
457
        int     nfserr;
458
 
459
        dprintk("nfsd: RMDIR    %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
460
 
461
        nfserr = nfsd_unlink(rqstp, &argp->fh, S_IFDIR, argp->name, argp->len);
462
        fh_put(&argp->fh);
463
        return nfserr;
464
}
465
 
466
/*
467
 * Read a portion of a directory.
468
 */
469
static int
470
nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp,
471
                                          struct nfsd_readdirres  *resp)
472
{
473
        u32 *           buffer;
474
        int             nfserr, count;
475
 
476
        dprintk("nfsd: READDIR  %s %d bytes at %d\n",
477
                SVCFH_fmt(&argp->fh),
478
                argp->count, argp->cookie);
479
 
480
        /* Reserve buffer space for status */
481
        svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &count, 1);
482
 
483
        /* Shrink to the client read size */
484
        if (count > (argp->count >> 2))
485
                count = argp->count >> 2;
486
 
487
        /* Make sure we've room for the NULL ptr & eof flag */
488
        count -= 2;
489
        if (count < 0)
490
                count = 0;
491
 
492
        /* Read directory and encode entries on the fly */
493
        nfserr = nfsd_readdir(rqstp, &argp->fh, (loff_t) argp->cookie,
494
                              nfssvc_encode_entry,
495
                              buffer, &count, NULL);
496
        resp->count = count;
497
 
498
        fh_put(&argp->fh);
499
        return nfserr;
500
}
501
 
502
/*
503
 * Get file system info
504
 */
505
static int
506
nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle   *argp,
507
                                          struct nfsd_statfsres *resp)
508
{
509
        int     nfserr;
510
 
511
        dprintk("nfsd: STATFS   %s\n", SVCFH_fmt(&argp->fh));
512
 
513
        nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
514
        fh_put(&argp->fh);
515
        return nfserr;
516
}
517
 
518
/*
519
 * NFSv2 Server procedures.
520
 * Only the results of non-idempotent operations are cached.
521
 */
522
#define nfsd_proc_none          NULL
523
#define nfssvc_release_none     NULL
524
struct nfsd_void { int dummy; };
525
 
526
#define PROC(name, argt, rest, relt, cache, respsize)   \
527
 { (svc_procfunc) nfsd_proc_##name,             \
528
   (kxdrproc_t) nfssvc_decode_##argt,           \
529
   (kxdrproc_t) nfssvc_encode_##rest,           \
530
   (kxdrproc_t) nfssvc_release_##relt,          \
531
   sizeof(struct nfsd_##argt),                  \
532
   sizeof(struct nfsd_##rest),                  \
533
   0,                                            \
534
   cache,                                       \
535
   respsize,                                    \
536
 }
537
 
538
#define ST 1            /* status */
539
#define FH 8            /* filehandle */
540
#define AT 18           /* attributes */
541
 
542
struct svc_procedure            nfsd_procedures2[18] = {
543
  PROC(null,     void,          void,           none,           RC_NOCACHE, ST),
544
  PROC(getattr,  fhandle,       attrstat,       fhandle,        RC_NOCACHE, ST+AT),
545
  PROC(setattr,  sattrargs,     attrstat,       fhandle,        RC_REPLBUFF, ST+AT),
546
  PROC(none,     void,          void,           none,           RC_NOCACHE, ST),
547
  PROC(lookup,   diropargs,     diropres,       fhandle,        RC_NOCACHE, ST+FH+AT),
548
  PROC(readlink, fhandle,       readlinkres,    none,           RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
549
  PROC(read,     readargs,      readres,        fhandle,        RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE),
550
  PROC(none,     void,          void,           none,           RC_NOCACHE, ST),
551
  PROC(write,    writeargs,     attrstat,       fhandle,        RC_REPLBUFF, ST+AT),
552
  PROC(create,   createargs,    diropres,       fhandle,        RC_REPLBUFF, ST+FH+AT),
553
  PROC(remove,   diropargs,     void,           none,           RC_REPLSTAT, ST),
554
  PROC(rename,   renameargs,    void,           none,           RC_REPLSTAT, ST),
555
  PROC(link,     linkargs,      void,           none,           RC_REPLSTAT, ST),
556
  PROC(symlink,  symlinkargs,   void,           none,           RC_REPLSTAT, ST),
557
  PROC(mkdir,    createargs,    diropres,       fhandle,        RC_REPLBUFF, ST+FH+AT),
558
  PROC(rmdir,    diropargs,     void,           none,           RC_REPLSTAT, ST),
559
  PROC(readdir,  readdirargs,   readdirres,     none,           RC_REPLBUFF, 0),
560
  PROC(statfs,   fhandle,       statfsres,      none,           RC_NOCACHE, ST+5),
561
};
562
 
563
 
564
/*
565
 * Map errnos to NFS errnos.
566
 */
567
int
568
nfserrno (int errno)
569
{
570
        static struct {
571
                int     nfserr;
572
                int     syserr;
573
        } nfs_errtbl[] = {
574
                { nfs_ok, 0 },
575
                { nfserr_perm, -EPERM },
576
                { nfserr_noent, -ENOENT },
577
                { nfserr_io, -EIO },
578
                { nfserr_nxio, -ENXIO },
579
                { nfserr_acces, -EACCES },
580
                { nfserr_exist, -EEXIST },
581
                { nfserr_xdev, -EXDEV },
582
                { nfserr_mlink, -EMLINK },
583
                { nfserr_nodev, -ENODEV },
584
                { nfserr_notdir, -ENOTDIR },
585
                { nfserr_isdir, -EISDIR },
586
                { nfserr_inval, -EINVAL },
587
                { nfserr_fbig, -EFBIG },
588
                { nfserr_nospc, -ENOSPC },
589
                { nfserr_rofs, -EROFS },
590
                { nfserr_mlink, -EMLINK },
591
                { nfserr_nametoolong, -ENAMETOOLONG },
592
                { nfserr_notempty, -ENOTEMPTY },
593
#ifdef EDQUOT
594
                { nfserr_dquot, -EDQUOT },
595
#endif
596
                { nfserr_stale, -ESTALE },
597
                { nfserr_dropit, -ENOMEM },
598
                { -1, -EIO }
599
        };
600
        int     i;
601
 
602
        for (i = 0; nfs_errtbl[i].nfserr != -1; i++) {
603
                if (nfs_errtbl[i].syserr == errno)
604
                        return nfs_errtbl[i].nfserr;
605
        }
606
        printk (KERN_INFO "nfsd: non-standard errno: %d\n", errno);
607
        return nfserr_io;
608
}
609
 

powered by: WebSVN 2.1.0

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