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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [nfsd/] [vfs.c] - Blame information for rev 79

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

Line No. Rev Author Line
1 62 marcus.erl
#define MSNFS   /* HACK HACK */
2
/*
3
 * linux/fs/nfsd/vfs.c
4
 *
5
 * File operations used by nfsd. Some of these have been ripped from
6
 * other parts of the kernel because they weren't exported, others
7
 * are partial duplicates with added or changed functionality.
8
 *
9
 * Note that several functions dget() the dentry upon which they want
10
 * to act, most notably those that create directory entries. Response
11
 * dentry's are dput()'d if necessary in the release callback.
12
 * So if you notice code paths that apparently fail to dput() the
13
 * dentry, don't worry--they have been taken care of.
14
 *
15
 * Copyright (C) 1995-1999 Olaf Kirch <okir@monad.swb.de>
16
 * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp>
17
 */
18
 
19
#include <linux/string.h>
20
#include <linux/time.h>
21
#include <linux/errno.h>
22
#include <linux/fs.h>
23
#include <linux/file.h>
24
#include <linux/mount.h>
25
#include <linux/major.h>
26
#include <linux/splice.h>
27
#include <linux/proc_fs.h>
28
#include <linux/stat.h>
29
#include <linux/fcntl.h>
30
#include <linux/net.h>
31
#include <linux/unistd.h>
32
#include <linux/slab.h>
33
#include <linux/pagemap.h>
34
#include <linux/in.h>
35
#include <linux/module.h>
36
#include <linux/namei.h>
37
#include <linux/vfs.h>
38
#include <linux/delay.h>
39
#include <linux/sunrpc/svc.h>
40
#include <linux/nfsd/nfsd.h>
41
#ifdef CONFIG_NFSD_V3
42
#include <linux/nfs3.h>
43
#include <linux/nfsd/xdr3.h>
44
#endif /* CONFIG_NFSD_V3 */
45
#include <linux/nfsd/nfsfh.h>
46
#include <linux/quotaops.h>
47
#include <linux/fsnotify.h>
48
#include <linux/posix_acl.h>
49
#include <linux/posix_acl_xattr.h>
50
#include <linux/xattr.h>
51
#ifdef CONFIG_NFSD_V4
52
#include <linux/nfs4.h>
53
#include <linux/nfs4_acl.h>
54
#include <linux/nfsd_idmap.h>
55
#include <linux/security.h>
56
#endif /* CONFIG_NFSD_V4 */
57
#include <linux/jhash.h>
58
 
59
#include <asm/uaccess.h>
60
 
61
#define NFSDDBG_FACILITY                NFSDDBG_FILEOP
62
 
63
 
64
/*
65
 * This is a cache of readahead params that help us choose the proper
66
 * readahead strategy. Initially, we set all readahead parameters to 0
67
 * and let the VFS handle things.
68
 * If you increase the number of cached files very much, you'll need to
69
 * add a hash table here.
70
 */
71
struct raparms {
72
        struct raparms          *p_next;
73
        unsigned int            p_count;
74
        ino_t                   p_ino;
75
        dev_t                   p_dev;
76
        int                     p_set;
77
        struct file_ra_state    p_ra;
78
        unsigned int            p_hindex;
79
};
80
 
81
struct raparm_hbucket {
82
        struct raparms          *pb_head;
83
        spinlock_t              pb_lock;
84
} ____cacheline_aligned_in_smp;
85
 
86
static struct raparms *         raparml;
87
#define RAPARM_HASH_BITS        4
88
#define RAPARM_HASH_SIZE        (1<<RAPARM_HASH_BITS)
89
#define RAPARM_HASH_MASK        (RAPARM_HASH_SIZE-1)
90
static struct raparm_hbucket    raparm_hash[RAPARM_HASH_SIZE];
91
 
92
/*
93
 * Called from nfsd_lookup and encode_dirent. Check if we have crossed
94
 * a mount point.
95
 * Returns -EAGAIN or -ETIMEDOUT leaving *dpp and *expp unchanged,
96
 *  or nfs_ok having possibly changed *dpp and *expp
97
 */
98
int
99
nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
100
                        struct svc_export **expp)
101
{
102
        struct svc_export *exp = *expp, *exp2 = NULL;
103
        struct dentry *dentry = *dpp;
104
        struct vfsmount *mnt = mntget(exp->ex_mnt);
105
        struct dentry *mounts = dget(dentry);
106
        int err = 0;
107
 
108
        while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts));
109
 
110
        exp2 = rqst_exp_get_by_name(rqstp, mnt, mounts);
111
        if (IS_ERR(exp2)) {
112
                if (PTR_ERR(exp2) != -ENOENT)
113
                        err = PTR_ERR(exp2);
114
                dput(mounts);
115
                mntput(mnt);
116
                goto out;
117
        }
118
        if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) {
119
                /* successfully crossed mount point */
120
                exp_put(exp);
121
                *expp = exp2;
122
                dput(dentry);
123
                *dpp = mounts;
124
        } else {
125
                exp_put(exp2);
126
                dput(mounts);
127
        }
128
        mntput(mnt);
129
out:
130
        return err;
131
}
132
 
133
__be32
134
nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
135
                   const char *name, int len,
136
                   struct svc_export **exp_ret, struct dentry **dentry_ret)
137
{
138
        struct svc_export       *exp;
139
        struct dentry           *dparent;
140
        struct dentry           *dentry;
141
        __be32                  err;
142
        int                     host_err;
143
 
144
        dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name);
145
 
146
        /* Obtain dentry and export. */
147
        err = fh_verify(rqstp, fhp, S_IFDIR, MAY_EXEC);
148
        if (err)
149
                return err;
150
 
151
        dparent = fhp->fh_dentry;
152
        exp  = fhp->fh_export;
153
        exp_get(exp);
154
 
155
        /* Lookup the name, but don't follow links */
156
        if (isdotent(name, len)) {
157
                if (len==1)
158
                        dentry = dget(dparent);
159
                else if (dparent != exp->ex_dentry) {
160
                        dentry = dget_parent(dparent);
161
                } else  if (!EX_NOHIDE(exp))
162
                        dentry = dget(dparent); /* .. == . just like at / */
163
                else {
164
                        /* checking mountpoint crossing is very different when stepping up */
165
                        struct svc_export *exp2 = NULL;
166
                        struct dentry *dp;
167
                        struct vfsmount *mnt = mntget(exp->ex_mnt);
168
                        dentry = dget(dparent);
169
                        while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry))
170
                                ;
171
                        dp = dget_parent(dentry);
172
                        dput(dentry);
173
                        dentry = dp;
174
 
175
                        exp2 = rqst_exp_parent(rqstp, mnt, dentry);
176
                        if (PTR_ERR(exp2) == -ENOENT) {
177
                                dput(dentry);
178
                                dentry = dget(dparent);
179
                        } else if (IS_ERR(exp2)) {
180
                                host_err = PTR_ERR(exp2);
181
                                dput(dentry);
182
                                mntput(mnt);
183
                                goto out_nfserr;
184
                        } else {
185
                                exp_put(exp);
186
                                exp = exp2;
187
                        }
188
                        mntput(mnt);
189
                }
190
        } else {
191
                fh_lock(fhp);
192
                dentry = lookup_one_len(name, dparent, len);
193
                host_err = PTR_ERR(dentry);
194
                if (IS_ERR(dentry))
195
                        goto out_nfserr;
196
                /*
197
                 * check if we have crossed a mount point ...
198
                 */
199
                if (d_mountpoint(dentry)) {
200
                        if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
201
                                dput(dentry);
202
                                goto out_nfserr;
203
                        }
204
                }
205
        }
206
        *dentry_ret = dentry;
207
        *exp_ret = exp;
208
        return 0;
209
 
210
out_nfserr:
211
        exp_put(exp);
212
        return nfserrno(host_err);
213
}
214
 
215
/*
216
 * Look up one component of a pathname.
217
 * N.B. After this call _both_ fhp and resfh need an fh_put
218
 *
219
 * If the lookup would cross a mountpoint, and the mounted filesystem
220
 * is exported to the client with NFSEXP_NOHIDE, then the lookup is
221
 * accepted as it stands and the mounted directory is
222
 * returned. Otherwise the covered directory is returned.
223
 * NOTE: this mountpoint crossing is not supported properly by all
224
 *   clients and is explicitly disallowed for NFSv3
225
 *      NeilBrown <neilb@cse.unsw.edu.au>
226
 */
227
__be32
228
nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
229
                                        int len, struct svc_fh *resfh)
230
{
231
        struct svc_export       *exp;
232
        struct dentry           *dentry;
233
        __be32 err;
234
 
235
        err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry);
236
        if (err)
237
                return err;
238
        err = check_nfsd_access(exp, rqstp);
