b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) * Process version 2 NFS requests.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8) #include <linux/namei.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9)
9a74af21330c8 (Boaz Harrosh 2009-12-03 20:30:56 +0200 10) #include "cache.h"
9a74af21330c8 (Boaz Harrosh 2009-12-03 20:30:56 +0200 11) #include "xdr.h"
0a3adadee42f2 (J. Bruce Fields 2009-11-04 18:12:35 -0500 12) #include "vfs.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14) #define NFSDDBG_FACILITY NFSDDBG_PROC
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 15)
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 16) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 17) nfsd_proc_null(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) {
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 19) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 20) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) * Get a file's attributes
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24) * N.B. After this call resp->fh needs an fh_put
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 26) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 27) nfsd_proc_getattr(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 29) struct nfsd_fhandle *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 30) struct nfsd_attrstat *resp = rqstp->rq_resp;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 31)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 32) dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 33)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 34) fh_copy(&resp->fh, &argp->fh);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 35) resp->status = fh_verify(rqstp, &resp->fh, 0,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 36) NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 37) if (resp->status != nfs_ok)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 38) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 39) resp->status = fh_getattr(&resp->fh, &resp->stat);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 40) out:
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 41) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 44) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 45) * Set a file's attributes
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 46) * N.B. After this call resp->fh needs an fh_put
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 47) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 48) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 49) nfsd_proc_setattr(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 50) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 51) struct nfsd_sattrargs *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 52) struct nfsd_attrstat *resp = rqstp->rq_resp;
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 53) struct iattr *iap = &argp->attrs;
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 54) struct svc_fh *fhp;
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 55)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 56) dprintk("nfsd: SETATTR %s, valid=%x, size=%ld\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 57) SVCFH_fmt(&argp->fh),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 58) argp->attrs.ia_valid, (long) argp->attrs.ia_size);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 59)
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 60) fhp = fh_copy(&resp->fh, &argp->fh);
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 61)
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 62) /*
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 63) * NFSv2 does not differentiate between "set-[ac]time-to-now"
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 64) * which only requires access, and "set-[ac]time-to-X" which
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 65) * requires ownership.
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 66) * So if it looks like it might be "set both to the same time which
31051c85b5e2a (Jan Kara 2016-05-26 16:55:18 +0200 67) * is close to now", and if setattr_prepare fails, then we
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 68) * convert to "set to now" instead of "set to explicit time"
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 69) *
31051c85b5e2a (Jan Kara 2016-05-26 16:55:18 +0200 70) * We only call setattr_prepare as the last test as technically
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 71) * it is not an interface that we should be using.
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 72) */
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 73) #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 74) #define MAX_TOUCH_TIME_ERROR (30*60)
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 75) if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET &&
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 76) iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) {
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 77) /*
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 78) * Looks probable.
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 79) *
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 80) * Now just make sure time is in the right ballpark.
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 81) * Solaris, at least, doesn't seem to care what the time
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 82) * request is. We require it be within 30 minutes of now.
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 83) */
b6356d420296e (Arnd Bergmann 2019-11-03 18:06:52 +0100 84) time64_t delta = iap->ia_atime.tv_sec - ktime_get_real_seconds();
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 85)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 86) resp->status = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 87) if (resp->status != nfs_ok)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 88) goto out;
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 89)
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 90) if (delta < 0)
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 91) delta = -delta;
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 92) if (delta < MAX_TOUCH_TIME_ERROR &&
2f221d6f7b881 (Christian Brauner 2021-01-21 14:19:26 +0100 93) setattr_prepare(&init_user_ns, fhp->fh_dentry, iap) != 0) {
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 94) /*
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 95) * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 96) * This will cause notify_change to set these times
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 97) * to "now"
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 98) */
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 99) iap->ia_valid &= ~BOTH_TIME_SET;
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 100) }
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 101) }
cc265089ce1b1 (Andreas Gruenbacher 2015-05-09 00:37:57 +0200 102)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 103) resp->status = nfsd_setattr(rqstp, fhp, iap, 0, (time64_t)0);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 104) if (resp->status != nfs_ok)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 105) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 106)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 107) resp->status = fh_getattr(&resp->fh, &resp->stat);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 108) out:
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 109) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 110) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 111)
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 112) /* Obsolete, replaced by MNTPROC_MNT. */
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 113) static __be32
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 114) nfsd_proc_root(struct svc_rqst *rqstp)
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 115) {
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 116) return rpc_success;
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 117) }
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 118)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 119) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 120) * Look up a path name component
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 121) * Note: the dentry in the resp->fh may be negative if the file
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 122) * doesn't exist yet.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 123) * N.B. After this call resp->fh needs an fh_put
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 124) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 125) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 126) nfsd_proc_lookup(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 127) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 128) struct nfsd_diropargs *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 129) struct nfsd_diropres *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 130)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 131) dprintk("nfsd: LOOKUP %s %.*s\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 132) SVCFH_fmt(&argp->fh), argp->len, argp->name);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 133)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 134) fh_init(&resp->fh, NFS_FHSIZE);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 135) resp->status = nfsd_lookup(rqstp, &argp->fh, argp->name, argp->len,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 136) &resp->fh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 137) fh_put(&argp->fh);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 138) if (resp->status != nfs_ok)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 139) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 140)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 141) resp->status = fh_getattr(&resp->fh, &resp->stat);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 142) out:
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 143) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 144) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 145)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 146) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 147) * Read a symlink.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 148) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 149) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 150) nfsd_proc_readlink(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 151) {
1fcbd1c9456ba (Chuck Lever 2020-10-21 12:21:25 -0400 152) struct nfsd_fhandle *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 153) struct nfsd_readlinkres *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 154)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 155) dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 156)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 157) /* Read the symlink. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 158) resp->len = NFS_MAXPATHLEN;
d9014b0f8fae1 (Chuck Lever 2020-10-23 15:41:09 -0400 159) resp->page = *(rqstp->rq_next_page++);
d9014b0f8fae1 (Chuck Lever 2020-10-23 15:41:09 -0400 160) resp->status = nfsd_readlink(rqstp, &argp->fh,
d9014b0f8fae1 (Chuck Lever 2020-10-23 15:41:09 -0400 161) page_address(resp->page), &resp->len);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 162)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 163) fh_put(&argp->fh);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 164) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 165) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 166)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 167) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 168) * Read a portion of a file.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 169) * N.B. After this call resp->fh needs an fh_put
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 170) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 171) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 172) nfsd_proc_read(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 173) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 174) struct nfsd_readargs *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 175) struct nfsd_readres *resp = rqstp->rq_resp;
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 176) unsigned int len;
83a63072c815e (Trond Myklebust 2019-08-26 13:03:11 -0400 177) u32 eof;
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 178) int v;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 179)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 180) dprintk("nfsd: READ %s %d bytes at %d\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 181) SVCFH_fmt(&argp->fh),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 182) argp->count, argp->offset);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 183)
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 184) argp->count = min_t(u32, argp->count, NFSSVC_MAXBLKSIZE_V2);
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 185)
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 186) v = 0;
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 187) len = argp->count;
a6f8d9dc9e44b (Chuck Lever 2020-10-23 16:40:11 -0400 188) resp->pages = rqstp->rq_next_page;
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 189) while (len > 0) {
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 190) struct page *page = *(rqstp->rq_next_page++);
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 191)
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 192) rqstp->rq_vec[v].iov_base = page_address(page);
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 193) rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 194) len -= rqstp->rq_vec[v].iov_len;
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 195) v++;
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 196) }
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 197)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 198) /* Obtain buffer pointer for payload. 19 is 1 word for
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 199) * status, 17 words for fattr, and 1 word for the byte count.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 200) */
cd123012d99fd (Jeff Layton 2007-05-09 02:34:50 -0700 201) svc_reserve_auth(rqstp, (19<<2) + argp->count + 4);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 202)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 203) resp->count = argp->count;
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 204) fh_copy(&resp->fh, &argp->fh);
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 205) resp->status = nfsd_read(rqstp, &resp->fh, argp->offset,
8c293ef993c8d (Chuck Lever 2020-10-21 12:15:51 -0400 206) rqstp->rq_vec, v, &resp->count, &eof);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 207) if (resp->status == nfs_ok)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 208) resp->status = fh_getattr(&resp->fh, &resp->stat);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 209) else if (resp->status == nfserr_jukebox)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 210) return rpc_drop_reply;
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 211) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 212) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 213)
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 214) /* Reserved */
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 215) static __be32
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 216) nfsd_proc_writecache(struct svc_rqst *rqstp)
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 217) {
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 218) return rpc_success;
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 219) }
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 220)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 221) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 222) * Write data to a file
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 223) * N.B. After this call resp->fh needs an fh_put
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 224) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 225) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 226) nfsd_proc_write(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 227) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 228) struct nfsd_writeargs *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 229) struct nfsd_attrstat *resp = rqstp->rq_resp;
31dec2538e45e (David Shaw 2009-03-05 20:16:14 -0500 230) unsigned long cnt = argp->len;
8154ef2776aa5 (Chuck Lever 2018-03-27 10:54:07 -0400 231) unsigned int nvecs;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 232)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 233) dprintk("nfsd: WRITE %s %d bytes at %d\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 234) SVCFH_fmt(&argp->fh),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 235) argp->len, argp->offset);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 236)
3fd9557aec919 (Chuck Lever 2018-07-27 11:19:05 -0400 237) nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
3fd9557aec919 (Chuck Lever 2018-07-27 11:19:05 -0400 238) &argp->first, cnt);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 239) if (!nvecs) {
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 240) resp->status = nfserr_io;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 241) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 242) }
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 243)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 244) resp->status = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 245) argp->offset, rqstp->rq_vec, nvecs,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 246) &cnt, NFS_DATA_SYNC, NULL);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 247) if (resp->status == nfs_ok)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 248) resp->status = fh_getattr(&resp->fh, &resp->stat);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 249) else if (resp->status == nfserr_jukebox)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 250) return rpc_drop_reply;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 251) out:
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 252) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 253) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 254)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 255) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 256) * CREATE processing is complicated. The keyword here is `overloaded.'
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 257) * The parent directory is kept locked between the check for existence
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 258) * and the actual create() call in compliance with VFS protocols.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 259) * N.B. After this call _both_ argp->fh and resp->fh need an fh_put
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 260) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 261) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 262) nfsd_proc_create(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 263) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 264) struct nfsd_createargs *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 265) struct nfsd_diropres *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 266) svc_fh *dirfhp = &argp->fh;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 267) svc_fh *newfhp = &resp->fh;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 268) struct iattr *attr = &argp->attrs;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 269) struct inode *inode;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 270) struct dentry *dchild;
c4d987ba841df (Al Viro 2006-10-19 23:29:00 -0700 271) int type, mode;
4a55c1017b8dc (Jan Kara 2012-06-12 16:20:33 +0200 272) int hosterr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 273) dev_t rdev = 0, wanted = new_decode_dev(attr->ia_size);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 274)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 275) dprintk("nfsd: CREATE %s %.*s\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 276) SVCFH_fmt(dirfhp), argp->len, argp->name);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 277)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 278) /* First verify the parent file handle */
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 279) resp->status = fh_verify(rqstp, dirfhp, S_IFDIR, NFSD_MAY_EXEC);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 280) if (resp->status != nfs_ok)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 281) goto done; /* must fh_put dirfhp even on error */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 282)
8837abcab3d16 (Miklos Szeredi 2008-06-16 13:20:29 +0200 283) /* Check for NFSD_MAY_WRITE in nfsd_create if necessary */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 284)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 285) resp->status = nfserr_exist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 286) if (isdotent(argp->name, argp->len))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 287) goto done;
4a55c1017b8dc (Jan Kara 2012-06-12 16:20:33 +0200 288) hosterr = fh_want_write(dirfhp);
4a55c1017b8dc (Jan Kara 2012-06-12 16:20:33 +0200 289) if (hosterr) {
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 290) resp->status = nfserrno(hosterr);
4a55c1017b8dc (Jan Kara 2012-06-12 16:20:33 +0200 291) goto done;
4a55c1017b8dc (Jan Kara 2012-06-12 16:20:33 +0200 292) }
4a55c1017b8dc (Jan Kara 2012-06-12 16:20:33 +0200 293)
7ed94296a660a (NeilBrown 2006-10-04 02:15:43 -0700 294) fh_lock_nested(dirfhp, I_MUTEX_PARENT);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 295) dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 296) if (IS_ERR(dchild)) {
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 297) resp->status = nfserrno(PTR_ERR(dchild));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 298) goto out_unlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 299) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 300) fh_init(newfhp, NFS_FHSIZE);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 301) resp->status = fh_compose(newfhp, dirfhp->fh_export, dchild, dirfhp);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 302) if (!resp->status && d_really_is_negative(dchild))
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 303) resp->status = nfserr_noent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 304) dput(dchild);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 305) if (resp->status) {
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 306) if (resp->status != nfserr_noent)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 307) goto out_unlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 308) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 309) * If the new file handle wasn't verified, we can't tell
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 310) * whether the file exists or not. Time to bail ...
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 311) */
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 312) resp->status = nfserr_acces;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 313) if (!newfhp->fh_dentry) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 314) printk(KERN_WARNING
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 315) "nfsd_proc_create: file handle not verified\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 316) goto out_unlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 317) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 318) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 319)
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 320) inode = d_inode(newfhp->fh_dentry);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 321)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 322) /* Unfudge the mode bits */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 323) if (attr->ia_valid & ATTR_MODE) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 324) type = attr->ia_mode & S_IFMT;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 325) mode = attr->ia_mode & ~S_IFMT;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 326) if (!type) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 327) /* no type, so if target exists, assume same as that,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 328) * else assume a file */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 329) if (inode) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 330) type = inode->i_mode & S_IFMT;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 331) switch(type) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 332) case S_IFCHR:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 333) case S_IFBLK:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 334) /* reserve rdev for later checking */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 335) rdev = inode->i_rdev;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 336) attr->ia_valid |= ATTR_SIZE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 337)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 338) fallthrough;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 339) case S_IFIFO:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 340) /* this is probably a permission check..
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 341) * at least IRIX implements perm checking on
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 342) * echo thing > device-special-file-or-pipe
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 343) * by doing a CREATE with type==0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 344) */
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 345) resp->status = nfsd_permission(rqstp,
0ec757df97430 (J. Bruce Fields 2007-07-17 04:04:48 -0700 346) newfhp->fh_export,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 347) newfhp->fh_dentry,
8837abcab3d16 (Miklos Szeredi 2008-06-16 13:20:29 +0200 348) NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 349) if (resp->status && resp->status != nfserr_rofs)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 350) goto out_unlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 351) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 352) } else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 353) type = S_IFREG;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 354) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 355) } else if (inode) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 356) type = inode->i_mode & S_IFMT;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 357) mode = inode->i_mode & ~S_IFMT;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 358) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 359) type = S_IFREG;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 360) mode = 0; /* ??? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 361) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 362)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 363) attr->ia_valid |= ATTR_MODE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 364) attr->ia_mode = mode;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 365)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 366) /* Special treatment for non-regular files according to the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 367) * gospel of sun micro
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 368) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 369) if (type != S_IFREG) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 370) if (type != S_IFBLK && type != S_IFCHR) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 371) rdev = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 372) } else if (type == S_IFCHR && !(attr->ia_valid & ATTR_SIZE)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 373) /* If you think you've seen the worst, grok this. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 374) type = S_IFIFO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 375) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 376) /* Okay, char or block special */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 377) if (!rdev)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 378) rdev = wanted;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 379) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 380)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 381) /* we've used the SIZE information, so discard it */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 382) attr->ia_valid &= ~ATTR_SIZE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 383)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 384) /* Make sure the type and device matches */
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 385) resp->status = nfserr_exist;
6e3e2c4362e41 (Al Viro 2021-03-01 20:37:10 -0500 386) if (inode && inode_wrong_type(inode, type))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 387) goto out_unlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 388) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 389)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 390) resp->status = nfs_ok;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 391) if (!inode) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 392) /* File doesn't exist. Create it and set attrs */
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 393) resp->status = nfsd_create_locked(rqstp, dirfhp, argp->name,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 394) argp->len, attr, type, rdev,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 395) newfhp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 396) } else if (type == S_IFREG) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 397) dprintk("nfsd: existing %s, valid=%x, size=%ld\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 398) argp->name, attr->ia_valid, (long) attr->ia_size);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 399) /* File already exists. We ignore all attributes except
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 400) * size, so that creat() behaves exactly like
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 401) * open(..., O_CREAT|O_TRUNC|O_WRONLY).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 402) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 403) attr->ia_valid &= ATTR_SIZE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 404) if (attr->ia_valid)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 405) resp->status = nfsd_setattr(rqstp, newfhp, attr, 0,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 406) (time64_t)0);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 407) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 408)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 409) out_unlock:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 410) /* We don't really need to unlock, as fh_put does it. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 411) fh_unlock(dirfhp);
4a55c1017b8dc (Jan Kara 2012-06-12 16:20:33 +0200 412) fh_drop_write(dirfhp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 413) done:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 414) fh_put(dirfhp);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 415) if (resp->status != nfs_ok)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 416) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 417) resp->status = fh_getattr(&resp->fh, &resp->stat);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 418) out:
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 419) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 420) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 421)
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 422) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 423) nfsd_proc_remove(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 424) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 425) struct nfsd_diropargs *argp = rqstp->rq_argp;
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 426) struct nfsd_stat *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 427)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 428) dprintk("nfsd: REMOVE %s %.*s\n", SVCFH_fmt(&argp->fh),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 429) argp->len, argp->name);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 430)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 431) /* Unlink. -SIFDIR means file must not be a directory */
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 432) resp->status = nfsd_unlink(rqstp, &argp->fh, -S_IFDIR,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 433) argp->name, argp->len);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 434) fh_put(&argp->fh);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 435) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 436) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 437)
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 438) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 439) nfsd_proc_rename(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 440) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 441) struct nfsd_renameargs *argp = rqstp->rq_argp;
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 442) struct nfsd_stat *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 443)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 444) dprintk("nfsd: RENAME %s %.*s -> \n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 445) SVCFH_fmt(&argp->ffh), argp->flen, argp->fname);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 446) dprintk("nfsd: -> %s %.*s\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 447) SVCFH_fmt(&argp->tfh), argp->tlen, argp->tname);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 448)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 449) resp->status = nfsd_rename(rqstp, &argp->ffh, argp->fname, argp->flen,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 450) &argp->tfh, argp->tname, argp->tlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 451) fh_put(&argp->ffh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 452) fh_put(&argp->tfh);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 453) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 454) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 455)
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 456) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 457) nfsd_proc_link(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 458) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 459) struct nfsd_linkargs *argp = rqstp->rq_argp;
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 460) struct nfsd_stat *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 461)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 462) dprintk("nfsd: LINK %s ->\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 463) SVCFH_fmt(&argp->ffh));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 464) dprintk("nfsd: %s %.*s\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 465) SVCFH_fmt(&argp->tfh),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 466) argp->tlen,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 467) argp->tname);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 468)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 469) resp->status = nfsd_link(rqstp, &argp->tfh, argp->tname, argp->tlen,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 470) &argp->ffh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 471) fh_put(&argp->ffh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 472) fh_put(&argp->tfh);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 473) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 474) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 475)
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 476) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 477) nfsd_proc_symlink(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 478) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 479) struct nfsd_symlinkargs *argp = rqstp->rq_argp;
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 480) struct nfsd_stat *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 481) struct svc_fh newfh;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 482)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 483) if (argp->tlen > NFS_MAXPATHLEN) {
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 484) resp->status = nfserr_nametoolong;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 485) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 486) }
38a70315599de (Chuck Lever 2018-03-27 10:54:21 -0400 487)
38a70315599de (Chuck Lever 2018-03-27 10:54:21 -0400 488) argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
11b4d66ea3313 (Chuck Lever 2018-07-27 11:19:10 -0400 489) page_address(rqstp->rq_arg.pages[0]),
38a70315599de (Chuck Lever 2018-03-27 10:54:21 -0400 490) argp->tlen);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 491) if (IS_ERR(argp->tname)) {
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 492) resp->status = nfserrno(PTR_ERR(argp->tname));
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 493) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 494) }
38a70315599de (Chuck Lever 2018-03-27 10:54:21 -0400 495)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 496) dprintk("nfsd: SYMLINK %s %.*s -> %.*s\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 497) SVCFH_fmt(&argp->ffh), argp->flen, argp->fname,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 498) argp->tlen, argp->tname);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 499)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 500) fh_init(&newfh, NFS_FHSIZE);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 501) resp->status = nfsd_symlink(rqstp, &argp->ffh, argp->fname, argp->flen,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 502) argp->tname, &newfh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 503)
11b4d66ea3313 (Chuck Lever 2018-07-27 11:19:10 -0400 504) kfree(argp->tname);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 505) fh_put(&argp->ffh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 506) fh_put(&newfh);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 507) out:
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 508) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 509) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 510)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 511) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 512) * Make directory. This operation is not idempotent.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 513) * N.B. After this call resp->fh needs an fh_put
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 514) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 515) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 516) nfsd_proc_mkdir(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 517) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 518) struct nfsd_createargs *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 519) struct nfsd_diropres *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 520)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 521) dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 522)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 523) if (resp->fh.fh_dentry) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 524) printk(KERN_WARNING
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 525) "nfsd_proc_mkdir: response already verified??\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 526) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 527)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 528) argp->attrs.ia_valid &= ~ATTR_SIZE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 529) fh_init(&resp->fh, NFS_FHSIZE);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 530) resp->status = nfsd_create(rqstp, &argp->fh, argp->name, argp->len,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 531) &argp->attrs, S_IFDIR, 0, &resp->fh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 532) fh_put(&argp->fh);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 533) if (resp->status != nfs_ok)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 534) goto out;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 535)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 536) resp->status = fh_getattr(&resp->fh, &resp->stat);
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 537) out:
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 538) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 539) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 540)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 541) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 542) * Remove a directory
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 543) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 544) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 545) nfsd_proc_rmdir(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 546) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 547) struct nfsd_diropargs *argp = rqstp->rq_argp;
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 548) struct nfsd_stat *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 549)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 550) dprintk("nfsd: RMDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 551)
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 552) resp->status = nfsd_unlink(rqstp, &argp->fh, S_IFDIR,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 553) argp->name, argp->len);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 554) fh_put(&argp->fh);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 555) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 556) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 557)
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 558) static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp,
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 559) struct nfsd_readdirres *resp,
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 560) int count)
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 561) {
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 562) struct xdr_buf *buf = &resp->dirlist;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 563) struct xdr_stream *xdr = &resp->xdr;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 564)
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 565) count = min_t(u32, count, PAGE_SIZE);
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 566)
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 567) memset(buf, 0, sizeof(*buf));
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 568)
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 569) /* Reserve room for the NULL ptr & eof flag (-2 words) */
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 570) buf->buflen = count - sizeof(__be32) * 2;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 571) buf->pages = rqstp->rq_next_page;
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 572) rqstp->rq_next_page++;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 573)
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 574) /* This is xdr_init_encode(), but it assumes that
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 575) * the head kvec has already been consumed. */
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 576) xdr_set_scratch_buffer(xdr, NULL, 0);
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 577) xdr->buf = buf;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 578) xdr->page_ptr = buf->pages;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 579) xdr->iov = NULL;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 580) xdr->p = page_address(*buf->pages);
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 581) xdr->end = xdr->p + (PAGE_SIZE >> 2);
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 582) xdr->rqst = NULL;
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 583) }
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 584)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 585) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 586) * Read a portion of a directory.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 587) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 588) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 589) nfsd_proc_readdir(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 590) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 591) struct nfsd_readdirargs *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 592) struct nfsd_readdirres *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 593) loff_t offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 594)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 595) dprintk("nfsd: READDIR %s %d bytes at %d\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 596) SVCFH_fmt(&argp->fh),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 597) argp->count, argp->cookie);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 598)
788cd46ecf83e (Chuck Lever 2020-11-13 17:03:49 -0500 599) nfsd_init_dirlist_pages(rqstp, resp, argp->count);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 600)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 601) resp->common.err = nfs_ok;
f5dcccd647da5 (Chuck Lever 2020-11-14 13:45:35 -0500 602) resp->cookie_offset = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 603) offset = argp->cookie;
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 604) resp->status = nfsd_readdir(rqstp, &argp->fh, &offset,
8a2cf9f5709cc (Chuck Lever 2020-11-15 14:30:13 -0500 605) &resp->common, nfssvc_encode_entry);
d52532002ffa2 (Chuck Lever 2020-11-13 16:53:17 -0500 606) nfssvc_encode_nfscookie(resp, offset);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 607)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 608) fh_put(&argp->fh);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 609) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 610) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 611)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 612) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 613) * Get file system info
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 614) */
7111c66e4e705 (Al Viro 2006-10-19 23:28:45 -0700 615) static __be32
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 616) nfsd_proc_statfs(struct svc_rqst *rqstp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 617) {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 618) struct nfsd_fhandle *argp = rqstp->rq_argp;
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 619) struct nfsd_statfsres *resp = rqstp->rq_resp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 620)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 621) dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 622)
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 623) resp->status = nfsd_statfs(rqstp, &argp->fh, &resp->stats,
f0af22101d907 (Chuck Lever 2020-10-01 18:59:49 -0400 624) NFSD_MAY_BYPASS_GSS_ON_ROOT);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 625) fh_put(&argp->fh);
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 626) return rpc_success;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 627) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 628)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 629) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 630) * NFSv2 Server procedures.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 631) * Only the results of non-idempotent operations are cached.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 632) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 633)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 634) #define ST 1 /* status */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 635) #define FH 8 /* filehandle */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 636) #define AT 18 /* attributes */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 637)
860bda29b99af (Christoph Hellwig 2017-05-12 16:11:49 +0200 638) static const struct svc_procedure nfsd_procedures2[18] = {
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 639) [NFSPROC_NULL] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 640) .pc_func = nfsd_proc_null,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 641) .pc_decode = nfssvc_decode_voidarg,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 642) .pc_encode = nfssvc_encode_voidres,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 643) .pc_argsize = sizeof(struct nfsd_voidargs),
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 644) .pc_ressize = sizeof(struct nfsd_voidres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 645) .pc_cachetype = RC_NOCACHE,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 646) .pc_xdrressize = 0,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 647) .pc_name = "NULL",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 648) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 649) [NFSPROC_GETATTR] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 650) .pc_func = nfsd_proc_getattr,
ebcd8e8b28535 (Chuck Lever 2020-10-21 12:14:23 -0400 651) .pc_decode = nfssvc_decode_fhandleargs,
92b54a4fa4224 (Chuck Lever 2020-10-23 15:28:59 -0400 652) .pc_encode = nfssvc_encode_attrstatres,
1841b9b61492e (Chuck Lever 2020-10-01 18:59:44 -0400 653) .pc_release = nfssvc_release_attrstat,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 654) .pc_argsize = sizeof(struct nfsd_fhandle),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 655) .pc_ressize = sizeof(struct nfsd_attrstat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 656) .pc_cachetype = RC_NOCACHE,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 657) .pc_xdrressize = ST+AT,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 658) .pc_name = "GETATTR",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 659) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 660) [NFSPROC_SETATTR] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 661) .pc_func = nfsd_proc_setattr,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 662) .pc_decode = nfssvc_decode_sattrargs,
92b54a4fa4224 (Chuck Lever 2020-10-23 15:28:59 -0400 663) .pc_encode = nfssvc_encode_attrstatres,
1841b9b61492e (Chuck Lever 2020-10-01 18:59:44 -0400 664) .pc_release = nfssvc_release_attrstat,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 665) .pc_argsize = sizeof(struct nfsd_sattrargs),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 666) .pc_ressize = sizeof(struct nfsd_attrstat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 667) .pc_cachetype = RC_REPLBUFF,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 668) .pc_xdrressize = ST+AT,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 669) .pc_name = "SETATTR",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 670) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 671) [NFSPROC_ROOT] = {
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 672) .pc_func = nfsd_proc_root,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 673) .pc_decode = nfssvc_decode_voidarg,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 674) .pc_encode = nfssvc_encode_voidres,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 675) .pc_argsize = sizeof(struct nfsd_voidargs),
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 676) .pc_ressize = sizeof(struct nfsd_voidres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 677) .pc_cachetype = RC_NOCACHE,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 678) .pc_xdrressize = 0,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 679) .pc_name = "ROOT",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 680) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 681) [NFSPROC_LOOKUP] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 682) .pc_func = nfsd_proc_lookup,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 683) .pc_decode = nfssvc_decode_diropargs,
63f8de37951a6 (Christoph Hellwig 2017-05-08 19:42:02 +0200 684) .pc_encode = nfssvc_encode_diropres,
1841b9b61492e (Chuck Lever 2020-10-01 18:59:44 -0400 685) .pc_release = nfssvc_release_diropres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 686) .pc_argsize = sizeof(struct nfsd_diropargs),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 687) .pc_ressize = sizeof(struct nfsd_diropres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 688) .pc_cachetype = RC_NOCACHE,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 689) .pc_xdrressize = ST+FH+AT,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 690) .pc_name = "LOOKUP",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 691) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 692) [NFSPROC_READLINK] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 693) .pc_func = nfsd_proc_readlink,
1fcbd1c9456ba (Chuck Lever 2020-10-21 12:21:25 -0400 694) .pc_decode = nfssvc_decode_fhandleargs,
63f8de37951a6 (Christoph Hellwig 2017-05-08 19:42:02 +0200 695) .pc_encode = nfssvc_encode_readlinkres,
1fcbd1c9456ba (Chuck Lever 2020-10-21 12:21:25 -0400 696) .pc_argsize = sizeof(struct nfsd_fhandle),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 697) .pc_ressize = sizeof(struct nfsd_readlinkres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 698) .pc_cachetype = RC_NOCACHE,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 699) .pc_xdrressize = ST+1+NFS_MAXPATHLEN/4,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 700) .pc_name = "READLINK",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 701) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 702) [NFSPROC_READ] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 703) .pc_func = nfsd_proc_read,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 704) .pc_decode = nfssvc_decode_readargs,
63f8de37951a6 (Christoph Hellwig 2017-05-08 19:42:02 +0200 705) .pc_encode = nfssvc_encode_readres,
1841b9b61492e (Chuck Lever 2020-10-01 18:59:44 -0400 706) .pc_release = nfssvc_release_readres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 707) .pc_argsize = sizeof(struct nfsd_readargs),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 708) .pc_ressize = sizeof(struct nfsd_readres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 709) .pc_cachetype = RC_NOCACHE,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 710) .pc_xdrressize = ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 711) .pc_name = "READ",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 712) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 713) [NFSPROC_WRITECACHE] = {
6b3dccd48de8a (Chuck Lever 2020-10-01 18:58:56 -0400 714) .pc_func = nfsd_proc_writecache,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 715) .pc_decode = nfssvc_decode_voidarg,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 716) .pc_encode = nfssvc_encode_voidres,
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 717) .pc_argsize = sizeof(struct nfsd_voidargs),
788f7183fba86 (Chuck Lever 2020-11-05 14:48:29 -0500 718) .pc_ressize = sizeof(struct nfsd_voidres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 719) .pc_cachetype = RC_NOCACHE,
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 720) .pc_xdrressize = 0,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 721) .pc_name = "WRITECACHE",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 722) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 723) [NFSPROC_WRITE] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 724) .pc_func = nfsd_proc_write,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 725) .pc_decode = nfssvc_decode_writeargs,
92b54a4fa4224 (Chuck Lever 2020-10-23 15:28:59 -0400 726) .pc_encode = nfssvc_encode_attrstatres,
1841b9b61492e (Chuck Lever 2020-10-01 18:59:44 -0400 727) .pc_release = nfssvc_release_attrstat,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 728) .pc_argsize = sizeof(struct nfsd_writeargs),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 729) .pc_ressize = sizeof(struct nfsd_attrstat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 730) .pc_cachetype = RC_REPLBUFF,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 731) .pc_xdrressize = ST+AT,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 732) .pc_name = "WRITE",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 733) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 734) [NFSPROC_CREATE] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 735) .pc_func = nfsd_proc_create,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 736) .pc_decode = nfssvc_decode_createargs,
63f8de37951a6 (Christoph Hellwig 2017-05-08 19:42:02 +0200 737) .pc_encode = nfssvc_encode_diropres,
1841b9b61492e (Chuck Lever 2020-10-01 18:59:44 -0400 738) .pc_release = nfssvc_release_diropres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 739) .pc_argsize = sizeof(struct nfsd_createargs),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 740) .pc_ressize = sizeof(struct nfsd_diropres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 741) .pc_cachetype = RC_REPLBUFF,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 742) .pc_xdrressize = ST+FH+AT,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 743) .pc_name = "CREATE",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 744) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 745) [NFSPROC_REMOVE] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 746) .pc_func = nfsd_proc_remove,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 747) .pc_decode = nfssvc_decode_diropargs,
a887eaed2a964 (Chuck Lever 2020-10-23 11:08:02 -0400 748) .pc_encode = nfssvc_encode_statres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 749) .pc_argsize = sizeof(struct nfsd_diropargs),
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 750) .pc_ressize = sizeof(struct nfsd_stat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 751) .pc_cachetype = RC_REPLSTAT,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 752) .pc_xdrressize = ST,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 753) .pc_name = "REMOVE",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 754) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 755) [NFSPROC_RENAME] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 756) .pc_func = nfsd_proc_rename,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 757) .pc_decode = nfssvc_decode_renameargs,
a887eaed2a964 (Chuck Lever 2020-10-23 11:08:02 -0400 758) .pc_encode = nfssvc_encode_statres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 759) .pc_argsize = sizeof(struct nfsd_renameargs),
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 760) .pc_ressize = sizeof(struct nfsd_stat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 761) .pc_cachetype = RC_REPLSTAT,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 762) .pc_xdrressize = ST,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 763) .pc_name = "RENAME",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 764) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 765) [NFSPROC_LINK] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 766) .pc_func = nfsd_proc_link,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 767) .pc_decode = nfssvc_decode_linkargs,
a887eaed2a964 (Chuck Lever 2020-10-23 11:08:02 -0400 768) .pc_encode = nfssvc_encode_statres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 769) .pc_argsize = sizeof(struct nfsd_linkargs),
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 770) .pc_ressize = sizeof(struct nfsd_stat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 771) .pc_cachetype = RC_REPLSTAT,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 772) .pc_xdrressize = ST,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 773) .pc_name = "LINK",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 774) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 775) [NFSPROC_SYMLINK] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 776) .pc_func = nfsd_proc_symlink,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 777) .pc_decode = nfssvc_decode_symlinkargs,
a887eaed2a964 (Chuck Lever 2020-10-23 11:08:02 -0400 778) .pc_encode = nfssvc_encode_statres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 779) .pc_argsize = sizeof(struct nfsd_symlinkargs),
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 780) .pc_ressize = sizeof(struct nfsd_stat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 781) .pc_cachetype = RC_REPLSTAT,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 782) .pc_xdrressize = ST,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 783) .pc_name = "SYMLINK",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 784) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 785) [NFSPROC_MKDIR] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 786) .pc_func = nfsd_proc_mkdir,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 787) .pc_decode = nfssvc_decode_createargs,
63f8de37951a6 (Christoph Hellwig 2017-05-08 19:42:02 +0200 788) .pc_encode = nfssvc_encode_diropres,
1841b9b61492e (Chuck Lever 2020-10-01 18:59:44 -0400 789) .pc_release = nfssvc_release_diropres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 790) .pc_argsize = sizeof(struct nfsd_createargs),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 791) .pc_ressize = sizeof(struct nfsd_diropres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 792) .pc_cachetype = RC_REPLBUFF,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 793) .pc_xdrressize = ST+FH+AT,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 794) .pc_name = "MKDIR",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 795) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 796) [NFSPROC_RMDIR] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 797) .pc_func = nfsd_proc_rmdir,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 798) .pc_decode = nfssvc_decode_diropargs,
a887eaed2a964 (Chuck Lever 2020-10-23 11:08:02 -0400 799) .pc_encode = nfssvc_encode_statres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 800) .pc_argsize = sizeof(struct nfsd_diropargs),
cc028a10a48c3 (Chuck Lever 2020-10-02 15:52:44 -0400 801) .pc_ressize = sizeof(struct nfsd_stat),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 802) .pc_cachetype = RC_REPLSTAT,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 803) .pc_xdrressize = ST,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 804) .pc_name = "RMDIR",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 805) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 806) [NFSPROC_READDIR] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 807) .pc_func = nfsd_proc_readdir,
026fec7e7c472 (Christoph Hellwig 2017-05-08 19:01:48 +0200 808) .pc_decode = nfssvc_decode_readdirargs,
63f8de37951a6 (Christoph Hellwig 2017-05-08 19:42:02 +0200 809) .pc_encode = nfssvc_encode_readdirres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 810) .pc_argsize = sizeof(struct nfsd_readdirargs),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 811) .pc_ressize = sizeof(struct nfsd_readdirres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 812) .pc_cachetype = RC_NOCACHE,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 813) .pc_name = "READDIR",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 814) },
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 815) [NFSPROC_STATFS] = {
a6beb73272b4c (Christoph Hellwig 2017-05-08 17:35:49 +0200 816) .pc_func = nfsd_proc_statfs,
ebcd8e8b28535 (Chuck Lever 2020-10-21 12:14:23 -0400 817) .pc_decode = nfssvc_decode_fhandleargs,
63f8de37951a6 (Christoph Hellwig 2017-05-08 19:42:02 +0200 818) .pc_encode = nfssvc_encode_statfsres,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 819) .pc_argsize = sizeof(struct nfsd_fhandle),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 820) .pc_ressize = sizeof(struct nfsd_statfsres),
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 821) .pc_cachetype = RC_NOCACHE,
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 822) .pc_xdrressize = ST+5,
2289e87b5951f (Chuck Lever 2020-09-17 17:22:49 -0400 823) .pc_name = "STATFS",
b9081d90f5b98 (Yu Zhiguo 2009-06-09 17:33:34 +0800 824) },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 825) };
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 826)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 827)
7fd38af9cae6a (Christoph Hellwig 2017-05-08 23:40:27 +0200 828) static unsigned int nfsd_count2[ARRAY_SIZE(nfsd_procedures2)];
e9679189e34b2 (Christoph Hellwig 2017-05-12 16:21:37 +0200 829) const struct svc_version nfsd_version2 = {
e9679189e34b2 (Christoph Hellwig 2017-05-12 16:21:37 +0200 830) .vs_vers = 2,
e9679189e34b2 (Christoph Hellwig 2017-05-12 16:21:37 +0200 831) .vs_nproc = 18,
e9679189e34b2 (Christoph Hellwig 2017-05-12 16:21:37 +0200 832) .vs_proc = nfsd_procedures2,
e9679189e34b2 (Christoph Hellwig 2017-05-12 16:21:37 +0200 833) .vs_count = nfsd_count2,
e9679189e34b2 (Christoph Hellwig 2017-05-12 16:21:37 +0200 834) .vs_dispatch = nfsd_dispatch,
e9679189e34b2 (Christoph Hellwig 2017-05-12 16:21:37 +0200 835) .vs_xdrsize = NFS2_SVC_XDRSIZE,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 836) };
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 837)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 838) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 839) * Map errnos to NFS errnos.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 840) */
63f103111fdfc (Al Viro 2006-10-19 23:28:54 -0700 841) __be32
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 842) nfserrno (int errno)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 843) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 844) static struct {
63f103111fdfc (Al Viro 2006-10-19 23:28:54 -0700 845) __be32 nfserr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 846) int syserr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 847) } nfs_errtbl[] = {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 848) { nfs_ok, 0 },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 849) { nfserr_perm, -EPERM },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 850) { nfserr_noent, -ENOENT },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 851) { nfserr_io, -EIO },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 852) { nfserr_nxio, -ENXIO },
62814d6a9bca1 (Jeff Layton 2014-07-03 15:15:54 -0400 853) { nfserr_fbig, -E2BIG },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 854) { nfserr_acces, -EACCES },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 855) { nfserr_exist, -EEXIST },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 856) { nfserr_xdev, -EXDEV },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 857) { nfserr_mlink, -EMLINK },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 858) { nfserr_nodev, -ENODEV },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 859) { nfserr_notdir, -ENOTDIR },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 860) { nfserr_isdir, -EISDIR },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 861) { nfserr_inval, -EINVAL },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 862) { nfserr_fbig, -EFBIG },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 863) { nfserr_nospc, -ENOSPC },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 864) { nfserr_rofs, -EROFS },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 865) { nfserr_mlink, -EMLINK },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 866) { nfserr_nametoolong, -ENAMETOOLONG },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 867) { nfserr_notempty, -ENOTEMPTY },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 868) #ifdef EDQUOT
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 869) { nfserr_dquot, -EDQUOT },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 870) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 871) { nfserr_stale, -ESTALE },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 872) { nfserr_jukebox, -ETIMEDOUT },
599eb3046a138 (NeilBrown 2008-06-19 10:11:09 +1000 873) { nfserr_jukebox, -ERESTARTSYS },
062304a815fe1 (J. Bruce Fields 2011-01-02 22:05:33 -0500 874) { nfserr_jukebox, -EAGAIN },
062304a815fe1 (J. Bruce Fields 2011-01-02 22:05:33 -0500 875) { nfserr_jukebox, -EWOULDBLOCK },
3beb6cd1d448e (J. Bruce Fields 2011-01-01 15:43:50 -0500 876) { nfserr_jukebox, -ENOMEM },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 877) { nfserr_io, -ETXTBSY },
a838cc49d9a7d (Andreas Gruenbacher 2005-06-22 17:16:24 +0000 878) { nfserr_notsupp, -EOPNOTSUPP },
b7aeda40d3010 (Dean Hildebrand 2008-12-15 19:40:15 +0200 879) { nfserr_toosmall, -ETOOSMALL },
f39bde24b275d (J. Bruce Fields 2009-09-27 14:41:43 -0400 880) { nfserr_serverfault, -ESERVERFAULT },
b3fbfe0e7a1d8 (Jeff Layton 2014-07-29 21:37:44 -0400 881) { nfserr_serverfault, -ENFILE },
42e616167abb7 (J. Bruce Fields 2016-10-04 13:57:43 -0400 882) { nfserr_io, -EUCLEAN },
c952cd4e949ab (Kinglong Mee 2017-03-10 09:52:20 +0800 883) { nfserr_perm, -ENOKEY },
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 884) };
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 885) int i;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 886)
63f103111fdfc (Al Viro 2006-10-19 23:28:54 -0700 887) for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 888) if (nfs_errtbl[i].syserr == errno)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 889) return nfs_errtbl[i].nfserr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 890) }
ff30f08c32f93 (J. Bruce Fields 2016-10-04 12:53:49 -0400 891) WARN_ONCE(1, "nfsd: non-standard errno: %d\n", errno);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 892) return nfserr_io;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 893) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 894)