^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * In-kernel MOUNT protocol client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/sunrpc/clnt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sunrpc/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define NFSDBG_FACILITY NFSDBG_MOUNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Defined by RFC 1094, section A.3; and RFC 1813, section 5.1.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define MNTPATHLEN (1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * XDR data type sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MNT_status_sz (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MNT_fhandle_sz XDR_QUADLEN(NFS2_FHSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MNT_fhandlev3_sz XDR_QUADLEN(NFS3_FHSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MNT_authflav3_sz (1 + NFS_MAX_SECFLAVORS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * XDR argument and result sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MNT_enc_dirpath_sz encode_dirpath_sz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MNT_dec_mountres_sz (MNT_status_sz + MNT_fhandle_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandlev3_sz + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MNT_authflav3_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Defined by RFC 1094, section A.5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) MOUNTPROC_NULL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) MOUNTPROC_MNT = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) MOUNTPROC_DUMP = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MOUNTPROC_UMNT = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) MOUNTPROC_UMNTALL = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MOUNTPROC_EXPORT = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Defined by RFC 1813, section 5.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) MOUNTPROC3_NULL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) MOUNTPROC3_MNT = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) MOUNTPROC3_DUMP = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) MOUNTPROC3_UMNT = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) MOUNTPROC3_UMNTALL = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) MOUNTPROC3_EXPORT = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const struct rpc_program mnt_program;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Defined by OpenGroup XNFS Version 3W, chapter 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) enum mountstat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MNT_OK = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MNT_EPERM = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MNT_ENOENT = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MNT_EACCES = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MNT_EINVAL = 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) } mnt_errtbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) { .status = MNT_OK, .errno = 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) { .status = MNT_EPERM, .errno = -EPERM, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) { .status = MNT_ENOENT, .errno = -ENOENT, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) { .status = MNT_EACCES, .errno = -EACCES, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) { .status = MNT_EINVAL, .errno = -EINVAL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Defined by RFC 1813, section 5.1.5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) enum mountstat3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) MNT3_OK = 0, /* no error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MNT3ERR_PERM = 1, /* Not owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) MNT3ERR_NOENT = 2, /* No such file or directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MNT3ERR_IO = 5, /* I/O error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MNT3ERR_ACCES = 13, /* Permission denied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MNT3ERR_NOTDIR = 20, /* Not a directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) MNT3ERR_INVAL = 22, /* Invalid argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) MNT3ERR_NAMETOOLONG = 63, /* Filename too long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) MNT3ERR_SERVERFAULT = 10006, /* A failure on the server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) } mnt3_errtbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) { .status = MNT3_OK, .errno = 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { .status = MNT3ERR_PERM, .errno = -EPERM, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { .status = MNT3ERR_NOENT, .errno = -ENOENT, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { .status = MNT3ERR_IO, .errno = -EIO, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { .status = MNT3ERR_ACCES, .errno = -EACCES, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { .status = MNT3ERR_NOTDIR, .errno = -ENOTDIR, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { .status = MNT3ERR_INVAL, .errno = -EINVAL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { .status = MNT3ERR_NAMETOOLONG, .errno = -ENAMETOOLONG, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { .status = MNT3ERR_NOTSUPP, .errno = -ENOTSUPP, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) { .status = MNT3ERR_SERVERFAULT, .errno = -EREMOTEIO, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct mountres {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct nfs_fh *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned int *auth_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) rpc_authflavor_t *auth_flavors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct mnt_fhstatus {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct nfs_fh *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * nfs_mount - Obtain an NFS file handle for the given host and path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @info: pointer to mount request arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Uses default timeout parameters specified by underlying transport. On
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * successful return, the auth_flavs list and auth_flav_len will be populated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * with the list from the server or a faked-up list if the server didn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * provide one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int nfs_mount(struct nfs_mount_request *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct mountres result = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .fh = info->fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .auth_count = info->auth_flav_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .auth_flavors = info->auth_flavs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .rpc_argp = info->dirpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .rpc_resp = &result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct rpc_create_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .net = info->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .protocol = info->protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .address = info->sap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .addrsize = info->salen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .servername = info->hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .program = &mnt_program,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .version = info->version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .authflavor = RPC_AUTH_UNIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .cred = current_cred(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct rpc_clnt *mnt_clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dprintk("NFS: sending MNT request for %s:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) (info->hostname ? info->hostname : "server"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) info->dirpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (strlen(info->dirpath) > MNTPATHLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (info->noresvport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) mnt_clnt = rpc_create(&args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (IS_ERR(mnt_clnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) goto out_clnt_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (info->version == NFS_MNT3_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rpc_shutdown_client(mnt_clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto out_call_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (result.errno != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) goto out_mnt_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dprintk("NFS: MNT request succeeded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * If the server didn't provide a flavor list, allow the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * client to try any flavor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (info->version != NFS_MNT3_VERSION || *info->auth_flav_len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dprintk("NFS: Faking up auth_flavs list\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) info->auth_flavs[0] = RPC_AUTH_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *info->auth_flav_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) out_clnt_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) status = PTR_ERR(mnt_clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dprintk("NFS: failed to create MNT RPC client, status=%d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) out_call_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dprintk("NFS: MNT request failed, status=%d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) out_mnt_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dprintk("NFS: MNT server returned result %d\n", result.errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) status = result.errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * nfs_umount - Notify a server that we have unmounted this export
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @info: pointer to umount request arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * MOUNTPROC_UMNT is advisory, so we set a short timeout, and always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * use UDP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void nfs_umount(const struct nfs_mount_request *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static const struct rpc_timeout nfs_umnt_timeout = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .to_initval = 1 * HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .to_maxval = 3 * HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .to_retries = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct rpc_create_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .net = info->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .protocol = IPPROTO_UDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .address = info->sap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .addrsize = info->salen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .timeout = &nfs_umnt_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .servername = info->hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .program = &mnt_program,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .version = info->version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .authflavor = RPC_AUTH_UNIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .flags = RPC_CLNT_CREATE_NOPING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .cred = current_cred(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .rpc_argp = info->dirpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct rpc_clnt *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (strlen(info->dirpath) > MNTPATHLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (info->noresvport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) clnt = rpc_create(&args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (IS_ERR(clnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto out_clnt_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dprintk("NFS: sending UMNT request for %s:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) (info->hostname ? info->hostname : "server"), info->dirpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (info->version == NFS_MNT3_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) msg.rpc_proc = &clnt->cl_procinfo[MOUNTPROC3_UMNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) msg.rpc_proc = &clnt->cl_procinfo[MOUNTPROC_UMNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) status = rpc_call_sync(clnt, &msg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) rpc_shutdown_client(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (unlikely(status < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) goto out_call_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) out_clnt_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dprintk("NFS: failed to create UMNT RPC client, status=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) PTR_ERR(clnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) out_call_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dprintk("NFS: UMNT request failed, status=%d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * XDR encode/decode functions for MOUNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) const u32 pathname_len = strlen(pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) p = xdr_reserve_space(xdr, 4 + pathname_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) xdr_encode_opaque(p, pathname, pathname_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void mnt_xdr_enc_dirpath(struct rpc_rqst *req, struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) const void *dirpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) encode_mntdirpath(xdr, dirpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * RFC 1094: "A non-zero status indicates some sort of error. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * case, the status is a UNIX error number." This can be problematic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * if the server and client use different errno values for the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * However, the OpenGroup XNFS spec provides a simple mapping that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * independent of local errno values on the server and the client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int decode_status(struct xdr_stream *xdr, struct mountres *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) p = xdr_inline_decode(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (unlikely(p == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) status = be32_to_cpup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) for (i = 0; i < ARRAY_SIZE(mnt_errtbl); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (mnt_errtbl[i].status == status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) res->errno = mnt_errtbl[i].errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) dprintk("NFS: unrecognized MNT status code: %u\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) res->errno = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct nfs_fh *fh = res->fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) p = xdr_inline_decode(xdr, NFS2_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (unlikely(p == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) fh->size = NFS2_FHSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) memcpy(fh->data, p, NFS2_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int mnt_xdr_dec_mountres(struct rpc_rqst *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct mountres *res = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) status = decode_status(xdr, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (unlikely(status != 0 || res->errno != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return decode_fhandle(xdr, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) p = xdr_inline_decode(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (unlikely(p == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) status = be32_to_cpup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) for (i = 0; i < ARRAY_SIZE(mnt3_errtbl); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (mnt3_errtbl[i].status == status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) res->errno = mnt3_errtbl[i].errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dprintk("NFS: unrecognized MNT3 status code: %u\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) res->errno = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int decode_fhandle3(struct xdr_stream *xdr, struct mountres *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct nfs_fh *fh = res->fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) p = xdr_inline_decode(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (unlikely(p == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) size = be32_to_cpup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (size > NFS3_FHSIZE || size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) p = xdr_inline_decode(xdr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (unlikely(p == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) fh->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) memcpy(fh->data, p, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) rpc_authflavor_t *flavors = res->auth_flavors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) unsigned int *count = res->auth_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) u32 entries, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (*count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) p = xdr_inline_decode(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (unlikely(p == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) entries = be32_to_cpup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dprintk("NFS: received %u auth flavors\n", entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (entries > NFS_MAX_SECFLAVORS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) entries = NFS_MAX_SECFLAVORS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) p = xdr_inline_decode(xdr, 4 * entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (unlikely(p == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (entries > *count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) entries = *count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) for (i = 0; i < entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) flavors[i] = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dprintk("NFS: auth flavor[%u]: %d\n", i, flavors[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) *count = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int mnt_xdr_dec_mountres3(struct rpc_rqst *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct xdr_stream *xdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct mountres *res = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) status = decode_fhs_status(xdr, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (unlikely(status != 0 || res->errno != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) status = decode_fhandle3(xdr, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (unlikely(status != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) res->errno = -EBADHANDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return decode_auth_flavors(xdr, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static const struct rpc_procinfo mnt_procedures[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) [MOUNTPROC_MNT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .p_proc = MOUNTPROC_MNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .p_encode = mnt_xdr_enc_dirpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .p_decode = mnt_xdr_dec_mountres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .p_arglen = MNT_enc_dirpath_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .p_replen = MNT_dec_mountres_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .p_statidx = MOUNTPROC_MNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .p_name = "MOUNT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) [MOUNTPROC_UMNT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .p_proc = MOUNTPROC_UMNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .p_encode = mnt_xdr_enc_dirpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .p_arglen = MNT_enc_dirpath_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .p_statidx = MOUNTPROC_UMNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .p_name = "UMOUNT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static const struct rpc_procinfo mnt3_procedures[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) [MOUNTPROC3_MNT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .p_proc = MOUNTPROC3_MNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .p_encode = mnt_xdr_enc_dirpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .p_decode = mnt_xdr_dec_mountres3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .p_arglen = MNT_enc_dirpath_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .p_replen = MNT_dec_mountres3_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .p_statidx = MOUNTPROC3_MNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .p_name = "MOUNT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) [MOUNTPROC3_UMNT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .p_proc = MOUNTPROC3_UMNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .p_encode = mnt_xdr_enc_dirpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .p_arglen = MNT_enc_dirpath_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .p_statidx = MOUNTPROC3_UMNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .p_name = "UMOUNT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static unsigned int mnt_counts[ARRAY_SIZE(mnt_procedures)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static const struct rpc_version mnt_version1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .number = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .nrprocs = ARRAY_SIZE(mnt_procedures),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .procs = mnt_procedures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .counts = mnt_counts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static unsigned int mnt3_counts[ARRAY_SIZE(mnt3_procedures)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static const struct rpc_version mnt_version3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .number = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .nrprocs = ARRAY_SIZE(mnt3_procedures),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .procs = mnt3_procedures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .counts = mnt3_counts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static const struct rpc_version *mnt_version[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) &mnt_version1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) &mnt_version3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static struct rpc_stat mnt_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static const struct rpc_program mnt_program = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .name = "mount",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .number = NFS_MNT_PROGRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .nrvers = ARRAY_SIZE(mnt_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .version = mnt_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .stats = &mnt_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) };