239
        if (err)
240
                goto out;
241
        /*
242
         * Note: we compose the file handle now, but as the
243
         * dentry may be negative, it may need to be updated.
244
         */
245
        err = fh_compose(resfh, exp, dentry, fhp);
246
        if (!err && !dentry->d_inode)
247
                err = nfserr_noent;
248
out:
249
        dput(dentry);
250
        exp_put(exp);
251
        return err;
252
}
253
 
254
 
255
/*
256
 * Set various file attributes.
257
 * N.B. After this call fhp needs an fh_put
258
 */
259
__be32
260
nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
261
             int check_guard, time_t guardtime)
262
{
263
        struct dentry   *dentry;
264
        struct inode    *inode;
265
        int             accmode = MAY_SATTR;
266
        int             ftype = 0;
267
        int             imode;
268
        __be32          err;
269
        int             host_err;
270
        int             size_change = 0;
271
 
272
        if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
273
                accmode |= MAY_WRITE|MAY_OWNER_OVERRIDE;
274
        if (iap->ia_valid & ATTR_SIZE)
275
                ftype = S_IFREG;
276
 
277
        /* Get inode */
278
        err = fh_verify(rqstp, fhp, ftype, accmode);
279
        if (err)
280
                goto out;
281
 
282
        dentry = fhp->fh_dentry;
283
        inode = dentry->d_inode;
284
 
285
        /* Ignore any mode updates on symlinks */
286
        if (S_ISLNK(inode->i_mode))
287
                iap->ia_valid &= ~ATTR_MODE;
288
 
289
        if (!iap->ia_valid)
290
                goto out;
291
 
292
        /*
293
         * NFSv2 does not differentiate between "set-[ac]time-to-now"
294
         * which only requires access, and "set-[ac]time-to-X" which
295
         * requires ownership.
296
         * So if it looks like it might be "set both to the same time which
297
         * is close to now", and if inode_change_ok fails, then we
298
         * convert to "set to now" instead of "set to explicit time"
299
         *
300
         * We only call inode_change_ok as the last test as technically
301
         * it is not an interface that we should be using.  It is only
302
         * valid if the filesystem does not define it's own i_op->setattr.
303
         */
304
#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
305
#define MAX_TOUCH_TIME_ERROR (30*60)
306
        if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET &&
307
            iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) {
308
                /*
309
                 * Looks probable.
310
                 *
311
                 * Now just make sure time is in the right ballpark.
312
                 * Solaris, at least, doesn't seem to care what the time
313
                 * request is.  We require it be within 30 minutes of now.
314
                 */
315
                time_t delta = iap->ia_atime.tv_sec - get_seconds();
316
                if (delta < 0)
317
                        delta = -delta;
318
                if (delta < MAX_TOUCH_TIME_ERROR &&
319
                    inode_change_ok(inode, iap) != 0) {
320
                        /*
321
                         * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
322
                         * This will cause notify_change to set these times
323
                         * to "now"
324
                         */
325
                        iap->ia_valid &= ~BOTH_TIME_SET;
326
                }
327
        }
328
 
329
        /*
330
         * The size case is special.
331
         * It changes the file as well as the attributes.
332
         */
333
        if (iap->ia_valid & ATTR_SIZE) {
334
                if (iap->ia_size < inode->i_size) {
335
                        err = nfsd_permission(rqstp, fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE);
336
                        if (err)
337
                                goto out;
338
                }
339
 
340
                /*
341
                 * If we are changing the size of the file, then
342
                 * we need to break all leases.
343
                 */
344
                host_err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
345
                if (host_err == -EWOULDBLOCK)
346
                        host_err = -ETIMEDOUT;
347
                if (host_err) /* ENOMEM or EWOULDBLOCK */
348
                        goto out_nfserr;
349
 
350
                host_err = get_write_access(inode);
351
                if (host_err)
352
                        goto out_nfserr;
353
 
354
                size_change = 1;
355
                host_err = locks_verify_truncate(inode, NULL, iap->ia_size);
356
                if (host_err) {
357
                        put_write_access(inode);
358
                        goto out_nfserr;
359
                }
360
                DQUOT_INIT(inode);
361
        }
362
 
363
        imode = inode->i_mode;
364
        if (iap->ia_valid & ATTR_MODE) {
365
                iap->ia_mode &= S_IALLUGO;
366
                imode = iap->ia_mode |= (imode & ~S_IALLUGO);
367
                /* if changing uid/gid revoke setuid/setgid in mode */
368
                if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) {
369
                        iap->ia_valid |= ATTR_KILL_PRIV;
370
                        iap->ia_mode &= ~S_ISUID;
371
                }
372
                if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
373
                        iap->ia_mode &= ~S_ISGID;
374
        } else {
375
                /*
376
                 * Revoke setuid/setgid bit on chown/chgrp
377
                 */
378
                if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
379
                        iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV;
380
                if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
381
                        iap->ia_valid |= ATTR_KILL_SGID;
382
        }
383
 
384
        /* Change the attributes. */
385
 
386
        iap->ia_valid |= ATTR_CTIME;
387
 
388
        err = nfserr_notsync;
389
        if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
390
                fh_lock(fhp);
391
                host_err = notify_change(dentry, iap);
392
                err = nfserrno(host_err);
393
                fh_unlock(fhp);
394
        }
395
        if (size_change)
396
                put_write_access(inode);
397
        if (!err)
398
                if (EX_ISSYNC(fhp->fh_export))
399
                        write_inode_now(inode, 1);
400
out:
401
        return err;
402
 
403
out_nfserr:
404
        err = nfserrno(host_err);
405
        goto out;
406
}
407
 
408
#if defined(CONFIG_NFSD_V2_ACL) || \
409
    defined(CONFIG_NFSD_V3_ACL) || \
410
    defined(CONFIG_NFSD_V4)
411
static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
412
{
413
        ssize_t buflen;
414
 
415
        buflen = vfs_getxattr(dentry, key, NULL, 0);
416
        if (buflen <= 0)
417
                return buflen;
418
 
419
        *buf = kmalloc(buflen, GFP_KERNEL);
420
        if (!*buf)
421
                return -ENOMEM;
422
 
423
        return vfs_getxattr(dentry, key, *buf, buflen);
424
}
425
#endif
426
 
427
#if defined(CONFIG_NFSD_V4)
428
static int
429
set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
430
{
431
        int len;
432
        size_t buflen;
433
        char *buf = NULL;
434
        int error = 0;
435
 
436
        buflen = posix_acl_xattr_size(pacl->a_count);
437
        buf = kmalloc(buflen, GFP_KERNEL);
438
        error = -ENOMEM;
439
        if (buf == NULL)
440
                goto out;
441
 
442
        len = posix_acl_to_xattr(pacl, buf, buflen);
443
        if (len < 0) {
444
                error = len;
445
                goto out;
446
        }
447
 
448
        error = vfs_setxattr(dentry, key, buf, len, 0);
449
out:
450
        kfree(buf);
451
        return error;
452
}
453
 
454
__be32
455
nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
456
    struct nfs4_acl *acl)
457
{
458
        __be32 error;
459
        int host_error;
460
        struct dentry *dentry;
461
        struct inode *inode;
462
        struct posix_acl *pacl = NULL, *dpacl = NULL;
463
        unsigned int flags = 0;
464
 
465
        /* Get inode */
466
        error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, MAY_SATTR);
467
        if (error)
468
                return error;
469
 
470
        dentry = fhp->fh_dentry;
471
        inode = dentry->d_inode;
472
        if (S_ISDIR(inode->i_mode))
473
                flags = NFS4_ACL_DIR;
474
 
475
        host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
476
        if (host_error == -EINVAL) {
477
                return nfserr_attrnotsupp;
478
        } else if (host_error < 0)
479
                goto out_nfserr;
480
 
481
        host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
482
        if (host_error < 0)
483
                goto out_release;
484
 
485
        if (S_ISDIR(inode->i_mode))
486
                host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
487
 
488
out_release:
489
        posix_acl_release(pacl);
490
        posix_acl_release(dpacl);
491
out_nfserr:
492
        if (host_error == -EOPNOTSUPP)
493
                return nfserr_attrnotsupp;
494
        else
495
                return nfserrno(host_error);
496
}
497
 
498
static struct posix_acl *
499
_get_posix_acl(struct dentry *dentry, char *key)
500
{
501
        void *buf = NULL;
502
        struct posix_acl *pacl = NULL;
503
        int buflen;
504
 
505
        buflen = nfsd_getxattr(dentry, key, &buf);
506
        if (!buflen)
507
                buflen = -ENODATA;
508
        if (buflen <= 0)
509
                return ERR_PTR(buflen);
510
 
511
        pacl = posix_acl_from_xattr(buf, buflen);
512
        kfree(buf);
513
        return pacl;
514
}
515
 
