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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [nfsd/] [nfsproc.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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