516
int
517
nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl)
518
{
519
        struct inode *inode = dentry->d_inode;
520
        int error = 0;
521
        struct posix_acl *pacl = NULL, *dpacl = NULL;
522
        unsigned int flags = 0;
523
 
524
        pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS);
525
        if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA)
526
                pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
527
        if (IS_ERR(pacl)) {
528
                error = PTR_ERR(pacl);
529
                pacl = NULL;
530
                goto out;
531
        }
532
 
533
        if (S_ISDIR(inode->i_mode)) {
534
                dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT);
535
                if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA)
536
                        dpacl = NULL;
537
                else if (IS_ERR(dpacl)) {
538
                        error = PTR_ERR(dpacl);
539
                        dpacl = NULL;
540
                        goto out;
541
                }
542
                flags = NFS4_ACL_DIR;
543
        }
544
 
545
        *acl = nfs4_acl_posix_to_nfsv4(pacl, dpacl, flags);
546
        if (IS_ERR(*acl)) {
547
                error = PTR_ERR(*acl);
548
                *acl = NULL;
549
        }
550
 out:
551
        posix_acl_release(pacl);
552
        posix_acl_release(dpacl);
553
        return error;
554
}
555
 
556
#endif /* defined(CONFIG_NFS_V4) */
557
 
558
#ifdef CONFIG_NFSD_V3
559
/*
560
 * Check server access rights to a file system object
561
 */
562
struct accessmap {
563
        u32             access;
564
        int             how;
565
};
566
static struct accessmap nfs3_regaccess[] = {
567
    {   NFS3_ACCESS_READ,       MAY_READ                        },
568
    {   NFS3_ACCESS_EXECUTE,    MAY_EXEC                        },
569
    {   NFS3_ACCESS_MODIFY,     MAY_WRITE|MAY_TRUNC             },
570
    {   NFS3_ACCESS_EXTEND,     MAY_WRITE                       },
571
 
572
    {   0,                       0                                }
573
};
574
 
575
static struct accessmap nfs3_diraccess[] = {
576
    {   NFS3_ACCESS_READ,       MAY_READ                        },
577
    {   NFS3_ACCESS_LOOKUP,     MAY_EXEC                        },
578
    {   NFS3_ACCESS_MODIFY,     MAY_EXEC|MAY_WRITE|MAY_TRUNC    },
579
    {   NFS3_ACCESS_EXTEND,     MAY_EXEC|MAY_WRITE              },
580
    {   NFS3_ACCESS_DELETE,     MAY_REMOVE                      },
581
 
582
    {   0,                       0                                }
583
};
584
 
585
static struct accessmap nfs3_anyaccess[] = {
586
        /* Some clients - Solaris 2.6 at least, make an access call
587
         * to the server to check for access for things like /dev/null
588
         * (which really, the server doesn't care about).  So
589
         * We provide simple access checking for them, looking
590
         * mainly at mode bits, and we make sure to ignore read-only
591
         * filesystem checks
592
         */
593
    {   NFS3_ACCESS_READ,       MAY_READ                        },
594
    {   NFS3_ACCESS_EXECUTE,    MAY_EXEC                        },
595
    {   NFS3_ACCESS_MODIFY,     MAY_WRITE|MAY_LOCAL_ACCESS      },
596
    {   NFS3_ACCESS_EXTEND,     MAY_WRITE|MAY_LOCAL_ACCESS      },
597
 
598
    {   0,                       0                                }
599
};
600
 
601
__be32
602
nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *supported)
603
{
604
        struct accessmap        *map;
605
        struct svc_export       *export;
606
        struct dentry           *dentry;
607
        u32                     query, result = 0, sresult = 0;
608
        __be32                  error;
609
 
610
        error = fh_verify(rqstp, fhp, 0, MAY_NOP);
611
        if (error)
612
                goto out;
613
 
614
        export = fhp->fh_export;
615
        dentry = fhp->fh_dentry;
616
 
617
        if (S_ISREG(dentry->d_inode->i_mode))
618
                map = nfs3_regaccess;
619
        else if (S_ISDIR(dentry->d_inode->i_mode))
620
                map = nfs3_diraccess;
621
        else
622
                map = nfs3_anyaccess;
623
 
624
 
625
        query = *access;
626
        for  (; map->access; map++) {
627
                if (map->access & query) {
628
                        __be32 err2;
629
 
630
                        sresult |= map->access;
631
 
632
                        err2 = nfsd_permission(rqstp, export, dentry, map->how);
633
                        switch (err2) {
634
                        case nfs_ok:
635
                                result |= map->access;
636
                                break;
637
 
638
                        /* the following error codes just mean the access was not allowed,
639
                         * rather than an error occurred */
640
                        case nfserr_rofs:
641
                        case nfserr_acces:
642
                        case nfserr_perm:
643
                                /* simply don't "or" in the access bit. */
644
                                break;
645
                        default:
646
                                error = err2;
647
                                goto out;
648
                        }
649
                }
650
        }
651
        *access = result;
652
        if (supported)
653
                *supported = sresult;
654
 
655
 out:
656
        return error;
657
}
658
#endif /* CONFIG_NFSD_V3 */
659
 
660
 
661
 
662
/*
663
 * Open an existing file or directory.
664
 * The access argument indicates the type of open (read/write/lock)
665
 * N.B. After this call fhp needs an fh_put
666
 */
667
__be32
668
nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
669
                        int access, struct file **filp)
670
{
671
        struct dentry   *dentry;
672
        struct inode    *inode;
673
        int             flags = O_RDONLY|O_LARGEFILE;
674
        __be32          err;
675
        int             host_err;
676
 
677
        /*
678
         * If we get here, then the client has already done an "open",
679
         * and (hopefully) checked permission - so allow OWNER_OVERRIDE
680
         * in case a chmod has now revoked permission.
681
         */
682
        err = fh_verify(rqstp, fhp, type, access | MAY_OWNER_OVERRIDE);
683
        if (err)
684
                goto out;
685
 
686
        dentry = fhp->fh_dentry;
687
        inode = dentry->d_inode;
688
 
689
        /* Disallow write access to files with the append-only bit set
690
         * or any access when mandatory locking enabled
691
         */
692
        err = nfserr_perm;
693
        if (IS_APPEND(inode) && (access & MAY_WRITE))
694
                goto out;
695
        /*
696
         * We must ignore files (but only files) which might have mandatory
697
         * locks on them because there is no way to know if the accesser has
698
         * the lock.
699
         */
700
        if (S_ISREG((inode)->i_mode) && mandatory_lock(inode))
701
                goto out;
702
 
703
        if (!inode->i_fop)
704
                goto out;
705
 
706
        /*
707
         * Check to see if there are any leases on this file.
708
         * This may block while leases are broken.
709
         */
710
        host_err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0));
711
        if (host_err == -EWOULDBLOCK)
712
                host_err = -ETIMEDOUT;
713
        if (host_err) /* NOMEM or WOULDBLOCK */
714
                goto out_nfserr;
715
 
716
        if (access & MAY_WRITE) {
717
                if (access & MAY_READ)
718
                        flags = O_RDWR|O_LARGEFILE;
719
                else
720
                        flags = O_WRONLY|O_LARGEFILE;
721
 
722
                DQUOT_INIT(inode);
723
        }
724
        *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags);
725
        if (IS_ERR(*filp))
726
                host_err = PTR_ERR(*filp);
727
out_nfserr:
728
        err = nfserrno(host_err);
729
out:
730
        return err;
731
}
732
 
733
/*
734
 * Close a file.
735
 */
736
void
737
nfsd_close(struct file *filp)
738
{
739
        fput(filp);
740
}
741
 
742
/*
743
 * Sync a file
744
 * As this calls fsync (not fdatasync) there is no need for a write_inode
745
 * after it.
746
 */
747
static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
748
                              const struct file_operations *fop)
749
{
750
        struct inode *inode = dp->d_inode;
751
        int (*fsync) (struct file *, struct dentry *, int);
752
        int err;
753
 
754
        err = filemap_fdatawrite(inode->i_mapping);
755
        if (err == 0 && fop && (fsync = fop->fsync))
756
                err = fsync(filp, dp, 0);
757
        if (err == 0)
758
                err = filemap_fdatawait(inode->i_mapping);
759
 
760
        return err;
761
}
762
 
763
 
764
static int
765
nfsd_sync(struct file *filp)
766
{
767
        int err;
768
        struct inode *inode = filp->f_path.dentry->d_inode;
769
        dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name);
770
        mutex_lock(&inode->i_mutex);
771
        err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op);
772
        mutex_unlock(&inode->i_mutex);
773
 
774
        return err;
775
}
776
 
777
int
778
nfsd_sync_dir(struct dentry *dp)
779
{
780
        return nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
781
}
782
 
783
/*
784
 * Obtain the readahead parameters for the file
785
 * specified by (dev, ino).
786
 */
787
 
788
static inline struct raparms *
789
nfsd_get_raparms(dev_t dev, ino_t ino)
790
{
791
        struct raparms  *ra, **rap, **frap = NULL;
792
        int depth = 0;
793
        unsigned int hash;
794
        struct raparm_hbucket *rab;
795
 
796
        hash = jhash_2words(dev, ino, 0xfeedbeef) & RAPARM_HASH_MASK;
797
        rab = &raparm_hash[hash];
798
 
799
        spin_lock(&rab->pb_lock);
800
        for (rap = &rab->pb_head; (ra = *rap); rap = &ra->p_next) {
801
                if (ra->p_ino == ino && ra->p_dev == dev)
802
                        goto found;
803
                depth++;
804
                if (ra->p_count == 0)
805
                        frap = rap;
806
        }
807
        depth = nfsdstats.ra_size*11/10;
808
        if (!frap) {
809
                spin_unlock(&rab->pb_lock);
810
                return NULL;
811
        }
812
        rap = frap;
813
        ra = *frap;
814
        ra->p_dev = dev;
815
        ra->p_ino = ino;
816
        ra->p_set = 0;
817
        ra->p_hindex = hash;
818
found:
819
        if (rap != &rab->pb_head) {
820
                *rap = ra->p_next;
821
                ra->p_next   = rab->pb_head;
822
                rab->pb_head = ra;
823
        }
824
        ra->p_count++;
825
        nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
826
        spin_unlock(&rab->pb_lock);
827
        return ra;
828
}
829
 
830
/*
831
 * Grab and keep cached pages associated with a file in the svc_rqst
832
 * so that they can be passed to the network sendmsg/sendpage routines
833
 * directly. They will be released after the sending has completed.
834
 */
835
static int
836
nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
837
                  struct splice_desc *sd)
838
{
839
        struct svc_rqst *rqstp = sd->u.data;
840
        struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
841
        struct page *page = buf->page;
842
        size_t size;
843
        int ret;
844
 
845
        ret = buf->ops->confirm(pipe, buf);
846
        if (unlikely(ret))
847
                return ret;
848
 
849
        size = sd->len;
850
 
851
        if (rqstp->rq_res.page_len == 0) {
852
                get_page(page);
853
                put_page(*pp);
854
                *pp = page;
855
                rqstp->rq_resused++;
856
                rqstp->rq_res.page_base = buf->offset;
857
                rqstp->rq_res.page_len = size;
858
        } else if (page != pp[-1]) {
859
                get_page(page);
860
                if (*pp)
861
                        put_page(*pp);
862
                *pp = page;
863
                rqstp->rq_resused++;
864
                rqstp->rq_res.page_len += size;
865
        } else
866
                rqstp->rq_res.page_len += size;
867
 
868
        return size;
869
}
870
 
871
static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
872
                                    struct splice_desc *sd)
873
{
874
        return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
875
}
876
 
877
static inline int svc_msnfs(struct svc_fh *ffhp)
878
{
879
#ifdef MSNFS
880
        return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS);
881
#else
882
        return 0;
883
#endif
884
}
885
 
886
static __be32
887
nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
888
              loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
889
{
890
        struct inode *inode;
891
        struct raparms  *ra;
892
        mm_segment_t    oldfs;
893
        __be32          err;
894
        int             host_err;
895
 
896
        err = nfserr_perm;
897
        inode = file->f_path.dentry->d_inode;
898
 
899
        if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
900
                goto out;
901
 
902
        /* Get readahead parameters */
903
        ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
904
 
905
        if (ra && ra->p_set)
906
                file->f_ra = ra->p_ra;
907
 
908
        if (file->f_op->splice_read && rqstp->rq_splice_ok) {
909
                struct splice_desc sd = {
910
                        .len            = 0,
911
                        .total_len      = *count,
912
                        .pos            = offset,
913
                        .u.data         = rqstp,
914
                };
915
 
916
                rqstp->rq_resused = 1;
917
                host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
918
        } else {
919
                oldfs = get_fs();
920
                set_fs(KERNEL_DS);
921
                host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
922
                set_fs(oldfs);
923
        }
924
 
925
        /* Write back readahead params */
926
        if (ra) {
927
                struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
928
                spin_lock(&rab->pb_lock);
929
                ra->p_ra = file->f_ra;
930
                ra->p_set = 1;
931
                ra->p_count--;
932
                spin_unlock(&rab->pb_lock);
933
        }
934
 
935
        if (host_err >= 0) {
936
                nfsdstats.io_read += host_err;
937
                *count = host_err;
938
                err = 0;
939
                fsnotify_access(file->f_path.dentry);
940
        } else
941
                err = nfserrno(host_err);
942
out:
943
        return err;
944
}
945
 
946
static void kill_suid(struct dentry *dentry)
947
{
948
        struct iattr    ia;
949
        ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
950
 
951
        mutex_lock(&dentry->d_inode->i_mutex);
952
        notify_change(dentry, &ia);
953
        mutex_unlock(&dentry->d_inode->i_mutex);
954
}
955
 
956
static __be32
957
nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
958
                                loff_t offset, struct kvec *vec, int vlen,
959
                                unsigned long cnt, int *stablep)
960
{
961
        struct svc_export       *exp;
962
        struct dentry           *dentry;
963
        struct inode            *inode;
964
        mm_segment_t            oldfs;
965
        __be32                  err = 0;
966
        int                     host_err;
967
        int                     stable = *stablep;
968
 
969
#ifdef MSNFS
970
        err = nfserr_perm;
971
 
972
        if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
973
                (!lock_may_write(file->f_path.dentry->d_inode, offset, cnt)))
974
                goto out;
975
#endif
976
 
977
        dentry = file->f_path.dentry;
978
        inode = dentry->d_inode;
979
        exp   = fhp->fh_export;
980
 
981
        /*
982
         * Request sync writes if
983
         *  -   the sync export option has been set, or
984
         *  -   the client requested O_SYNC behavior (NFSv3 feature).
985
         *  -   The file system doesn't support fsync().
986
         * When gathered writes have been configured for this volume,
987
         * flushing the data to disk is handled separately below.
988
         */
989
 
990
        if (file->f_op->fsync == 0) {/* COMMIT3 cannot work */
991
               stable = 2;
992
               *stablep = 2; /* FILE_SYNC */
993
        }
994
 
995
        if (!EX_ISSYNC(exp))
996
                stable = 0;
997
        if (stable && !EX_WGATHER(exp))
998
                file->f_flags |= O_SYNC;
999
 
1000
        /* Write the data. */
1001
        oldfs = get_fs(); set_fs(KERNEL_DS);
1002
        host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
1003
        set_fs(oldfs);
1004
        if (host_err >= 0) {
1005
                nfsdstats.io_write += cnt;
1006
                fsnotify_modify(file->f_path.dentry);
1007
        }
1008
 
1009
        /* clear setuid/setgid flag after write */
1010
        if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
1011
                kill_suid(dentry);
1012
 
1013
        if (host_err >= 0 && stable) {
1014
                static ino_t    last_ino;
1015
                static dev_t    last_dev;
1016
 
1017
                /*
1018
                 * Gathered writes: If another process is currently
1019
                 * writing to the file, there's a high chance
1020
                 * this is another nfsd (triggered by a bulk write
1021
                 * from a client's biod). Rather than syncing the
1022
                 * file with each write request, we sleep for 10 msec.
1023
                 *
1024
                 * I don't know if this roughly approximates
1025
                 * C. Juszak's idea of gathered writes, but it's a
1026
                 * nice and simple solution (IMHO), and it seems to
1027
                 * work:-)
1028
                 */
1029
                if (EX_WGATHER(exp)) {
1030
                        if (atomic_read(&inode->i_writecount) > 1
1031
                            || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) {
1032
                                dprintk("nfsd: write defer %d\n", task_pid_nr(current));
1033
                                msleep(10);
1034
                                dprintk("nfsd: write resume %d\n", task_pid_nr(current));
1035
                        }
1036
 
1037
                        if (inode->i_state & I_DIRTY) {
1038
                                dprintk("nfsd: write sync %d\n", task_pid_nr(current));
1039
                                host_err=nfsd_sync(file);
1040
                        }
1041
#if 0
1042
                        wake_up(&inode->i_wait);
1043
#endif
1044
                }
1045
                last_ino = inode->i_ino;
1046
                last_dev = inode->i_sb->s_dev;
1047
        }
1048
 
1049
        dprintk("nfsd: write complete host_err=%d\n", host_err);
1050
        if (host_err >= 0)
1051
                err = 0;
1052
        else
1053
                err = nfserrno(host_err);
1054
out:
1055
        return err;
1056
}
1057
 
1058
/*
1059
 * Read data from a file. count must contain the requested read count
1060
 * on entry. On return, *count contains the number of bytes actually read.
1061
 * N.B. After this call fhp needs an fh_put
1062
 */
1063
__be32
1064
nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1065
                loff_t offset, struct kvec *vec, int vlen,
1066
                unsigned long *count)
1067
{
1068
        __be32          err;
1069
 
1070
        if (file) {
1071
                err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry,
1072
                                MAY_READ|MAY_OWNER_OVERRIDE);
1073
                if (err)
1074
                        goto out;
1075
                err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1076
        } else {
1077
                err = nfsd_open(rqstp, fhp, S_IFREG, MAY_READ, &file);
1078
                if (err)
1079
                        goto out;
1080
                err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1081
                nfsd_close(file);
1082
        }
1083
out:
1084
        return err;
1085
}
1086
 
1087
/*
1088
 * Write data to a file.
1089
 * The stable flag requests synchronous writes.
1090
 * N.B. After this call fhp needs an fh_put
1091
 */
1092
__be32
1093
nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1094
                loff_t offset, struct kvec *vec, int vlen, unsigned long cnt,
1095
                int *stablep)
1096
{
1097
        __be32                  err = 0;
1098
 
1099
        if (file) {
1100
                err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry,
1101
                                MAY_WRITE|MAY_OWNER_OVERRIDE);
1102
                if (err)
1103
                        goto out;
1104
                err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, cnt,
1105
                                stablep);
1106
        } else {
1107
                err = nfsd_open(rqstp, fhp, S_IFREG, MAY_WRITE, &file);
1108
                if (err)
1109
                        goto out;
1110
 
1111
                if (cnt)
1112
                        err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen,
1113
                                             cnt, stablep);
1114
                nfsd_close(file);
1115
        }
1116
out:
1117
        return err;
1118
}
1119
 
1120
#ifdef CONFIG_NFSD_V3
1121
/*
1122
 * Commit all pending writes to stable storage.
1123
 * Strictly speaking, we could sync just the indicated file region here,
1124
 * but there's currently no way we can ask the VFS to do so.
1125
 *
1126
 * Unfortunately we cannot lock the file to make sure we return full WCC
1127
 * data to the client, as locking happens lower down in the filesystem.
1128
 */
1129
__be32
1130
nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1131
               loff_t offset, unsigned long count)
1132
{
1133
        struct file     *file;
1134
        __be32          err;
1135
 
1136
        if ((u64)count > ~(u64)offset)
1137
                return nfserr_inval;
1138
 
1139
        if ((err = nfsd_open(rqstp, fhp, S_IFREG, MAY_WRITE, &file)) != 0)
1140
                return err;
1141
        if (EX_ISSYNC(fhp->fh_export)) {
1142
                if (file->f_op && file->f_op->fsync) {
1143
                        err = nfserrno(nfsd_sync(file));
1144
                } else {
1145
                        err = nfserr_notsupp;
1146
                }
1147
        }
1148
 
1149
        nfsd_close(file);
1150
        return err;
1151
}
1152
#endif /* CONFIG_NFSD_V3 */
1153
 
1154
/*
1155
 * Create a file (regular, directory, device, fifo); UNIX sockets
1156
 * not yet implemented.
1157
 * If the response fh has been verified, the parent directory should
1158
 * already be locked. Note that the parent directory is left locked.
1159
 *
1160
 * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
1161
 */
1162
__be32
1163
nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1164
                char *fname, int flen, struct iattr *iap,
1165
                int type, dev_t rdev, struct svc_fh *resfhp)
1166
{
1167
        struct dentry   *dentry, *dchild = NULL;
1168
        struct inode    *dirp;
1169
        __be32          err;
1170
        int             host_err;
1171
 
1172
        err = nfserr_perm;
1173
        if (!flen)
1174
                goto out;
1175
        err = nfserr_exist;
1176
        if (isdotent(fname, flen))
1177
                goto out;
1178
 
1179
        err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
1180
        if (err)
1181
                goto out;
1182
 
1183
        dentry = fhp->fh_dentry;
1184
        dirp = dentry->d_inode;
1185
 
1186
        err = nfserr_notdir;
1187
        if(!dirp->i_op || !dirp->i_op->lookup)
1188
                goto out;
1189
        /*
1190
         * Check whether the response file handle has been verified yet.
1191
         * If it has, the parent directory should already be locked.
1192
         */
1193
        if (!resfhp->fh_dentry) {
1194
                /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
1195
                fh_lock_nested(fhp, I_MUTEX_PARENT);
1196
                dchild = lookup_one_len(fname, dentry, flen);
1197
                host_err = PTR_ERR(dchild);
1198
                if (IS_ERR(dchild))
1199
                        goto out_nfserr;
1200
                err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
1201
                if (err)
1202
                        goto out;
1203
        } else {
1204
                /* called from nfsd_proc_create */
1205
                dchild = dget(resfhp->fh_dentry);
1206
                if (!fhp->fh_locked) {
1207
                        /* not actually possible */
1208
                        printk(KERN_ERR
1209
                                "nfsd_create: parent %s/%s not locked!\n",
1210
                                dentry->d_parent->d_name.name,
1211
                                dentry->d_name.name);
1212
                        err = nfserr_io;
1213
                        goto out;
1214
                }
1215
        }
1216
        /*
1217
         * Make sure the child dentry is still negative ...
1218
         */
1219
        err = nfserr_exist;
1220
        if (dchild->d_inode) {
1221
                dprintk("nfsd_create: dentry %s/%s not negative!\n",
1222
                        dentry->d_name.name, dchild->d_name.name);
1223
                goto out;
1224
        }
1225
 
1226
        if (!(iap->ia_valid & ATTR_MODE))
1227
                iap->ia_mode = 0;
1228
        iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type;
1229
 
1230
        /*
1231
         * Get the dir op function pointer.
1232
         */
1233
        err = 0;
1234
        switch (type) {
1235
        case S_IFREG:
1236
                host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1237
                break;
1238
        case S_IFDIR:
1239
                host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
1240
                break;
1241
        case S_IFCHR:
1242
        case S_IFBLK:
1243
        case S_IFIFO:
1244
        case S_IFSOCK:
1245
                host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
1246
                break;
1247
        default:
1248
                printk("nfsd: bad file type %o in nfsd_create\n", type);
1249
                host_err = -EINVAL;
1250
        }
1251
        if (host_err < 0)
1252
                goto out_nfserr;
1253
 
1254
        if (EX_ISSYNC(fhp->fh_export)) {
1255
                err = nfserrno(nfsd_sync_dir(dentry));
1256
                write_inode_now(dchild->d_inode, 1);
1257
        }
1258
 
1259
 
1260
        /* Set file attributes. Mode has already been set and
1261
         * setting uid/gid works only for root. Irix appears to
1262
         * send along the gid when it tries to implement setgid
1263
         * directories via NFS.
1264
         */
1265
        if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1266
                __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1267
                if (err2)
1268
                        err = err2;
1269
        }
1270
        /*
1271
         * Update the file handle to get the new inode info.
1272
         */
1273
        if (!err)
1274
                err = fh_update(resfhp);
1275
out:
1276
        if (dchild && !IS_ERR(dchild))
1277
                dput(dchild);
1278
        return err;
1279
 
1280
out_nfserr:
1281
        err = nfserrno(host_err);
1282
        goto out;
1283
}
1284
 
1285
#ifdef CONFIG_NFSD_V3
1286
/*
1287
 * NFSv3 version of nfsd_create
1288
 */
1289
__be32
1290
nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1291
                char *fname, int flen, struct iattr *iap,
1292
                struct svc_fh *resfhp, int createmode, u32 *verifier,
1293
                int *truncp, int *created)
1294
{
1295
        struct dentry   *dentry, *dchild = NULL;
1296
        struct inode    *dirp;
1297
        __be32          err;
1298
        int             host_err;
1299
        __u32           v_mtime=0, v_atime=0;
1300
 
1301
        err = nfserr_perm;
1302
        if (!flen)
1303
                goto out;
1304
        err = nfserr_exist;
1305
        if (isdotent(fname, flen))
1306
                goto out;
1307
        if (!(iap->ia_valid & ATTR_MODE))
1308
                iap->ia_mode = 0;
1309
        err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
1310
        if (err)
1311
                goto out;
1312
 
1313
        dentry = fhp->fh_dentry;
1314
        dirp = dentry->d_inode;
1315
 
1316
        /* Get all the sanity checks out of the way before
1317
         * we lock the parent. */
1318
        err = nfserr_notdir;
1319
        if(!dirp->i_op || !dirp->i_op->lookup)
1320
                goto out;
1321
        fh_lock_nested(fhp, I_MUTEX_PARENT);
1322
 
1323
        /*
1324
         * Compose the response file handle.
1325
         */
1326
        dchild = lookup_one_len(fname, dentry, flen);
1327
        host_err = PTR_ERR(dchild);
1328
        if (IS_ERR(dchild))
1329
                goto out_nfserr;
1330
 
1331
        err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
1332
        if (err)
1333
                goto out;
1334
 
1335
        if (createmode == NFS3_CREATE_EXCLUSIVE) {
1336
                /* solaris7 gets confused (bugid 4218508) if these have
1337
                 * the high bit set, so just clear the high bits. If this is
1338
                 * ever changed to use different attrs for storing the
1339
                 * verifier, then do_open_lookup() will also need to be fixed
1340
                 * accordingly.
1341
                 */
1342
                v_mtime = verifier[0]&0x7fffffff;
1343
                v_atime = verifier[1]&0x7fffffff;
1344
        }
1345
 
1346
        if (dchild->d_inode) {
1347
                err = 0;
1348
 
1349
                switch (createmode) {
1350
                case NFS3_CREATE_UNCHECKED:
1351
                        if (! S_ISREG(dchild->d_inode->i_mode))
1352
                                err = nfserr_exist;
1353
                        else if (truncp) {
1354
                                /* in nfsv4, we need to treat this case a little
1355
                                 * differently.  we don't want to truncate the
1356
                                 * file now; this would be wrong if the OPEN
1357
                                 * fails for some other reason.  furthermore,
1358
                                 * if the size is nonzero, we should ignore it
1359
                                 * according to spec!
1360
                                 */
1361
                                *truncp = (iap->ia_valid & ATTR_SIZE) && !iap->ia_size;
1362
                        }
1363
                        else {
1364
                                iap->ia_valid &= ATTR_SIZE;
1365
                                goto set_attr;
1366
                        }
1367
                        break;
1368
                case NFS3_CREATE_EXCLUSIVE:
1369
                        if (   dchild->d_inode->i_mtime.tv_sec == v_mtime
1370
                            && dchild->d_inode->i_atime.tv_sec == v_atime
1371
                            && dchild->d_inode->i_size  == 0 )
1372
                                break;
1373
                         /* fallthru */
1374
                case NFS3_CREATE_GUARDED:
1375
                        err = nfserr_exist;
1376
                }
1377
                goto out;
1378
        }
1379
 
1380
        host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1381
        if (host_err < 0)
1382
                goto out_nfserr;
1383
        if (created)
1384
                *created = 1;
1385
 
1386
        if (EX_ISSYNC(fhp->fh_export)) {
1387
                err = nfserrno(nfsd_sync_dir(dentry));
1388
                /* setattr will sync the child (or not) */
1389
        }
1390
 
1391
        if (createmode == NFS3_CREATE_EXCLUSIVE) {
1392
                /* Cram the verifier into atime/mtime */
1393
                iap->ia_valid = ATTR_MTIME|ATTR_ATIME
1394
                        | ATTR_MTIME_SET|ATTR_ATIME_SET;
1395
                /* XXX someone who knows this better please fix it for nsec */
1396
                iap->ia_mtime.tv_sec = v_mtime;
1397
                iap->ia_atime.tv_sec = v_atime;
1398
                iap->ia_mtime.tv_nsec = 0;
1399
                iap->ia_atime.tv_nsec = 0;
1400
        }
1401
 
1402
        /* Set file attributes.
1403
         * Irix appears to send along the gid when it tries to
1404
         * implement setgid directories via NFS. Clear out all that cruft.
1405
         */
1406
 set_attr:
1407
        if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1408
                __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1409
                if (err2)
1410
                        err = err2;
1411
        }
1412
 
1413
        /*
1414
         * Update the filehandle to get the new inode info.
1415
         */
1416
        if (!err)
1417
                err = fh_update(resfhp);
1418
 
1419
 out:
1420
        fh_unlock(fhp);
1421
        if (dchild && !IS_ERR(dchild))
1422
                dput(dchild);
1423
        return err;
1424
 
1425
 out_nfserr:
1426
        err = nfserrno(host_err);
1427
        goto out;
1428
}
1429
#endif /* CONFIG_NFSD_V3 */
1430
 
1431
/*
1432
 * Read a symlink. On entry, *lenp must contain the maximum path length that
1433
 * fits into the buffer. On return, it contains the true length.
1434
 * N.B. After this call fhp needs an fh_put
1435
 */
1436
__be32
1437
nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
1438
{
1439
        struct dentry   *dentry;
1440
        struct inode    *inode;
1441
        mm_segment_t    oldfs;
1442
        __be32          err;
1443
        int             host_err;
1444
 
1445
        err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP);
1446
        if (err)
1447
                goto out;
1448
 
1449
        dentry = fhp->fh_dentry;
1450
        inode = dentry->d_inode;
1451
 
1452
        err = nfserr_inval;
1453
        if (!inode->i_op || !inode->i_op->readlink)
1454
                goto out;
1455
 
1456
        touch_atime(fhp->fh_export->ex_mnt, dentry);
1457
        /* N.B. Why does this call need a get_fs()??
1458
         * Remove the set_fs and watch the fireworks:-) --okir
1459
         */
1460
 
1461
        oldfs = get_fs(); set_fs(KERNEL_DS);
1462
        host_err = inode->i_op->readlink(dentry, buf, *lenp);
1463
        set_fs(oldfs);
1464
 
1465
        if (host_err < 0)
1466
                goto out_nfserr;
1467
        *lenp = host_err;
1468
        err = 0;
1469
out:
1470
        return err;
1471
 
1472
out_nfserr:
1473
        err = nfserrno(host_err);
1474
        goto out;
1475
}
1476
 
1477
/*
1478
 * Create a symlink and look up its inode
1479
 * N.B. After this call _both_ fhp and resfhp need an fh_put
1480
 */
1481
__be32
1482
nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1483
                                char *fname, int flen,
1484
                                char *path,  int plen,
1485
                                struct svc_fh *resfhp,
1486
                                struct iattr *iap)
1487
{
1488
        struct dentry   *dentry, *dnew;
1489
        __be32          err, cerr;
1490
        int             host_err;
1491
        umode_t         mode;
1492
 
1493
        err = nfserr_noent;
1494
        if (!flen || !plen)
1495
                goto out;
1496
        err = nfserr_exist;
1497
        if (isdotent(fname, flen))
1498
                goto out;
1499
 
1500
        err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
1501
        if (err)
1502
                goto out;
1503
        fh_lock(fhp);
1504
        dentry = fhp->fh_dentry;
1505
        dnew = lookup_one_len(fname, dentry, flen);
1506
        host_err = PTR_ERR(dnew);
1507
        if (IS_ERR(dnew))
1508
                goto out_nfserr;
1509
 
1510
        mode = S_IALLUGO;
1511
        /* Only the MODE ATTRibute is even vaguely meaningful */
1512
        if (iap && (iap->ia_valid & ATTR_MODE))
1513
                mode = iap->ia_mode & S_IALLUGO;
1514
 
1515
        if (unlikely(path[plen] != 0)) {
1516
                char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
1517
                if (path_alloced == NULL)
1518
                        host_err = -ENOMEM;
1519
                else {
1520
                        strncpy(path_alloced, path, plen);
1521
                        path_alloced[plen] = 0;
1522
                        host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
1523
                        kfree(path_alloced);
1524
                }
1525
        } else
1526
                host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
1527
 
1528
        if (!host_err) {
1529
                if (EX_ISSYNC(fhp->fh_export))
1530
                        host_err = nfsd_sync_dir(dentry);
1531
        }
1532
        err = nfserrno(host_err);
1533
        fh_unlock(fhp);
1534
 
1535
        cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
1536
        dput(dnew);
1537
        if (err==0) err = cerr;
1538
out:
1539
        return err;
1540
 
1541
out_nfserr:
1542
        err = nfserrno(host_err);
1543
        goto out;
1544
}
1545
 
1546
/*
1547
 * Create a hardlink
1548
 * N.B. After this call _both_ ffhp and tfhp need an fh_put
1549
 */
1550
__be32
1551
nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1552
                                char *name, int len, struct svc_fh *tfhp)
1553
{
1554
        struct dentry   *ddir, *dnew, *dold;
1555
        struct inode    *dirp, *dest;
1556
        __be32          err;
1557
        int             host_err;
1558
 
1559
        err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE);
1560
        if (err)
1561
                goto out;
1562
        err = fh_verify(rqstp, tfhp, -S_IFDIR, MAY_NOP);
1563
        if (err)
1564
                goto out;
1565
 
1566
        err = nfserr_perm;
1567
        if (!len)
1568
                goto out;
1569
        err = nfserr_exist;
1570
        if (isdotent(name, len))
1571
                goto out;
1572
 
1573
        fh_lock_nested(ffhp, I_MUTEX_PARENT);
1574
        ddir = ffhp->fh_dentry;
1575
        dirp = ddir->d_inode;
1576
 
1577
        dnew = lookup_one_len(name, ddir, len);
1578
        host_err = PTR_ERR(dnew);
1579
        if (IS_ERR(dnew))
1580
                goto out_nfserr;
1581
 
1582
        dold = tfhp->fh_dentry;
1583
        dest = dold->d_inode;
1584
 
1585
        host_err = vfs_link(dold, dirp, dnew);
1586
        if (!host_err) {
1587
                if (EX_ISSYNC(ffhp->fh_export)) {
1588
                        err = nfserrno(nfsd_sync_dir(ddir));
1589
                        write_inode_now(dest, 1);
1590
                }
1591
                err = 0;
1592
        } else {
1593
                if (host_err == -EXDEV && rqstp->rq_vers == 2)
1594
                        err = nfserr_acces;
1595
                else
1596
                        err = nfserrno(host_err);
1597
        }
1598
 
1599
        dput(dnew);
1600
out_unlock:
1601
        fh_unlock(ffhp);
1602
out:
1603
        return err;
1604
 
1605
out_nfserr:
1606
        err = nfserrno(host_err);
1607
        goto out_unlock;
1608
}
1609
 
1610
/*
1611
 * Rename a file
1612
 * N.B. After this call _both_ ffhp and tfhp need an fh_put
1613
 */
1614
__be32
1615
nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1616
                            struct svc_fh *tfhp, char *tname, int tlen)
1617
{
1618
        struct dentry   *fdentry, *tdentry, *odentry, *ndentry, *trap;
1619
        struct inode    *fdir, *tdir;
1620
        __be32          err;
1621
        int             host_err;
1622
 
1623
        err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE);
1624
        if (err)
1625
                goto out;
1626
        err = fh_verify(rqstp, tfhp, S_IFDIR, MAY_CREATE);
1627
        if (err)
1628
                goto out;
1629
 
1630
        fdentry = ffhp->fh_dentry;
1631
        fdir = fdentry->d_inode;
1632
 
1633
        tdentry = tfhp->fh_dentry;
1634
        tdir = tdentry->d_inode;
1635
 
1636
        err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev;
1637
        if (ffhp->fh_export != tfhp->fh_export)
1638
                goto out;
1639
 
1640
        err = nfserr_perm;
1641
        if (!flen || isdotent(fname, flen) || !tlen || isdotent(tname, tlen))
1642
                goto out;
1643
 
1644
        /* cannot use fh_lock as we need deadlock protective ordering
1645
         * so do it by hand */
1646
        trap = lock_rename(tdentry, fdentry);
1647
        ffhp->fh_locked = tfhp->fh_locked = 1;
1648
        fill_pre_wcc(ffhp);
1649
        fill_pre_wcc(tfhp);
1650
 
1651
        odentry = lookup_one_len(fname, fdentry, flen);
1652
        host_err = PTR_ERR(odentry);
1653
        if (IS_ERR(odentry))
1654
                goto out_nfserr;
1655
 
1656
        host_err = -ENOENT;
1657
        if (!odentry->d_inode)
1658
                goto out_dput_old;
1659
        host_err = -EINVAL;
1660
        if (odentry == trap)
1661
                goto out_dput_old;
1662
 
1663
        ndentry = lookup_one_len(tname, tdentry, tlen);
1664
        host_err = PTR_ERR(ndentry);
1665
        if (IS_ERR(ndentry))
1666
                goto out_dput_old;
1667
        host_err = -ENOTEMPTY;
1668
        if (ndentry == trap)
1669
                goto out_dput_new;
1670
 
1671
#ifdef MSNFS
1672
        if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1673
                ((atomic_read(&odentry->d_count) > 1)
1674
                 || (atomic_read(&ndentry->d_count) > 1))) {
1675
                        host_err = -EPERM;
1676
        } else
1677
#endif
1678
        host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1679
        if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
1680
                host_err = nfsd_sync_dir(tdentry);
1681
                if (!host_err)
1682
                        host_err = nfsd_sync_dir(fdentry);
1683
        }
1684
 
1685
 out_dput_new:
1686
        dput(ndentry);
1687
 out_dput_old:
1688
        dput(odentry);
1689
 out_nfserr:
1690
        err = nfserrno(host_err);
1691
 
1692
        /* we cannot reply on fh_unlock on the two filehandles,
1693
         * as that would do the wrong thing if the two directories
1694
         * were the same, so again we do it by hand
1695
         */
1696
        fill_post_wcc(ffhp);
1697
        fill_post_wcc(tfhp);
1698
        unlock_rename(tdentry, fdentry);
1699
        ffhp->fh_locked = tfhp->fh_locked = 0;
1700
 
1701
out:
1702
        return err;
1703
}
1704
 
1705
/*
1706
 * Unlink a file or directory
1707
 * N.B. After this call fhp needs an fh_put
1708
 */
1709
__be32
1710
nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1711
                                char *fname, int flen)
1712
{
1713
        struct dentry   *dentry, *rdentry;
1714
        struct inode    *dirp;
1715
        __be32          err;
1716
        int             host_err;
1717
 
1718
        err = nfserr_acces;
1719
        if (!flen || isdotent(fname, flen))
1720
                goto out;
1721
        err = fh_verify(rqstp, fhp, S_IFDIR, MAY_REMOVE);
1722
        if (err)
1723
                goto out;
1724
 
1725
        fh_lock_nested(fhp, I_MUTEX_PARENT);
1726
        dentry = fhp->fh_dentry;
1727
        dirp = dentry->d_inode;
1728
 
1729
        rdentry = lookup_one_len(fname, dentry, flen);
1730
        host_err = PTR_ERR(rdentry);
1731
        if (IS_ERR(rdentry))
1732
                goto out_nfserr;
1733
 
1734
        if (!rdentry->d_inode) {
1735
                dput(rdentry);
1736
                err = nfserr_noent;
1737
                goto out;
1738
        }
1739
 
1740
        if (!type)
1741
                type = rdentry->d_inode->i_mode & S_IFMT;
1742
 
1743
        if (type != S_IFDIR) { /* It's UNLINK */
1744
#ifdef MSNFS
1745
                if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1746
                        (atomic_read(&rdentry->d_count) > 1)) {
1747
                        host_err = -EPERM;
1748
                } else
1749
#endif
1750
                host_err = vfs_unlink(dirp, rdentry);
1751
        } else { /* It's RMDIR */
1752
                host_err = vfs_rmdir(dirp, rdentry);
1753
        }
1754
 
1755
        dput(rdentry);
1756
 
1757
        if (host_err)
1758
                goto out_nfserr;
1759
        if (EX_ISSYNC(fhp->fh_export))
1760
                host_err = nfsd_sync_dir(dentry);
1761
 
1762
out_nfserr:
1763
        err = nfserrno(host_err);
1764
out:
1765
        return err;
1766
}
1767
 
1768
/*
1769
 * Read entries from a directory.
1770
 * The  NFSv3/4 verifier we ignore for now.
1771
 */
1772
__be32
1773
nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
1774
             struct readdir_cd *cdp, filldir_t func)
1775
{
1776
        __be32          err;
1777
        int             host_err;
1778
        struct file     *file;
1779
        loff_t          offset = *offsetp;
1780
 
1781
        err = nfsd_open(rqstp, fhp, S_IFDIR, MAY_READ, &file);
1782
        if (err)
1783
                goto out;
1784
 
1785
        offset = vfs_llseek(file, offset, 0);
1786
        if (offset < 0) {
1787
                err = nfserrno((int)offset);
1788
                goto out_close;
1789
        }
1790
 
1791
        /*
1792
         * Read the directory entries. This silly loop is necessary because
1793
         * readdir() is not guaranteed to fill up the entire buffer, but
1794
         * may choose to do less.
1795
         */
1796
 
1797
        do {
1798
                cdp->err = nfserr_eof; /* will be cleared on successful read */
1799
                host_err = vfs_readdir(file, func, cdp);
1800
        } while (host_err >=0 && cdp->err == nfs_ok);
1801
        if (host_err)
1802
                err = nfserrno(host_err);
1803
        else
1804
                err = cdp->err;
1805
        *offsetp = vfs_llseek(file, 0, 1);
1806
 
1807
        if (err == nfserr_eof || err == nfserr_toosmall)
1808
                err = nfs_ok; /* can still be found in ->err */
1809
out_close:
1810
        nfsd_close(file);
1811
out:
1812
        return err;
1813
}
1814
 
1815
/*
1816
 * Get file system stats
1817
 * N.B. After this call fhp needs an fh_put
1818
 */
1819
__be32
1820
nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
1821
{
1822
        __be32 err = fh_verify(rqstp, fhp, 0, MAY_NOP);
1823
        if (!err && vfs_statfs(fhp->fh_dentry,stat))
1824
                err = nfserr_io;
1825
        return err;
1826
}
1827
 
1828
static int exp_rdonly(struct svc_rqst *rqstp, struct svc_export *exp)
1829
{
1830
        return nfsexp_flags(rqstp, exp) & NFSEXP_READONLY;
1831
}
1832
 
1833
/*
1834
 * Check for a user's access permissions to this inode.
1835
 */
1836
__be32
1837
nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
1838
                                        struct dentry *dentry, int acc)
1839
{
1840
        struct inode    *inode = dentry->d_inode;
1841
        int             err;
1842
 
1843
        if (acc == MAY_NOP)
1844
                return 0;
1845
#if 0
1846
        dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n",
1847
                acc,
1848
                (acc & MAY_READ)?       " read"  : "",
1849
                (acc & MAY_WRITE)?      " write" : "",
1850
                (acc & MAY_EXEC)?       " exec"  : "",
1851
                (acc & MAY_SATTR)?      " sattr" : "",
1852
                (acc & MAY_TRUNC)?      " trunc" : "",
1853
                (acc & MAY_LOCK)?       " lock"  : "",
1854
                (acc & MAY_OWNER_OVERRIDE)? " owneroverride" : "",
1855
                inode->i_mode,
1856
                IS_IMMUTABLE(inode)?    " immut" : "",
1857
                IS_APPEND(inode)?       " append" : "",
1858
                IS_RDONLY(inode)?       " ro" : "");
1859
        dprintk("      owner %d/%d user %d/%d\n",
1860
                inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
1861
#endif
1862
 
1863
        /* Normally we reject any write/sattr etc access on a read-only file
1864
         * system.  But if it is IRIX doing check on write-access for a
1865
         * device special file, we ignore rofs.
1866
         */
1867
        if (!(acc & MAY_LOCAL_ACCESS))
1868
                if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
1869
                        if (exp_rdonly(rqstp, exp) || IS_RDONLY(inode))
1870
                                return nfserr_rofs;
1871
                        if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
1872
                                return nfserr_perm;
1873
                }
1874
        if ((acc & MAY_TRUNC) && IS_APPEND(inode))
1875
                return nfserr_perm;
1876
 
1877
        if (acc & MAY_LOCK) {
1878
                /* If we cannot rely on authentication in NLM requests,
1879
                 * just allow locks, otherwise require read permission, or
1880
                 * ownership
1881
                 */
1882
                if (exp->ex_flags & NFSEXP_NOAUTHNLM)
1883
                        return 0;
1884
                else
1885
                        acc = MAY_READ | MAY_OWNER_OVERRIDE;
1886
        }
1887
        /*
1888
         * The file owner always gets access permission for accesses that
1889
         * would normally be checked at open time. This is to make
1890
         * file access work even when the client has done a fchmod(fd, 0).
1891
         *
1892
         * However, `cp foo bar' should fail nevertheless when bar is
1893
         * readonly. A sensible way to do this might be to reject all
1894
         * attempts to truncate a read-only file, because a creat() call
1895
         * always implies file truncation.
1896
         * ... but this isn't really fair.  A process may reasonably call
1897
         * ftruncate on an open file descriptor on a file with perm 000.
1898
         * We must trust the client to do permission checking - using "ACCESS"
1899
         * with NFSv3.
1900
         */
1901
        if ((acc & MAY_OWNER_OVERRIDE) &&
1902
            inode->i_uid == current->fsuid)
1903
                return 0;
1904
 
1905
        err = permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC), NULL);
1906
 
1907
        /* Allow read access to binaries even when mode 111 */
1908
        if (err == -EACCES && S_ISREG(inode->i_mode) &&
1909
            acc == (MAY_READ | MAY_OWNER_OVERRIDE))
1910
                err = permission(inode, MAY_EXEC, NULL);
1911
 
1912
        return err? nfserrno(err) : 0;
1913
}
1914
 
1915
void
1916
nfsd_racache_shutdown(void)
1917
{
1918
        if (!raparml)
1919
                return;
1920
        dprintk("nfsd: freeing readahead buffers.\n");
1921
        kfree(raparml);
1922
        raparml = NULL;
1923
}
1924
/*
1925
 * Initialize readahead param cache
1926
 */
1927
int
1928
nfsd_racache_init(int cache_size)
1929
{
1930
        int     i;
1931
        int     j = 0;
1932
        int     nperbucket;
1933
 
1934
 
1935
        if (raparml)
1936
                return 0;
1937
        if (cache_size < 2*RAPARM_HASH_SIZE)
1938
                cache_size = 2*RAPARM_HASH_SIZE;
1939
        raparml = kcalloc(cache_size, sizeof(struct raparms), GFP_KERNEL);
1940
 
1941
        if (!raparml) {
1942
                printk(KERN_WARNING
1943
                        "nfsd: Could not allocate memory read-ahead cache.\n");
1944
                return -ENOMEM;
1945
        }
1946
 
1947
        dprintk("nfsd: allocating %d readahead buffers.\n", cache_size);
1948
        for (i = 0 ; i < RAPARM_HASH_SIZE ; i++) {
1949
                raparm_hash[i].pb_head = NULL;
1950
                spin_lock_init(&raparm_hash[i].pb_lock);
1951
        }
1952
        nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE);
1953
        for (i = 0; i < cache_size - 1; i++) {
1954
                if (i % nperbucket == 0)
1955
                        raparm_hash[j++].pb_head = raparml + i;
1956
                if (i % nperbucket < nperbucket-1)
1957
                        raparml[i].p_next = raparml + i + 1;
1958
        }
1959
 
1960
        nfsdstats.ra_size = cache_size;
1961
        return 0;
1962
}
1963
 
1964
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
1965
struct posix_acl *
1966
nfsd_get_posix_acl(struct svc_fh *fhp, int type)
1967
{
1968
        struct inode *inode = fhp->fh_dentry->d_inode;
1969
        char *name;
1970
        void *value = NULL;
1971
        ssize_t size;
1972
        struct posix_acl *acl;
1973
 
1974
        if (!IS_POSIXACL(inode))
1975
                return ERR_PTR(-EOPNOTSUPP);
1976
 
1977
        switch (type) {
1978
        case ACL_TYPE_ACCESS:
1979
                name = POSIX_ACL_XATTR_ACCESS;
1980
                break;
1981
        case ACL_TYPE_DEFAULT:
1982
                name = POSIX_ACL_XATTR_DEFAULT;
1983
                break;
1984
        default:
1985
                return ERR_PTR(-EOPNOTSUPP);
1986
        }
1987
 
1988
        size = nfsd_getxattr(fhp->fh_dentry, name, &value);
1989
        if (size < 0)
1990
                return ERR_PTR(size);
1991
 
1992
        acl = posix_acl_from_xattr(value, size);
1993
        kfree(value);
1994
        return acl;
1995
}
1996
 
1997
int
1998
nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
1999
{
2000
        struct inode *inode = fhp->fh_dentry->d_inode;
2001
        char *name;
2002
        void *value = NULL;
2003
        size_t size;
2004
        int error;
2005
 
2006
        if (!IS_POSIXACL(inode) || !inode->i_op ||
2007
            !inode->i_op->setxattr || !inode->i_op->removexattr)
2008
                return -EOPNOTSUPP;
2009
        switch(type) {
2010
                case ACL_TYPE_ACCESS:
2011
                        name = POSIX_ACL_XATTR_ACCESS;
2012
                        break;
2013
                case ACL_TYPE_DEFAULT:
2014
                        name = POSIX_ACL_XATTR_DEFAULT;
2015
                        break;
2016
                default:
2017
                        return -EOPNOTSUPP;
2018
        }
2019
 
2020
        if (acl && acl->a_count) {
2021
                size = posix_acl_xattr_size(acl->a_count);
2022
                value = kmalloc(size, GFP_KERNEL);
2023
                if (!value)
2024
                        return -ENOMEM;
2025
                error = posix_acl_to_xattr(acl, value, size);
2026
                if (error < 0)
2027
                        goto getout;
2028
                size = error;
2029
        } else
2030
                size = 0;
2031
 
2032
        if (size)
2033
                error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
2034
        else {
2035
                if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
2036
                        error = 0;
2037
                else {
2038
                        error = vfs_removexattr(fhp->fh_dentry, name);
2039
                        if (error == -ENODATA)
2040
                                error = 0;
2041
                }
2042
        }
2043
 
2044
getout:
2045
        kfree(value);
2046
        return error;
2047
}
2048
#endif  /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */

powered by: WebSVN 2.1.0

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