^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/nfs/nfs4proc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Client-side procedure declarations for NFSv4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2002 The Regents of the University of Michigan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Kendrick Smith <kmsmith@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Andy Adamson <andros@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 3. Neither the name of the University nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/sunrpc/clnt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/nfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/nfs4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/nfs_page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/nfs_mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include "nfs4_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include "delegation.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include "iostat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "callback.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include "pnfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include "netns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include "sysfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include "nfs4idmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include "nfs4session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include "fscache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include "nfs42.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include "nfs4trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #ifdef CONFIG_NFS_V4_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include "nfs42.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #endif /* CONFIG_NFS_V4_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define NFSDBG_FACILITY NFSDBG_PROC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define NFS4_BITMASK_SZ 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define NFS4_POLL_RETRY_MIN (HZ/10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define NFS4_POLL_RETRY_MAX (15*HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* file attributes which can be mapped to nfs attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define NFS4_VALID_ATTRS (ATTR_MODE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) | ATTR_UID \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) | ATTR_GID \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) | ATTR_SIZE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) | ATTR_ATIME \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) | ATTR_MTIME \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) | ATTR_CTIME \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) | ATTR_ATIME_SET \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) | ATTR_MTIME_SET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct nfs4_opendata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct nfs_fattr *fattr, struct iattr *sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct nfs_open_context *ctx, struct nfs4_label *ilabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct nfs4_label *olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct nfs4_slot *slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) bool is_privileged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) const struct cred *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const struct cred *, bool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) const __u32 *src, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct nfs4_label *label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #ifdef CONFIG_NFS_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline struct nfs4_label *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct iattr *sattr, struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (label == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) err = security_dentry_init_security(dentry, sattr->ia_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) &dentry->d_name, (void **)&label->label, &label->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) nfs4_label_release_security(struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) security_release_secctx(label->label, label->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return server->attr_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return server->attr_bitmask_nl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static inline struct nfs4_label *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct iattr *sattr, struct nfs4_label *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) { return NULL; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) nfs4_label_release_security(struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { return; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static inline u32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) { return server->attr_bitmask; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Prevent leaks of NFSv4 errors into userland */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int nfs4_map_errors(int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (err >= -1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case -NFS4ERR_RESOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case -NFS4ERR_LAYOUTTRYLATER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case -NFS4ERR_RECALLCONFLICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case -NFS4ERR_WRONGSEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case -NFS4ERR_WRONG_CRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case -NFS4ERR_BADOWNER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case -NFS4ERR_BADNAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case -NFS4ERR_SHARE_DENIED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case -NFS4ERR_MINOR_VERS_MISMATCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case -NFS4ERR_FILE_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dprintk("%s could not handle NFSv4 error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) __func__, -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * This is our standard bitmap for GETATTR requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) const u32 nfs4_fattr_bitmap[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) FATTR4_WORD0_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) | FATTR4_WORD0_CHANGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) | FATTR4_WORD0_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) | FATTR4_WORD0_FSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) | FATTR4_WORD0_FILEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) FATTR4_WORD1_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) | FATTR4_WORD1_NUMLINKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) | FATTR4_WORD1_OWNER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) | FATTR4_WORD1_OWNER_GROUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) | FATTR4_WORD1_RAWDEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) | FATTR4_WORD1_SPACE_USED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) | FATTR4_WORD1_TIME_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) | FATTR4_WORD1_TIME_METADATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) | FATTR4_WORD1_TIME_MODIFY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) | FATTR4_WORD1_MOUNTED_ON_FILEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #ifdef CONFIG_NFS_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) FATTR4_WORD2_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static const u32 nfs4_pnfs_open_bitmap[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) FATTR4_WORD0_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) | FATTR4_WORD0_CHANGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) | FATTR4_WORD0_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) | FATTR4_WORD0_FSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) | FATTR4_WORD0_FILEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) FATTR4_WORD1_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) | FATTR4_WORD1_NUMLINKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) | FATTR4_WORD1_OWNER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) | FATTR4_WORD1_OWNER_GROUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) | FATTR4_WORD1_RAWDEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) | FATTR4_WORD1_SPACE_USED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) | FATTR4_WORD1_TIME_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) | FATTR4_WORD1_TIME_METADATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) | FATTR4_WORD1_TIME_MODIFY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) FATTR4_WORD2_MDSTHRESHOLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #ifdef CONFIG_NFS_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) | FATTR4_WORD2_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static const u32 nfs4_open_noattr_bitmap[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) FATTR4_WORD0_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) | FATTR4_WORD0_FILEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const u32 nfs4_statfs_bitmap[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) FATTR4_WORD0_FILES_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) | FATTR4_WORD0_FILES_FREE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) | FATTR4_WORD0_FILES_TOTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) FATTR4_WORD1_SPACE_AVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) | FATTR4_WORD1_SPACE_FREE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) | FATTR4_WORD1_SPACE_TOTAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) const u32 nfs4_pathconf_bitmap[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) FATTR4_WORD0_MAXLINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) | FATTR4_WORD0_MAXNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) | FATTR4_WORD0_MAXREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) | FATTR4_WORD0_MAXWRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) | FATTR4_WORD0_LEASE_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) FATTR4_WORD1_TIME_DELTA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) | FATTR4_WORD1_FS_LAYOUT_TYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) FATTR4_WORD2_LAYOUT_BLKSIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) | FATTR4_WORD2_CLONE_BLKSIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) | FATTR4_WORD2_XATTR_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) const u32 nfs4_fs_locations_bitmap[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) FATTR4_WORD0_CHANGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) | FATTR4_WORD0_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) | FATTR4_WORD0_FSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) | FATTR4_WORD0_FILEID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) | FATTR4_WORD0_FS_LOCATIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) FATTR4_WORD1_OWNER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) | FATTR4_WORD1_OWNER_GROUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) | FATTR4_WORD1_RAWDEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) | FATTR4_WORD1_SPACE_USED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) | FATTR4_WORD1_TIME_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) | FATTR4_WORD1_TIME_METADATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) | FATTR4_WORD1_TIME_MODIFY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) | FATTR4_WORD1_MOUNTED_ON_FILEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned long cache_validity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) memcpy(dst, src, NFS4_BITMASK_SZ*sizeof(*dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!inode || !nfs4_have_delegation(inode, FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (!(cache_validity & NFS_INO_REVAL_FORCED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) cache_validity &= ~(NFS_INO_INVALID_CHANGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) | NFS_INO_INVALID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!(cache_validity & NFS_INO_INVALID_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dst[0] &= ~FATTR4_WORD0_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!(cache_validity & NFS_INO_INVALID_CHANGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dst[0] &= ~FATTR4_WORD0_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void nfs4_bitmap_copy_adjust_setattr(__u32 *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) const __u32 *src, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) nfs4_bitmap_copy_adjust(dst, src, inode);
^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) static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct nfs4_readdir_arg *readdir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned int attrs = FATTR4_WORD0_FILEID | FATTR4_WORD0_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) __be32 *start, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (cookie > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) readdir->cookie = cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) memcpy(&readdir->verifier, verifier, sizeof(readdir->verifier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) readdir->cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) memset(&readdir->verifier, 0, sizeof(readdir->verifier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (cookie == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * NFSv4 servers do not return entries for '.' and '..'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * Therefore, we fake these entries here. We let '.'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * have cookie 0 and '..' have cookie 1. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * when talking to the server, we always send cookie 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * instead of 1 or 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) start = p = kmap_atomic(*readdir->pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (cookie == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) *p++ = xdr_one; /* next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) *p++ = xdr_zero; /* cookie, first word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) *p++ = xdr_one; /* cookie, second word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) *p++ = xdr_one; /* entry len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) memcpy(p, ".\0\0\0", 4); /* entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *p++ = xdr_one; /* bitmap length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) *p++ = htonl(attrs); /* bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) *p++ = htonl(12); /* attribute buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *p++ = htonl(NF4DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *p++ = xdr_one; /* next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *p++ = xdr_zero; /* cookie, first word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *p++ = xdr_two; /* cookie, second word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) *p++ = xdr_two; /* entry len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) memcpy(p, "..\0\0", 4); /* entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) *p++ = xdr_one; /* bitmap length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *p++ = htonl(attrs); /* bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *p++ = htonl(12); /* attribute buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *p++ = htonl(NF4DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry->d_parent)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) readdir->pgbase = (char *)p - (char *)start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) readdir->count -= readdir->pgbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) kunmap_atomic(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static void nfs4_test_and_free_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) const struct nfs4_minor_version_ops *ops = server->nfs_client->cl_mvops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ops->test_and_free_expired(server, stateid, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static void __nfs4_free_revoked_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) stateid->type = NFS4_REVOKED_STATEID_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) nfs4_test_and_free_stateid(server, stateid, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void nfs4_free_revoked_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) const nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) nfs4_stateid tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) nfs4_stateid_copy(&tmp, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) __nfs4_free_revoked_stateid(server, &tmp, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static long nfs4_update_delay(long *timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return NFS4_POLL_RETRY_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (*timeout <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *timeout = NFS4_POLL_RETRY_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (*timeout > NFS4_POLL_RETRY_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) *timeout = NFS4_POLL_RETRY_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = *timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *timeout <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int nfs4_delay_killable(long *timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) freezable_schedule_timeout_killable_unsafe(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) nfs4_update_delay(timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!__fatal_signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int nfs4_delay_interruptible(long *timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) freezable_schedule_timeout_interruptible_unsafe(nfs4_update_delay(timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return __fatal_signal_pending(current) ? -EINTR :-ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int nfs4_delay(long *timeout, bool interruptible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (interruptible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return nfs4_delay_interruptible(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return nfs4_delay_killable(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static const nfs4_stateid *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) nfs4_recoverable_stateid(const nfs4_stateid *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) switch (stateid->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case NFS4_OPEN_STATEID_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case NFS4_LOCK_STATEID_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) case NFS4_DELEGATION_STATEID_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /* This is the error handling routine for processes that are allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * to sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int nfs4_do_handle_exception(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int errorcode, struct nfs4_exception *exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct nfs4_state *state = exception->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) const nfs4_stateid *stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct inode *inode = exception->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int ret = errorcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) exception->delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) exception->recovering = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) exception->retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) stateid = nfs4_recoverable_stateid(exception->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (stateid == NULL && state != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) stateid = nfs4_recoverable_stateid(&state->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) switch(errorcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case -NFS4ERR_BADHANDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case -ESTALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (inode != NULL && S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) pnfs_destroy_layout(NFS_I(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) case -NFS4ERR_DELEG_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case -NFS4ERR_PARTNER_NO_AUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (inode != NULL && stateid != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) nfs_inode_find_state_and_recover(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) goto wait_on_recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case -NFS4ERR_OPENMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) err = nfs_async_inode_return_delegation(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto wait_on_recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (stateid != NULL && stateid->type == NFS4_DELEGATION_STATEID_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) exception->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) break;
^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) if (state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = nfs4_schedule_stateid_recovery(server, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) goto wait_on_recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) case -NFS4ERR_STALE_CLIENTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) nfs4_schedule_lease_recovery(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto wait_on_recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) case -NFS4ERR_MOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ret = nfs4_schedule_migration_recovery(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) goto wait_on_recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) case -NFS4ERR_LEASE_MOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) nfs4_schedule_lease_moved_recovery(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) goto wait_on_recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) case -NFS4ERR_BADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case -NFS4ERR_BADSLOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) case -NFS4ERR_BAD_HIGH_SLOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) case -NFS4ERR_DEADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case -NFS4ERR_SEQ_FALSE_RETRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) case -NFS4ERR_SEQ_MISORDERED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Handled in nfs41_sequence_process() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto wait_on_recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #endif /* defined(CONFIG_NFS_V4_1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) case -NFS4ERR_FILE_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (exception->timeout > HZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* We have retried a decent amount, time to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) nfs_inc_server_stats(server, NFSIOS_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) case -NFS4ERR_GRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) case -NFS4ERR_LAYOUTTRYLATER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) case -NFS4ERR_RECALLCONFLICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) exception->delay = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) case -NFS4ERR_RETRY_UNCACHED_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) case -NFS4ERR_OLD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) exception->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) case -NFS4ERR_BADOWNER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* The following works around a Linux server bug! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case -NFS4ERR_BADNAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (server->caps & NFS_CAP_UIDGID_NOMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) server->caps &= ~NFS_CAP_UIDGID_NOMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) exception->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) printk(KERN_WARNING "NFS: v4 server %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) "does not accept raw "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) "uid/gids. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) "Reenabling the idmapper.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) server->nfs_client->cl_hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* We failed to handle the error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return nfs4_map_errors(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) wait_on_recovery:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) exception->recovering = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* This is the error handling routine for processes that are allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * to sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) ret = nfs4_do_handle_exception(server, errorcode, exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (exception->delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ret = nfs4_delay(&exception->timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) exception->interruptible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (exception->recovering) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (exception->task_is_privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return -EDEADLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ret = nfs4_wait_clnt_recover(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (test_bit(NFS_MIG_FAILED, &server->mig_status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) out_retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) exception->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) nfs4_async_handle_exception(struct rpc_task *task, struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int errorcode, struct nfs4_exception *exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ret = nfs4_do_handle_exception(server, errorcode, exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (exception->delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) rpc_delay(task, nfs4_update_delay(&exception->timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (exception->recovering) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (exception->task_is_privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return -EDEADLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (test_bit(NFS_MIG_FAILED, &server->mig_status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) out_retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) exception->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * For NFS4ERR_MOVED, the client transport will need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * be recomputed after migration recovery has completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (errorcode == -NFS4ERR_MOVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) rpc_task_release_transport(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct nfs4_state *state, long *timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) .state = state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (task->tk_status >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) exception.timeout = *timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) task->tk_status = nfs4_async_handle_exception(task, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) task->tk_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (exception.delay && timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) *timeout = exception.timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (exception.retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * Return 'true' if 'clp' is using an rpc_client that is integrity protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * or 'false' otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static bool _nfs4_is_integrity_protected(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) rpc_authflavor_t flavor = clp->cl_rpcclient->cl_auth->au_flavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return (flavor == RPC_AUTH_GSS_KRB5I) || (flavor == RPC_AUTH_GSS_KRB5P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static void do_renew_lease(struct nfs_client *clp, unsigned long timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) spin_lock(&clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (time_before(clp->cl_last_renewal,timestamp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) clp->cl_last_renewal = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) spin_unlock(&clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (!nfs4_has_session(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) do_renew_lease(clp, timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct nfs4_call_sync_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) const struct nfs_server *seq_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct nfs4_sequence_args *seq_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct nfs4_sequence_res *seq_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) void nfs4_init_sequence(struct nfs4_sequence_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct nfs4_sequence_res *res, int cache_reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) args->sa_slot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) args->sa_cache_this = cache_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) args->sa_privileged = privileged;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) res->sr_slot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static void nfs40_sequence_free_slot(struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct nfs4_slot *slot = res->sr_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct nfs4_slot_table *tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) tbl = slot->table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) spin_lock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (!nfs41_wake_and_assign_slot(tbl, slot))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) nfs4_free_slot(tbl, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) spin_unlock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) res->sr_slot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static int nfs40_sequence_done(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (res->sr_slot != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) nfs40_sequence_free_slot(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static void nfs41_release_slot(struct nfs4_slot *slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct nfs4_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct nfs4_slot_table *tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) bool send_new_highest_used_slotid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (!slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) tbl = slot->table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) session = tbl->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* Bump the slot sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (slot->seq_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) slot->seq_nr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) slot->seq_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) spin_lock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* Be nice to the server: try to ensure that the last transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * value for highest_user_slotid <= target_highest_slotid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (tbl->highest_used_slotid > tbl->target_highest_slotid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) send_new_highest_used_slotid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (nfs41_wake_and_assign_slot(tbl, slot)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) send_new_highest_used_slotid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) nfs4_free_slot(tbl, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (tbl->highest_used_slotid != NFS4_NO_SLOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) send_new_highest_used_slotid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) spin_unlock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (send_new_highest_used_slotid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) nfs41_notify_server(session->clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (waitqueue_active(&tbl->slot_waitq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) wake_up_all(&tbl->slot_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) nfs41_release_slot(res->sr_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) res->sr_slot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static void nfs4_slot_sequence_record_sent(struct nfs4_slot *slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) u32 seqnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if ((s32)(seqnr - slot->seq_nr_highest_sent) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) slot->seq_nr_highest_sent = seqnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static void nfs4_slot_sequence_acked(struct nfs4_slot *slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) u32 seqnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) slot->seq_nr_highest_sent = seqnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) slot->seq_nr_last_acked = seqnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static void nfs4_probe_sequence(struct nfs_client *client, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct nfs4_slot *slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct rpc_task *task = _nfs41_proc_sequence(client, cred, slot, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (!IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) rpc_put_task_async(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static int nfs41_sequence_process(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct nfs4_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct nfs4_slot *slot = res->sr_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (slot == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) goto out_noaction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* don't increment the sequence number if the task wasn't sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (!RPC_WAS_SENT(task) || slot->seq_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) session = slot->table->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) clp = session->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) trace_nfs4_sequence_done(session, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) status = res->sr_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (task->tk_status == -NFS4ERR_DEADSESSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) status = -NFS4ERR_DEADSESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* Check the SEQUENCE operation status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /* Mark this sequence number as having been acked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) nfs4_slot_sequence_acked(slot, slot->seq_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Update the slot's sequence and clientid lease timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) slot->seq_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) do_renew_lease(clp, res->sr_timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /* Check sequence flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) !!slot->privileged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) nfs41_update_target_slotid(slot->table, slot, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * sr_status remains 1 if an RPC level error occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * The server may or may not have processed the sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * operation..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) nfs4_slot_sequence_record_sent(slot, slot->seq_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) slot->seq_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /* The server detected a resend of the RPC call and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * returned NFS4ERR_DELAY as per Section 2.10.6.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * of RFC5661.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dprintk("%s: slot=%u seq=%u: Operation in progress\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) slot->slot_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) slot->seq_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) nfs4_slot_sequence_acked(slot, slot->seq_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) case -NFS4ERR_RETRY_UNCACHED_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) case -NFS4ERR_SEQ_FALSE_RETRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * The server thinks we tried to replay a request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * Retry the call after bumping the sequence ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) nfs4_slot_sequence_acked(slot, slot->seq_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) goto retry_new_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) case -NFS4ERR_BADSLOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * The slot id we used was probably retired. Try again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * using a different slot id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (slot->slot_nr < slot->table->target_highest_slotid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) goto session_recover;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) goto retry_nowait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case -NFS4ERR_SEQ_MISORDERED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) nfs4_slot_sequence_record_sent(slot, slot->seq_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * Were one or more calls using this slot interrupted?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * If the server never received the request, then our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * transmitted slot sequence number may be too high. However,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * if the server did receive the request then it might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * accidentally give us a reply with a mismatched operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * We can sort this out by sending a lone sequence operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * to the server on the same slot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if ((s32)(slot->seq_nr - slot->seq_nr_last_acked) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) slot->seq_nr--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (task->tk_msg.rpc_proc != &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) nfs4_probe_sequence(clp, task->tk_msg.rpc_cred, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) res->sr_slot = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) goto retry_nowait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * RFC5661:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * A retry might be sent while the original request is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * still in progress on the replier. The replier SHOULD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * deal with the issue by returning NFS4ERR_DELAY as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * reply to SEQUENCE or CB_SEQUENCE operation, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * implementations MAY return NFS4ERR_SEQ_MISORDERED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * Restart the search after a delay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) slot->seq_nr = slot->seq_nr_highest_sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) case -NFS4ERR_BADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case -NFS4ERR_DEADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) goto session_recover;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* Just update the slot sequence no. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) slot->seq_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /* The session may be reset by one of the error handlers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) dprintk("%s: Error %d free the slot \n", __func__, res->sr_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) out_noaction:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) session_recover:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) nfs4_schedule_session_recovery(session, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dprintk("%s ERROR: %d Reset session\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) nfs41_sequence_free_slot(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) retry_new_seq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ++slot->seq_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) retry_nowait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (rpc_restart_call_prepare(task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) nfs41_sequence_free_slot(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) out_retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (!rpc_restart_call(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) rpc_delay(task, NFS4_POLL_RETRY_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!nfs41_sequence_process(task, res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (res->sr_slot != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) nfs41_sequence_free_slot(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) EXPORT_SYMBOL_GPL(nfs41_sequence_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (res->sr_slot == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (res->sr_slot->table->session != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return nfs41_sequence_process(task, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return nfs40_sequence_done(task, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static void nfs4_sequence_free_slot(struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (res->sr_slot != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (res->sr_slot->table->session != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) nfs41_sequence_free_slot(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) nfs40_sequence_free_slot(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (res->sr_slot == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (!res->sr_slot->table->session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return nfs40_sequence_done(task, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return nfs41_sequence_done(task, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) EXPORT_SYMBOL_GPL(nfs4_sequence_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct nfs4_call_sync_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) nfs4_setup_sequence(data->seq_server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) data->seq_args, data->seq_res, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) struct nfs4_call_sync_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) nfs41_sequence_done(task, data->seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) static const struct rpc_call_ops nfs41_call_sync_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) .rpc_call_prepare = nfs41_call_sync_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) .rpc_call_done = nfs41_call_sync_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) #else /* !CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return nfs40_sequence_done(task, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static void nfs4_sequence_free_slot(struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (res->sr_slot != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) nfs40_sequence_free_slot(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) int nfs4_sequence_done(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return nfs40_sequence_done(task, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) EXPORT_SYMBOL_GPL(nfs4_sequence_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) #endif /* !CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static void nfs41_sequence_res_init(struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) res->sr_timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) res->sr_status_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) res->sr_status = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) void nfs4_sequence_attach_slot(struct nfs4_sequence_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct nfs4_sequence_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct nfs4_slot *slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) slot->privileged = args->sa_privileged ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) args->sa_slot = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) res->sr_slot = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) int nfs4_setup_sequence(struct nfs_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct nfs4_sequence_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct nfs4_sequence_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct rpc_task *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct nfs4_session *session = nfs4_get_session(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct nfs4_slot_table *tbl = client->cl_slot_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct nfs4_slot *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* slot already allocated? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (res->sr_slot != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) goto out_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) tbl = &session->fc_slot_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) spin_lock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* The state manager will wait until the slot table is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) goto out_sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) slot = nfs4_alloc_slot(tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (IS_ERR(slot)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (slot == ERR_PTR(-ENOMEM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) goto out_sleep_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) goto out_sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) spin_unlock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) nfs4_sequence_attach_slot(args, res, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) trace_nfs4_setup_sequence(session, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) out_start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) nfs41_sequence_res_init(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) rpc_call_start(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) out_sleep_timeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* Try again in 1/4 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (args->sa_privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) rpc_sleep_on_priority_timeout(&tbl->slot_tbl_waitq, task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) jiffies + (HZ >> 2), RPC_PRIORITY_PRIVILEGED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) rpc_sleep_on_timeout(&tbl->slot_tbl_waitq, task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) NULL, jiffies + (HZ >> 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) spin_unlock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) out_sleep:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (args->sa_privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) rpc_sleep_on_priority(&tbl->slot_tbl_waitq, task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) RPC_PRIORITY_PRIVILEGED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) spin_unlock(&tbl->slot_tbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) EXPORT_SYMBOL_GPL(nfs4_setup_sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static void nfs40_call_sync_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct nfs4_call_sync_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) nfs4_setup_sequence(data->seq_server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) data->seq_args, data->seq_res, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static void nfs40_call_sync_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) struct nfs4_call_sync_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) nfs4_sequence_done(task, data->seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static const struct rpc_call_ops nfs40_call_sync_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .rpc_call_prepare = nfs40_call_sync_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .rpc_call_done = nfs40_call_sync_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) static int nfs4_call_sync_custom(struct rpc_task_setup *task_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) task = rpc_run_task(task_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ret = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static int nfs4_do_call_sync(struct rpc_clnt *clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) struct rpc_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct nfs4_sequence_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct nfs4_sequence_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) unsigned short task_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct nfs4_call_sync_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .seq_server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .seq_args = args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) .seq_res = res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) struct rpc_task_setup task_setup = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .rpc_client = clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .rpc_message = msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .callback_ops = clp->cl_mvops->call_sync_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) .callback_data = &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) .flags = task_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return nfs4_call_sync_custom(&task_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct rpc_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct nfs4_sequence_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct nfs4_sequence_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return nfs4_do_call_sync(clnt, server, msg, args, res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) int nfs4_call_sync(struct rpc_clnt *clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct rpc_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) struct nfs4_sequence_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct nfs4_sequence_res *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) int cache_reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) nfs4_init_sequence(args, res, cache_reply, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return nfs4_call_sync_sequence(clnt, server, msg, args, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) nfs4_inc_nlink_locked(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) inc_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) nfs4_dec_nlink_locked(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) drop_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) nfs4_update_changeattr_locked(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) struct nfs4_change_info *cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) unsigned long timestamp, unsigned long cache_validity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) nfsi->cache_validity |= NFS_INO_INVALID_CTIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) | NFS_INO_INVALID_MTIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) | cache_validity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) nfsi->attrtimeo_timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) nfsi->cache_validity |= NFS_INO_INVALID_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) nfs_force_lookup_revalidate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (!NFS_PROTO(inode)->have_delegation(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (cinfo->before != inode_peek_iversion_raw(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) nfsi->cache_validity |= NFS_INO_INVALID_ACCESS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) NFS_INO_INVALID_ACL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) NFS_INO_INVALID_XATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) inode_set_iversion_raw(inode, cinfo->after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) nfsi->read_cache_jiffies = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) nfsi->attr_gencount = nfs_inc_attr_generation_counter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) nfs_fscache_invalidate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) nfs4_update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) unsigned long timestamp, unsigned long cache_validity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) spin_lock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) nfs4_update_changeattr_locked(dir, cinfo, timestamp, cache_validity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) spin_unlock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) struct nfs4_open_createattrs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct nfs4_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct iattr *sattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) const __u32 verf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) int err, struct nfs4_exception *exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (!(server->caps & NFS_CAP_ATOMIC_OPEN_V1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) server->caps &= ~NFS_CAP_ATOMIC_OPEN_V1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) exception->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static fmode_t _nfs4_ctx_to_accessmode(const struct nfs_open_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static fmode_t _nfs4_ctx_to_openmode(const struct nfs_open_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) fmode_t ret = ctx->mode & (FMODE_READ|FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return (ctx->mode & FMODE_EXEC) ? FMODE_READ | ret : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) nfs4_map_atomic_open_share(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) fmode_t fmode, int openflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) u32 res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) switch (fmode & (FMODE_READ | FMODE_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) case FMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) res = NFS4_SHARE_ACCESS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) case FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) res = NFS4_SHARE_ACCESS_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) case FMODE_READ|FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) res = NFS4_SHARE_ACCESS_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (!(server->caps & NFS_CAP_ATOMIC_OPEN_V1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) /* Want no delegation if we're using O_DIRECT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (openflags & O_DIRECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) res |= NFS4_SHARE_WANT_NO_DELEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static enum open_claim_type4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) nfs4_map_atomic_open_claim(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) enum open_claim_type4 claim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (server->caps & NFS_CAP_ATOMIC_OPEN_V1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return claim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) switch (claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return claim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return NFS4_OPEN_CLAIM_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return NFS4_OPEN_CLAIM_DELEGATE_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return NFS4_OPEN_CLAIM_DELEGATE_PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static void nfs4_init_opendata_res(struct nfs4_opendata *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) p->o_res.f_attr = &p->f_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) p->o_res.f_label = p->f_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) p->o_res.seqid = p->o_arg.seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) p->c_res.seqid = p->c_arg.seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) p->o_res.server = p->o_arg.server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) p->o_res.access_request = p->o_arg.access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) nfs_fattr_init(&p->f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct nfs4_state_owner *sp, fmode_t fmode, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) const struct nfs4_open_createattrs *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) enum open_claim_type4 claim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) gfp_t gfp_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct dentry *parent = dget_parent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) struct inode *dir = d_inode(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) struct nfs4_label *label = (c != NULL) ? c->label : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct nfs4_opendata *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) p = kzalloc(sizeof(*p), gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) p->f_label = nfs4_label_alloc(server, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (IS_ERR(p->f_label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) goto err_free_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) p->a_label = nfs4_label_alloc(server, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (IS_ERR(p->a_label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) goto err_free_f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) alloc_seqid = server->nfs_client->cl_mvops->alloc_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) p->o_arg.seqid = alloc_seqid(&sp->so_seqid, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (IS_ERR(p->o_arg.seqid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) goto err_free_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) nfs_sb_active(dentry->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) p->dentry = dget(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) p->dir = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) p->owner = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) atomic_inc(&sp->so_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) p->o_arg.open_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) p->o_arg.share_access = nfs4_map_atomic_open_share(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) fmode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (flags & O_CREAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) p->o_arg.umask = current_umask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) p->o_arg.label = nfs4_label_copy(p->a_label, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (c->sattr != NULL && c->sattr->ia_valid != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) p->o_arg.u.attrs = &p->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) memcpy(&p->attrs, c->sattr, sizeof(p->attrs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) memcpy(p->o_arg.u.verifier.data, c->verf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) sizeof(p->o_arg.u.verifier.data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * will return permission denied for all bits until close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (!(flags & O_EXCL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* ask server to check for all possible rights as results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * are cached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) switch (p->o_arg.claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) p->o_arg.access = NFS4_ACCESS_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) NFS4_ACCESS_MODIFY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) NFS4_ACCESS_EXTEND |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) NFS4_ACCESS_EXECUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) #ifdef CONFIG_NFS_V4_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (server->caps & NFS_CAP_XATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) p->o_arg.access |= NFS4_ACCESS_XAREAD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) NFS4_ACCESS_XAWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) NFS4_ACCESS_XALIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) p->o_arg.clientid = server->nfs_client->cl_clientid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) p->o_arg.id.uniquifier = sp->so_seqid.owner_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) p->o_arg.name = &dentry->d_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) p->o_arg.server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) p->o_arg.bitmask = nfs4_bitmask(server, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) switch (p->o_arg.claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) case NFS4_OPEN_CLAIM_DELEGATE_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) case NFS4_OPEN_CLAIM_DELEGATE_PREV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) p->o_arg.fh = NFS_FH(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) case NFS4_OPEN_CLAIM_PREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) p->o_arg.fh = NFS_FH(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) p->c_arg.fh = &p->o_res.fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) p->c_arg.stateid = &p->o_res.stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) p->c_arg.seqid = p->o_arg.seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) nfs4_init_opendata_res(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) kref_init(&p->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) err_free_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) nfs4_label_free(p->a_label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) err_free_f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) nfs4_label_free(p->f_label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) err_free_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) static void nfs4_opendata_free(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct nfs4_opendata *p = container_of(kref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct nfs4_opendata, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct super_block *sb = p->dentry->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) nfs4_lgopen_release(p->lgp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) nfs_free_seqid(p->o_arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) nfs4_sequence_free_slot(&p->o_res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (p->state != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) nfs4_put_open_state(p->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) nfs4_put_state_owner(p->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) nfs4_label_free(p->a_label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) nfs4_label_free(p->f_label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) dput(p->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) dput(p->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) nfs_sb_deactive(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) nfs_fattr_free_names(&p->f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) kfree(p->f_attr.mdsthreshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) static void nfs4_opendata_put(struct nfs4_opendata *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (p != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) kref_put(&p->kref, nfs4_opendata_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static bool nfs4_mode_match_open_stateid(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) switch(fmode & (FMODE_READ|FMODE_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) case FMODE_READ|FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return state->n_rdwr != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) case FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return state->n_wronly != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) case FMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) return state->n_rdonly != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int can_open_cached(struct nfs4_state *state, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) int open_mode, enum open_claim_type4 claim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (open_mode & (O_EXCL|O_TRUNC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) switch (claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) switch (mode & (FMODE_READ|FMODE_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) case FMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) && state->n_rdonly != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) case FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) && state->n_wronly != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) case FMODE_READ|FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) && state->n_rdwr != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) enum open_claim_type4 claim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (delegation == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if ((delegation->type & fmode) != fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) switch (claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) case NFS4_OPEN_CLAIM_PREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (!test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) nfs_mark_delegation_referenced(delegation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static void update_open_stateflags(struct nfs4_state *state, fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) switch (fmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) case FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) state->n_wronly++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) case FMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) state->n_rdonly++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) case FMODE_READ|FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) state->n_rdwr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) nfs4_state_set_mode_locked(state, state->state | fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) static bool nfs_open_stateid_recover_openmode(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) if (state->n_rdonly && !test_bit(NFS_O_RDONLY_STATE, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (state->n_wronly && !test_bit(NFS_O_WRONLY_STATE, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (state->n_rdwr && !test_bit(NFS_O_RDWR_STATE, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) static void nfs_state_log_update_open_stateid(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) if (test_and_clear_bit(NFS_STATE_CHANGE_WAIT, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) wake_up_all(&state->waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static void nfs_test_and_clear_all_open_stateid(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) struct nfs_client *clp = state->owner->so_server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) bool need_recover = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags) && state->n_rdonly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) need_recover = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags) && state->n_wronly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) need_recover = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags) && state->n_rdwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) need_recover = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (need_recover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) nfs4_state_mark_reclaim_nograce(clp, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * Check for whether or not the caller may update the open stateid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * to the value passed in by stateid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) * Note: This function relies heavily on the server implementing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) * RFC7530 Section 9.1.4.2, and RFC5661 Section 8.2.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * i.e. The stateid seqids have to be initialised to 1, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * are then incremented on every state transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) static bool nfs_stateid_is_sequential(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) const nfs4_stateid *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (test_bit(NFS_OPEN_STATE, &state->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* The common case - we're updating to a new sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (nfs4_stateid_match_other(stateid, &state->open_stateid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (nfs4_stateid_is_next(&state->open_stateid, stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* The server returned a new stateid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /* This is the first OPEN in this generation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (stateid->seqid == cpu_to_be32(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) static void nfs_resync_open_stateid_locked(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (!(state->n_wronly || state->n_rdonly || state->n_rdwr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (state->n_wronly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) set_bit(NFS_O_WRONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) if (state->n_rdonly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) set_bit(NFS_O_RDONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (state->n_rdwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) set_bit(NFS_O_RDWR_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) set_bit(NFS_OPEN_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static void nfs_clear_open_stateid_locked(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) nfs4_stateid *stateid, fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) clear_bit(NFS_O_RDWR_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) switch (fmode & (FMODE_READ|FMODE_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) case FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) clear_bit(NFS_O_RDONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) case FMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) clear_bit(NFS_O_WRONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) clear_bit(NFS_O_RDONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) clear_bit(NFS_O_WRONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) clear_bit(NFS_OPEN_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (stateid == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) /* Handle OPEN+OPEN_DOWNGRADE races */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (nfs4_stateid_match_other(stateid, &state->open_stateid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) !nfs4_stateid_is_newer(stateid, &state->open_stateid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) nfs_resync_open_stateid_locked(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) nfs4_stateid_copy(&state->stateid, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) nfs4_stateid_copy(&state->open_stateid, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) trace_nfs4_open_stateid_update(state->inode, stateid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) nfs_state_log_update_open_stateid(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) static void nfs_clear_open_stateid(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) nfs4_stateid *arg_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) nfs4_stateid *stateid, fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) write_seqlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) /* Ignore, if the CLOSE argment doesn't match the current stateid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (nfs4_state_match_open_stateid_other(state, arg_stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) nfs_clear_open_stateid_locked(state, stateid, fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (test_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) nfs4_schedule_state_manager(state->owner->so_server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) static void nfs_set_open_stateid_locked(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) const nfs4_stateid *stateid, nfs4_stateid *freeme)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) __must_hold(&state->owner->so_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) __must_hold(&state->seqlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) __must_hold(RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (nfs_stateid_is_sequential(state, stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) /* Rely on seqids for serialisation with NFSv4.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (!nfs4_has_session(NFS_SERVER(state->inode)->nfs_client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) set_bit(NFS_STATE_CHANGE_WAIT, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) prepare_to_wait(&state->waitq, &wait, TASK_KILLABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) * Ensure we process the state changes in the same order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * in which the server processed them by delaying the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) * update of the stateid until we are in sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) spin_unlock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) trace_nfs4_open_stateid_update_wait(state->inode, stateid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (!fatal_signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) if (schedule_timeout(5*HZ) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) status = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) finish_wait(&state->waitq, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) spin_lock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) write_seqlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (test_bit(NFS_OPEN_STATE, &state->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) !nfs4_stateid_match_other(stateid, &state->open_stateid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) nfs4_stateid_copy(freeme, &state->open_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) nfs_test_and_clear_all_open_stateid(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) nfs4_stateid_copy(&state->stateid, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) nfs4_stateid_copy(&state->open_stateid, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) trace_nfs4_open_stateid_update(state->inode, stateid, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) nfs_state_log_update_open_stateid(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) static void nfs_state_set_open_stateid(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) const nfs4_stateid *open_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) fmode_t fmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) nfs4_stateid *freeme)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) * Protect the call to nfs4_state_set_mode_locked and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) * serialise the stateid update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) write_seqlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) nfs_set_open_stateid_locked(state, open_stateid, freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) switch (fmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) case FMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) set_bit(NFS_O_RDONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) case FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) set_bit(NFS_O_WRONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) case FMODE_READ|FMODE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) set_bit(NFS_O_RDWR_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) set_bit(NFS_OPEN_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) static void nfs_state_clear_open_state_flags(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) clear_bit(NFS_O_RDWR_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) clear_bit(NFS_O_WRONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) clear_bit(NFS_O_RDONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) clear_bit(NFS_OPEN_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) static void nfs_state_set_delegation(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) const nfs4_stateid *deleg_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) * Protect the call to nfs4_state_set_mode_locked and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) * serialise the stateid update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) write_seqlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) nfs4_stateid_copy(&state->stateid, deleg_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) set_bit(NFS_DELEGATED_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) static void nfs_state_clear_delegation(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) write_seqlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) nfs4_stateid_copy(&state->stateid, &state->open_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) clear_bit(NFS_DELEGATED_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) int update_open_stateid(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) const nfs4_stateid *open_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) const nfs4_stateid *delegation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) struct nfs_inode *nfsi = NFS_I(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct nfs_delegation *deleg_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) nfs4_stateid freeme = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) fmode &= (FMODE_READ|FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) spin_lock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (open_stateid != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) nfs_state_set_open_stateid(state, open_stateid, fmode, &freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) deleg_cur = nfs4_get_valid_delegation(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (deleg_cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) goto no_delegation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) spin_lock(&deleg_cur->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) if (rcu_dereference(nfsi->delegation) != deleg_cur ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) test_bit(NFS_DELEGATION_RETURNING, &deleg_cur->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) (deleg_cur->type & fmode) != fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) goto no_delegation_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (delegation == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) delegation = &deleg_cur->stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) else if (!nfs4_stateid_match_other(&deleg_cur->stateid, delegation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) goto no_delegation_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) nfs_mark_delegation_referenced(deleg_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) nfs_state_set_delegation(state, &deleg_cur->stateid, fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) no_delegation_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) spin_unlock(&deleg_cur->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) no_delegation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) update_open_stateflags(state, fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) spin_unlock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (test_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) nfs4_schedule_state_manager(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) if (freeme.type != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) nfs4_test_and_free_stateid(server, &freeme,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) state->owner->so_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) static bool nfs4_update_lock_stateid(struct nfs4_lock_state *lsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) const nfs4_stateid *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) struct nfs4_state *state = lsp->ls_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) spin_lock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) if (!nfs4_stateid_match_other(stateid, &lsp->ls_stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) goto out_noupdate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (!nfs4_stateid_is_newer(stateid, &lsp->ls_stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) goto out_noupdate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) nfs4_stateid_copy(&lsp->ls_stateid, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) out_noupdate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) spin_unlock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) struct nfs_delegation *delegation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) fmode &= FMODE_READ|FMODE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) delegation = nfs4_get_valid_delegation(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (delegation == NULL || (delegation->type & fmode) == fmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) nfs4_inode_return_delegation(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) struct nfs4_state *state = opendata->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) struct nfs_delegation *delegation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) int open_mode = opendata->o_arg.open_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) fmode_t fmode = opendata->o_arg.fmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) enum open_claim_type4 claim = opendata->o_arg.claim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) nfs4_stateid stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) int ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) spin_lock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (can_open_cached(state, fmode, open_mode, claim)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) update_open_stateflags(state, fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) spin_unlock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) goto out_return_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) spin_unlock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) delegation = nfs4_get_valid_delegation(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) if (!can_open_delegated(delegation, fmode, claim)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) /* Save the delegation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) nfs4_stateid_copy(&stateid, &delegation->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) nfs_release_seqid(opendata->o_arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (!opendata->is_recover) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) /* Try to update the stateid using the delegation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (update_open_stateid(state, NULL, &stateid, fmode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) goto out_return_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) out_return_state:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) refcount_inc(&state->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) struct nfs_client *clp = NFS_SERVER(state->inode)->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) struct nfs_delegation *delegation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) int delegation_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) delegation = rcu_dereference(NFS_I(state->inode)->delegation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (delegation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) delegation_flags = delegation->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) switch (data->o_arg.claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) case NFS4_OPEN_CLAIM_DELEGATE_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) "returning a delegation for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) "OPEN(CLAIM_DELEGATE_CUR)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) clp->cl_hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) nfs_inode_set_delegation(state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) data->owner->so_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) data->o_res.delegation_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) &data->o_res.delegation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) data->o_res.pagemod_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) nfs_inode_reclaim_delegation(state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) data->owner->so_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) data->o_res.delegation_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) &data->o_res.delegation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) data->o_res.pagemod_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (data->o_res.do_recall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) nfs_async_inode_return_delegation(state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) &data->o_res.delegation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * Check the inode attributes against the CLAIM_PREVIOUS returned attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) * and update the nfs4_state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) static struct nfs4_state *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) struct inode *inode = data->state->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) struct nfs4_state *state = data->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) if (!data->rpc_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) if (data->rpc_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) return ERR_PTR(data->rpc_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) /* cached opens have already been processed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) ret = nfs_refresh_inode(inode, &data->f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (data->o_res.delegation_type != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) nfs4_opendata_check_deleg(data, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) update:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) if (!update_open_stateid(state, &data->o_res.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) NULL, data->o_arg.fmode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) return ERR_PTR(-EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) refcount_inc(&state->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static struct inode *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) nfs4_opendata_get_inode(struct nfs4_opendata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) switch (data->o_arg.claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) case NFS4_OPEN_CLAIM_DELEGATE_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) case NFS4_OPEN_CLAIM_DELEGATE_PREV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (!(data->f_attr.valid & NFS_ATTR_FATTR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) return ERR_PTR(-EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) &data->f_attr, data->f_label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) inode = d_inode(data->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) nfs_refresh_inode(inode, &data->f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) static struct nfs4_state *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) nfs4_opendata_find_nfs4_state(struct nfs4_opendata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) struct nfs4_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) inode = nfs4_opendata_get_inode(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) return ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (data->state != NULL && data->state->inode == inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) state = data->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) refcount_inc(&state->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) state = nfs4_get_open_state(inode, data->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) if (state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) state = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) static struct nfs4_state *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) struct nfs4_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) if (!data->rpc_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) state = nfs4_try_open_cached(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) trace_nfs4_cached_open(data->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) state = nfs4_opendata_find_nfs4_state(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (data->o_res.delegation_type != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) nfs4_opendata_check_deleg(data, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) if (!update_open_stateid(state, &data->o_res.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) NULL, data->o_arg.fmode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) nfs4_put_open_state(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) state = ERR_PTR(-EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) nfs_release_seqid(data->o_arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) static struct nfs4_state *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) struct nfs4_state *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) ret =_nfs4_opendata_reclaim_to_nfs4_state(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) ret = _nfs4_opendata_to_nfs4_state(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) nfs4_sequence_free_slot(&data->o_res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) static struct nfs_open_context *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) nfs4_state_find_open_context_mode(struct nfs4_state *state, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) struct nfs_inode *nfsi = NFS_I(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) list_for_each_entry_rcu(ctx, &nfsi->open_files, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) if (ctx->state != state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if ((ctx->mode & mode) != mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (!get_nfs_open_context(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) return ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) static struct nfs_open_context *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) nfs4_state_find_open_context(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) ctx = nfs4_state_find_open_context_mode(state, FMODE_READ|FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (!IS_ERR(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) return ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) ctx = nfs4_state_find_open_context_mode(state, FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (!IS_ERR(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) return ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) return nfs4_state_find_open_context_mode(state, FMODE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) struct nfs4_state *state, enum open_claim_type4 claim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) struct nfs4_opendata *opendata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) NULL, claim, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) if (opendata == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) opendata->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) refcount_inc(&state->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) return opendata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) static int nfs4_open_recover_helper(struct nfs4_opendata *opendata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) struct nfs4_state *newstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (!nfs4_mode_match_open_stateid(opendata->state, fmode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) opendata->o_arg.open_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) opendata->o_arg.fmode = fmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) opendata->o_arg.share_access = nfs4_map_atomic_open_share(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) NFS_SB(opendata->dentry->d_sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) fmode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) memset(&opendata->o_res, 0, sizeof(opendata->o_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) memset(&opendata->c_res, 0, sizeof(opendata->c_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) nfs4_init_opendata_res(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) ret = _nfs4_recover_proc_open(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) newstate = nfs4_opendata_to_nfs4_state(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) if (IS_ERR(newstate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) return PTR_ERR(newstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) if (newstate != opendata->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) ret = -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) nfs4_close_state(newstate, fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) /* memory barrier prior to reading state->n_* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) ret = nfs4_open_recover_helper(opendata, FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) ret = nfs4_open_recover_helper(opendata, FMODE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) * We may have performed cached opens for all three recoveries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) * Check if we need to update the current stateid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) !nfs4_stateid_match(&state->stateid, &state->open_stateid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) write_seqlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) nfs4_stateid_copy(&state->stateid, &state->open_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) * OPEN_RECLAIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) * reclaim state on the server after a reboot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) struct nfs_delegation *delegation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) struct nfs4_opendata *opendata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) fmode_t delegation_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) opendata = nfs4_open_recoverdata_alloc(ctx, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) NFS4_OPEN_CLAIM_PREVIOUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (IS_ERR(opendata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return PTR_ERR(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) delegation = rcu_dereference(NFS_I(state->inode)->delegation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) delegation_type = delegation->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) opendata->o_arg.u.delegation_type = delegation_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) status = nfs4_open_recover(opendata, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) nfs4_opendata_put(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) struct nfs4_exception exception = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) err = _nfs4_do_open_reclaim(ctx, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) trace_nfs4_open_reclaim(ctx, 0, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (err != -NFS4ERR_DELAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) ctx = nfs4_state_find_open_context(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) if (IS_ERR(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) clear_bit(NFS_DELEGATED_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) nfs_state_clear_open_state_flags(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) ret = nfs4_do_open_reclaim(ctx, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) put_nfs_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct nfs4_state *state, const nfs4_stateid *stateid, struct file_lock *fl, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) printk(KERN_ERR "NFS: %s: unhandled error "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) "%d.\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) case -ESTALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) case -NFS4ERR_BADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) case -NFS4ERR_BADSLOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) case -NFS4ERR_BAD_HIGH_SLOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) case -NFS4ERR_DEADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) case -NFS4ERR_STALE_CLIENTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* Don't recall a delegation if it was lost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) nfs4_schedule_lease_recovery(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) case -NFS4ERR_MOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) nfs4_schedule_migration_recovery(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) case -NFS4ERR_LEASE_MOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) nfs4_schedule_lease_moved_recovery(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) case -NFS4ERR_DELEG_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) case -NFS4ERR_OPENMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) nfs_inode_find_state_and_recover(state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) nfs4_schedule_stateid_recovery(server, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) case -NFS4ERR_GRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) case -ENOMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) case -NFS4ERR_DENIED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (fl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) struct nfs4_lock_state *lsp = fl->fl_u.nfs4_fl.owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) if (lsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) set_bit(NFS_LOCK_LOST, &lsp->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) struct nfs4_state *state, const nfs4_stateid *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) struct nfs4_opendata *opendata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) opendata = nfs4_open_recoverdata_alloc(ctx, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) NFS4_OPEN_CLAIM_DELEG_CUR_FH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) if (IS_ERR(opendata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) return PTR_ERR(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) if (!test_bit(NFS_O_RDWR_STATE, &state->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) err = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) if (!test_bit(NFS_O_WRONLY_STATE, &state->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) err = nfs4_open_recover_helper(opendata, FMODE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) if (!test_bit(NFS_O_RDONLY_STATE, &state->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) err = nfs4_open_recover_helper(opendata, FMODE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) nfs_state_clear_delegation(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) nfs4_opendata_put(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) return nfs4_handle_delegation_recall_error(server, state, stateid, NULL, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) struct nfs4_opendata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) nfs4_setup_sequence(data->o_arg.server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) &data->c_arg.seq_args, &data->c_res.seq_res, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) struct nfs4_opendata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) nfs40_sequence_done(task, &data->c_res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) data->rpc_status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) if (data->rpc_status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) nfs4_stateid_copy(&data->o_res.stateid, &data->c_res.stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) nfs_confirm_seqid(&data->owner->so_seqid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) renew_lease(data->o_res.server, data->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) data->rpc_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) static void nfs4_open_confirm_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) struct nfs4_opendata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) struct nfs4_state *state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) /* If this request hasn't been cancelled, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) if (!data->cancelled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) /* In case of error, no cleanup! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (!data->rpc_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) state = nfs4_opendata_to_nfs4_state(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) nfs4_close_state(state, data->o_arg.fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) nfs4_opendata_put(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) static const struct rpc_call_ops nfs4_open_confirm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) .rpc_call_prepare = nfs4_open_confirm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) .rpc_call_done = nfs4_open_confirm_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) .rpc_release = nfs4_open_confirm_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) * Note: On error, nfs4_proc_open_confirm will free the struct nfs4_opendata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) struct nfs_server *server = NFS_SERVER(d_inode(data->dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) .rpc_argp = &data->c_arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) .rpc_resp = &data->c_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) .rpc_cred = data->owner->so_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) .rpc_client = server->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) .callback_ops = &nfs4_open_confirm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) .callback_data = data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) .workqueue = nfsiod_workqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) nfs4_init_sequence(&data->c_arg.seq_args, &data->c_res.seq_res, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) data->is_recover);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) kref_get(&data->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) data->rpc_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) data->rpc_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) data->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) status = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) data->cancelled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) status = data->rpc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) struct nfs4_opendata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) struct nfs4_state_owner *sp = data->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) struct nfs_client *clp = sp->so_server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) enum open_claim_type4 claim = data->o_arg.claim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) goto out_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) * Check if we still need to send an OPEN call, or if we can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) * a delegation instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) if (data->state != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) struct nfs_delegation *delegation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) if (can_open_cached(data->state, data->o_arg.fmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) data->o_arg.open_flags, claim))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) goto out_no_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) delegation = nfs4_get_valid_delegation(data->state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) if (can_open_delegated(delegation, data->o_arg.fmode, claim))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) goto unlock_no_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) /* Update client id. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) data->o_arg.clientid = clp->cl_clientid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) switch (claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) case NFS4_OPEN_CLAIM_PREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) data->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) &data->o_arg.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) &data->o_res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) task) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) nfs_release_seqid(data->o_arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) /* Set the create mode (note dependency on the session type) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) data->o_arg.createmode = NFS4_CREATE_UNCHECKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (data->o_arg.open_flags & O_EXCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) if (nfs4_has_persistent_session(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) data->o_arg.createmode = NFS4_CREATE_GUARDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) else if (clp->cl_mvops->minor_version > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) unlock_no_action:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) trace_nfs4_cached_open(data->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) out_no_action:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) task->tk_action = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) out_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) nfs4_sequence_done(task, &data->o_res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) static void nfs4_open_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) struct nfs4_opendata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) data->rpc_status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) if (!nfs4_sequence_process(task, &data->o_res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) if (task->tk_status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) if (data->o_res.f_attr->valid & NFS_ATTR_FATTR_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) switch (data->o_res.f_attr->mode & S_IFMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) case S_IFLNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) data->rpc_status = -ELOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) case S_IFDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) data->rpc_status = -EISDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) data->rpc_status = -ENOTDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) renew_lease(data->o_res.server, data->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) nfs_confirm_seqid(&data->owner->so_seqid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) data->rpc_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) static void nfs4_open_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) struct nfs4_opendata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) struct nfs4_state *state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) /* If this request hasn't been cancelled, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) if (!data->cancelled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) /* In case of error, no cleanup! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (data->rpc_status != 0 || !data->rpc_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) /* In case we need an open_confirm, no cleanup! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) state = nfs4_opendata_to_nfs4_state(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) nfs4_close_state(state, data->o_arg.fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) nfs4_opendata_put(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) static const struct rpc_call_ops nfs4_open_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) .rpc_call_prepare = nfs4_open_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) .rpc_call_done = nfs4_open_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) .rpc_release = nfs4_open_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) static int nfs4_run_open_task(struct nfs4_opendata *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) struct nfs_open_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) struct inode *dir = d_inode(data->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) struct nfs_openargs *o_arg = &data->o_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) struct nfs_openres *o_res = &data->o_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) .rpc_argp = o_arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) .rpc_resp = o_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) .rpc_cred = data->owner->so_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) .rpc_client = server->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) .callback_ops = &nfs4_open_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) .callback_data = data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) .workqueue = nfsiod_workqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) kref_get(&data->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) data->rpc_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) data->rpc_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) data->cancelled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) data->is_recover = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) if (!ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) data->is_recover = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) task_setup_data.flags |= RPC_TASK_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) pnfs_lgopen_prepare(data, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) status = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) data->cancelled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) status = data->rpc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) struct inode *dir = d_inode(data->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) struct nfs_openres *o_res = &data->o_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) status = nfs4_run_open_task(data, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) if (status != 0 || !data->rpc_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) status = _nfs4_proc_open_confirm(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) * Additional permission checks in order to distinguish between an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) * open for read, and an open for execute. This works around the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) * fact that NFSv4 OPEN treats read and execute permissions as being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) * the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) * Note that in the non-execute case, we want to turn off permission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) * checking if we just created a new file (POSIX open() semantics).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) static int nfs4_opendata_access(const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) struct nfs4_opendata *opendata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) struct nfs4_state *state, fmode_t fmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) int openflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) struct nfs_access_entry cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) u32 mask, flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) /* access call failed or for some reason the server doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) * support any access modes -- defer access call until later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) if (opendata->o_res.access_supported == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) * Use openflags to check for exec, because fmode won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) * always have FMODE_EXEC set when file open for exec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) if (openflags & __FMODE_EXEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) /* ONLY check for exec rights */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) if (S_ISDIR(state->inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) mask = NFS4_ACCESS_LOOKUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) mask = NFS4_ACCESS_EXECUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) } else if ((fmode & FMODE_READ) && !opendata->file_created)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) mask = NFS4_ACCESS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) cache.cred = cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) nfs_access_set_mask(&cache, opendata->o_res.access_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) nfs_access_add_cache(state->inode, &cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) flags = NFS4_ACCESS_READ | NFS4_ACCESS_EXECUTE | NFS4_ACCESS_LOOKUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) if ((mask & ~cache.mask & flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) static int _nfs4_proc_open(struct nfs4_opendata *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) struct nfs_open_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) struct inode *dir = d_inode(data->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) struct nfs_openargs *o_arg = &data->o_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) struct nfs_openres *o_res = &data->o_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) status = nfs4_run_open_task(data, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) if (!data->rpc_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) if (status == -NFS4ERR_BADNAME &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) !(o_arg->open_flags & O_CREAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) nfs_fattr_map_and_free_names(server, &data->f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) if (o_arg->open_flags & O_CREAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) if (o_arg->open_flags & O_EXCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) data->file_created = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) else if (o_res->cinfo.before != o_res->cinfo.after)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) data->file_created = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) if (data->file_created ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) inode_peek_iversion_raw(dir) != o_res->cinfo.after)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) nfs4_update_changeattr(dir, &o_res->cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) o_res->f_attr->time_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) server->caps &= ~NFS_CAP_POSIX_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) status = _nfs4_proc_open_confirm(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) nfs4_sequence_free_slot(&o_res->seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) o_res->f_label, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) * OPEN_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) * reclaim state on the server after a network partition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) * Assumes caller holds the appropriate lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) struct nfs4_opendata *opendata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) opendata = nfs4_open_recoverdata_alloc(ctx, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) NFS4_OPEN_CLAIM_FH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) if (IS_ERR(opendata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) return PTR_ERR(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) ret = nfs4_open_recover(opendata, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) if (ret == -ESTALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) d_drop(ctx->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) nfs4_opendata_put(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) struct nfs4_exception exception = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) err = _nfs4_open_expired(ctx, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) trace_nfs4_open_expired(ctx, 0, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) case -NFS4ERR_GRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) ctx = nfs4_state_find_open_context(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) if (IS_ERR(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) ret = nfs4_do_open_expired(ctx, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) put_nfs_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) const nfs4_stateid *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) nfs_remove_bad_delegation(state->inode, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) nfs_state_clear_delegation(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) static void nfs40_clear_delegation_stateid(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) nfs_finish_clear_delegation_stateid(state, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) /* NFSv4.0 doesn't allow for delegation recovery on open expire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) nfs40_clear_delegation_stateid(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) nfs_state_clear_open_state_flags(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) return nfs4_open_expired(sp, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) static int nfs40_test_and_free_expired_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) return -NFS4ERR_BAD_STATEID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) static int nfs41_test_and_free_expired_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) switch (stateid->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) case NFS4_INVALID_STATEID_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) case NFS4_SPECIAL_STATEID_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) return -NFS4ERR_BAD_STATEID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) case NFS4_REVOKED_STATEID_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) status = nfs41_test_stateid(server, stateid, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) case -NFS4ERR_DELEG_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) /* Ack the revoked state to the server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) nfs41_free_stateid(server, stateid, cred, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) return -NFS4ERR_EXPIRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) static int nfs41_check_delegation_stateid(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) nfs4_stateid stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) struct nfs_delegation *delegation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) const struct cred *cred = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) int status, ret = NFS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) /* Get the delegation credential for use by test/free_stateid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) delegation = rcu_dereference(NFS_I(state->inode)->delegation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) if (delegation == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) nfs_state_clear_delegation(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) return NFS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) spin_lock(&delegation->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) nfs4_stateid_copy(&stateid, &delegation->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) &delegation->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) spin_unlock(&delegation->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) return NFS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) if (delegation->cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) cred = get_cred(delegation->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) spin_unlock(&delegation->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) status = nfs41_test_and_free_expired_stateid(server, &stateid, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) trace_nfs4_test_delegation_stateid(state, NULL, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) nfs_finish_clear_delegation_stateid(state, &stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) ret = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) static void nfs41_delegation_recover_stateid(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) nfs4_stateid tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) if (test_bit(NFS_DELEGATED_STATE, &state->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) nfs4_copy_delegation_stateid(state->inode, state->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) &tmp, NULL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) nfs4_stateid_match_other(&state->stateid, &tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) nfs_state_set_delegation(state, &tmp, state->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) nfs_state_clear_delegation(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) * nfs41_check_expired_locks - possibly free a lock stateid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) * @state: NFSv4 state for an inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) * Returns NFS_OK if recovery for this stateid is now finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) * Otherwise a negative NFS4ERR value is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) static int nfs41_check_expired_locks(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) int status, ret = NFS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) struct nfs4_lock_state *lsp, *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) if (!test_bit(LK_STATE_IN_USE, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) spin_lock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) list_for_each_entry(lsp, &state->lock_states, ls_locks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) const struct cred *cred = lsp->ls_state->owner->so_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) refcount_inc(&lsp->ls_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) spin_unlock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) nfs4_put_lock_state(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) prev = lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) status = nfs41_test_and_free_expired_stateid(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) &lsp->ls_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) trace_nfs4_test_lock_stateid(state, lsp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) if (status == -NFS4ERR_EXPIRED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) status == -NFS4ERR_BAD_STATEID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) clear_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) lsp->ls_stateid.type = NFS4_INVALID_STATEID_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) if (!recover_lost_locks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) set_bit(NFS_LOCK_LOST, &lsp->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) } else if (status != NFS_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) ret = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) nfs4_put_lock_state(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) spin_lock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) spin_unlock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) nfs4_put_lock_state(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) * nfs41_check_open_stateid - possibly free an open stateid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) * @state: NFSv4 state for an inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) * Returns NFS_OK if recovery for this stateid is now finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) * Otherwise a negative NFS4ERR value is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) static int nfs41_check_open_stateid(struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) nfs4_stateid *stateid = &state->open_stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) const struct cred *cred = state->owner->so_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) if (test_bit(NFS_OPEN_STATE, &state->flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) return -NFS4ERR_BAD_STATEID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) status = nfs41_test_and_free_expired_stateid(server, stateid, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) trace_nfs4_test_open_stateid(state, NULL, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) nfs_state_clear_open_state_flags(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) stateid->type = NFS4_INVALID_STATEID_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) if (nfs_open_stateid_recover_openmode(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) return -NFS4ERR_OPENMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) return NFS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) status = nfs41_check_delegation_stateid(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) if (status != NFS_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) nfs41_delegation_recover_stateid(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) status = nfs41_check_expired_locks(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) if (status != NFS_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) status = nfs41_check_open_stateid(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (status != NFS_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) status = nfs4_open_expired(sp, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) * on an EXCLUSIVE create, the server should send back a bitmask with FATTR4-*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) * fields corresponding to attributes that were used to store the verifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) * Make sure we clobber those fields in the later setattr call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) static unsigned nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) struct iattr *sattr, struct nfs4_label **label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) const __u32 *bitmask = opendata->o_arg.server->exclcreat_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) __u32 attrset[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) unsigned ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) for (i = 0; i < ARRAY_SIZE(attrset); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) attrset[i] = opendata->o_res.attrset[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) if (opendata->o_arg.createmode == NFS4_CREATE_EXCLUSIVE4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) attrset[i] &= ~bitmask[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) ret = (opendata->o_arg.createmode == NFS4_CREATE_EXCLUSIVE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) sattr->ia_valid : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) if ((attrset[1] & (FATTR4_WORD1_TIME_ACCESS|FATTR4_WORD1_TIME_ACCESS_SET))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) if (sattr->ia_valid & ATTR_ATIME_SET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) ret |= ATTR_ATIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) ret |= ATTR_ATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) if ((attrset[1] & (FATTR4_WORD1_TIME_MODIFY|FATTR4_WORD1_TIME_MODIFY_SET))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) if (sattr->ia_valid & ATTR_MTIME_SET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) ret |= ATTR_MTIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) ret |= ATTR_MTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) if (!(attrset[2] & FATTR4_WORD2_SECURITY_LABEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) *label = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) int flags, struct nfs_open_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) struct nfs4_state_owner *sp = opendata->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) struct nfs_server *server = sp->so_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) struct nfs4_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) struct inode *dir = d_inode(opendata->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) unsigned long dir_verifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) unsigned int seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) dir_verifier = nfs_save_change_attribute(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) ret = _nfs4_proc_open(opendata, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) state = _nfs4_opendata_to_nfs4_state(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) ret = PTR_ERR(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) if (IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) ctx->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) if (server->caps & NFS_CAP_POSIX_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) if (opendata->o_res.rflags & NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) set_bit(NFS_STATE_MAY_NOTIFY_LOCK, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) dentry = opendata->dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) if (d_really_is_negative(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) struct dentry *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) alias = d_exact_alias(dentry, state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) if (!alias)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) alias = d_splice_alias(igrab(state->inode), dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) /* d_splice_alias() can't fail here - it's a non-directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) if (alias) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) dput(ctx->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) ctx->dentry = dentry = alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) switch(opendata->o_arg.claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) case NFS4_OPEN_CLAIM_DELEGATE_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) case NFS4_OPEN_CLAIM_DELEGATE_PREV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) if (!opendata->rpc_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) if (opendata->o_res.delegation_type != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) dir_verifier = nfs_save_change_attribute(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) nfs_set_verifier(dentry, dir_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) /* Parse layoutget results before we check for access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) ret = nfs4_opendata_access(sp->so_cred, opendata, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) acc_mode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) if (d_inode(dentry) == state->inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) nfs_inode_attach_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) nfs4_schedule_stateid_recovery(server, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) if (!opendata->cancelled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) nfs4_sequence_free_slot(&opendata->o_res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) * Returns a referenced nfs4_state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) static int _nfs4_do_open(struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) const struct nfs4_open_createattrs *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) int *opened)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) struct nfs4_state_owner *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) struct nfs4_state *state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) struct nfs4_opendata *opendata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) struct dentry *dentry = ctx->dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) const struct cred *cred = ctx->cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) fmode_t fmode = _nfs4_ctx_to_openmode(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) struct iattr *sattr = c->sattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) struct nfs4_label *label = c->label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) struct nfs4_label *olabel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) /* Protect against reboot recovery conflicts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) sp = nfs4_get_state_owner(server, cred, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) if (sp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) status = nfs4_client_recover_expired_lease(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) goto err_put_state_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) nfs4_return_incompatible_delegation(d_inode(dentry), fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) claim = NFS4_OPEN_CLAIM_FH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) c, claim, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (opendata == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) goto err_put_state_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) if (label) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) olabel = nfs4_label_alloc(server, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) if (IS_ERR(olabel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) status = PTR_ERR(olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) goto err_opendata_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) if (server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) if (!opendata->f_attr.mdsthreshold) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) if (!opendata->f_attr.mdsthreshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) goto err_free_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) opendata->state = nfs4_get_open_state(d_inode(dentry), sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) status = _nfs4_open_and_get_state(opendata, flags, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) goto err_free_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) state = ctx->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) unsigned attrs = nfs4_exclusive_attrset(opendata, sattr, &label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) * send create attributes which was not set by open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) * with an extra setattr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) if (attrs || label) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) unsigned ia_old = sattr->ia_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) sattr->ia_valid = attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) nfs_fattr_init(opendata->o_res.f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) status = nfs4_do_setattr(state->inode, cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) opendata->o_res.f_attr, sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) ctx, label, olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) nfs_setattr_update_inode(state->inode, sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) opendata->o_res.f_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) sattr->ia_valid = ia_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) if (opened && opendata->file_created)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) *opened = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) *ctx_th = opendata->f_attr.mdsthreshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) opendata->f_attr.mdsthreshold = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) nfs4_label_free(olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) nfs4_opendata_put(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) nfs4_put_state_owner(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) err_free_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) nfs4_label_free(olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) err_opendata_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) nfs4_opendata_put(opendata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) err_put_state_owner:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) nfs4_put_state_owner(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) static struct nfs4_state *nfs4_do_open(struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) struct iattr *sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) struct nfs4_label *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) int *opened)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) struct nfs4_state *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) struct nfs4_open_createattrs c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) .label = label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) .sattr = sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) .verf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) [0] = (__u32)jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) [1] = (__u32)current->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) status = _nfs4_do_open(dir, ctx, flags, &c, opened);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) res = ctx->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) trace_nfs4_open_file(ctx, flags, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) /* NOTE: BAD_SEQID means the server and client disagree about the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) * book-keeping w.r.t. state-changing operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) * (OPEN/CLOSE/LOCK/LOCKU...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) * It is actually a sign of a bug on the client or on the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) * If we receive a BAD_SEQID error in the particular case of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) * doing an OPEN, we assume that nfs_increment_open_seqid() will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) * have unhashed the old state_owner for us, and that we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) * therefore safely retry using a new one. We should still warn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) * the user though...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) if (status == -NFS4ERR_BAD_SEQID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) pr_warn_ratelimited("NFS: v4 server %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) " returned a bad sequence-id error!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) NFS_SERVER(dir)->nfs_client->cl_hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) exception.retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) * BAD_STATEID on OPEN means that the server cancelled our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) * state before it received the OPEN_CONFIRM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) * Recover by retrying the request as per the discussion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) * on Page 181 of RFC3530.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) if (status == -NFS4ERR_BAD_STATEID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) exception.retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) if (status == -NFS4ERR_EXPIRED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) nfs4_schedule_lease_recovery(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) exception.retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) if (status == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) /* We must have found a delegation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) exception.retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) if (nfs4_clear_cap_atomic_open_v1(server, status, &exception))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) res = ERR_PTR(nfs4_handle_exception(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) status, &exception));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) static int _nfs4_do_setattr(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) struct nfs_setattrargs *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) struct nfs_setattrres *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) struct nfs_open_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) .rpc_argp = arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) .rpc_resp = res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) const struct cred *delegation_cred = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) unsigned long timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) bool truncate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) nfs_fattr_init(res->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) /* Servers should only apply open mode checks for file size changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) truncate = (arg->iap->ia_valid & ATTR_SIZE) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) if (!truncate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) nfs4_inode_make_writeable(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) goto zero_stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) if (nfs4_copy_delegation_stateid(inode, FMODE_WRITE, &arg->stateid, &delegation_cred)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) /* Use that stateid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) } else if (ctx != NULL && ctx->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) struct nfs_lock_context *l_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) if (!nfs4_valid_open_stateid(ctx->state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) l_ctx = nfs_get_lock_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) if (IS_ERR(l_ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) return PTR_ERR(l_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) status = nfs4_select_rw_stateid(ctx->state, FMODE_WRITE, l_ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) &arg->stateid, &delegation_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) nfs_put_lock_context(l_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) if (status == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) else if (status == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) goto zero_stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) zero_stateid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) nfs4_stateid_copy(&arg->stateid, &zero_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) if (delegation_cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) msg.rpc_cred = delegation_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) status = nfs4_call_sync(server->client, server, &msg, &arg->seq_args, &res->seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) put_cred(delegation_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) if (status == 0 && ctx != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) renew_lease(server, timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) trace_nfs4_setattr(inode, &arg->stateid, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) struct nfs_fattr *fattr, struct iattr *sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) struct nfs_open_context *ctx, struct nfs4_label *ilabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) struct nfs4_label *olabel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) __u32 bitmask[NFS4_BITMASK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) struct nfs4_state *state = ctx ? ctx->state : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) struct nfs_setattrargs arg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) .iap = sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) .label = ilabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) struct nfs_setattrres res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) .fattr = fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) .label = olabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) .state = state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) .inode = inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) .stateid = &arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) nfs4_bitmap_copy_adjust_setattr(bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) nfs4_bitmask(server, olabel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) err = _nfs4_do_setattr(inode, &arg, &res, cred, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) case -NFS4ERR_OPENMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) if (!(sattr->ia_valid & ATTR_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) pr_warn_once("NFSv4: server %s is incorrectly "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) "applying open mode checks to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) "a SETATTR that is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) "changing file size.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) server->nfs_client->cl_hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) if (state && !(state->state & FMODE_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) err = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) if (sattr->ia_valid & ATTR_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) err = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) err = nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) nfs4_wait_on_layoutreturn(struct inode *inode, struct rpc_task *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) if (inode == NULL || !nfs_have_layout(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) return pnfs_wait_on_layoutreturn(inode, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) * Update the seqid of an open stateid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) static void nfs4_sync_open_stateid(nfs4_stateid *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) __be32 seqid_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) u32 dst_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) int seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) if (!nfs4_valid_open_stateid(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) seq = read_seqbegin(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) if (!nfs4_state_match_open_stateid_other(state, dst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) nfs4_stateid_copy(dst, &state->open_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) if (read_seqretry(&state->seqlock, seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) seqid_open = state->open_stateid.seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) if (read_seqretry(&state->seqlock, seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) dst_seqid = be32_to_cpu(dst->seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) if ((s32)(dst_seqid - be32_to_cpu(seqid_open)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) dst->seqid = seqid_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) * Update the seqid of an open stateid after receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) * NFS4ERR_OLD_STATEID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) static bool nfs4_refresh_open_old_stateid(nfs4_stateid *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) struct nfs4_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) __be32 seqid_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) u32 dst_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) int seq, status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) if (!nfs4_valid_open_stateid(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) seq = read_seqbegin(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) if (!nfs4_state_match_open_stateid_other(state, dst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) if (read_seqretry(&state->seqlock, seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) write_seqlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) seqid_open = state->open_stateid.seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) dst_seqid = be32_to_cpu(dst->seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) /* Did another OPEN bump the state's seqid? try again: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) if ((s32)(be32_to_cpu(seqid_open) - dst_seqid) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) dst->seqid = seqid_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) /* server says we're behind but we haven't seen the update yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) set_bit(NFS_STATE_CHANGE_WAIT, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) prepare_to_wait(&state->waitq, &wait, TASK_KILLABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) write_sequnlock(&state->seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) trace_nfs4_close_stateid_update_wait(state->inode, dst, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) if (fatal_signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) status = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) if (schedule_timeout(5*HZ) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) finish_wait(&state->waitq, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) if (status == -EINTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) /* we slept the whole 5 seconds, we must have lost a seqid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) dst->seqid = cpu_to_be32(dst_seqid + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) struct nfs4_closedata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) struct nfs4_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) struct nfs_closeargs arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) struct nfs_closeres res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) struct nfs4_layoutreturn_args arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) struct nfs4_layoutreturn_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) struct nfs4_xdr_opaque_data ld_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) u32 roc_barrier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) bool roc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) } lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) struct nfs_fattr fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) unsigned long timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) static void nfs4_free_closedata(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) struct nfs4_closedata *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) struct nfs4_state_owner *sp = calldata->state->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) struct super_block *sb = calldata->state->inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) if (calldata->lr.roc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) pnfs_roc_release(&calldata->lr.arg, &calldata->lr.res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) calldata->res.lr_ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) nfs4_put_open_state(calldata->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) nfs_free_seqid(calldata->arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) nfs4_put_state_owner(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) nfs_sb_deactive(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) static void nfs4_close_done(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) struct nfs4_closedata *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) struct nfs4_state *state = calldata->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) struct nfs_server *server = NFS_SERVER(calldata->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) nfs4_stateid *res_stateid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) .state = state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) .inode = calldata->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) .stateid = &calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) dprintk("%s: begin!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) if (!nfs4_sequence_done(task, &calldata->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) /* Handle Layoutreturn errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) if (pnfs_roc_done(task, &calldata->arg.lr_args, &calldata->res.lr_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) &calldata->res.lr_ret) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) /* hmm. we are done with the inode, and in the process of freeing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) * the state_owner. we keep this around to process errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) res_stateid = &calldata->res.stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) renew_lease(server, calldata->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) case -NFS4ERR_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) if (calldata->arg.bitmask != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) calldata->arg.bitmask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) calldata->res.fattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) case -NFS4ERR_OLD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) /* Did we race with OPEN? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) if (nfs4_refresh_open_old_stateid(&calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) nfs4_free_revoked_stateid(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) &calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) task->tk_msg.rpc_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) if (calldata->arg.fmode == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) task->tk_status = nfs4_async_handle_exception(task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) server, task->tk_status, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) if (exception.retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) nfs_clear_open_stateid(state, &calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) res_stateid, calldata->arg.fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) nfs_release_seqid(calldata->arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) nfs_refresh_inode(calldata->inode, &calldata->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) out_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) static void nfs4_close_prepare(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) struct nfs4_closedata *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) struct nfs4_state *state = calldata->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) struct inode *inode = calldata->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) struct pnfs_layout_hdr *lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) bool is_rdonly, is_wronly, is_rdwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) int call_close = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) dprintk("%s: begin!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) goto out_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) spin_lock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) /* Calculate the change in open mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) calldata->arg.fmode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) if (state->n_rdwr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) if (state->n_rdonly == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) call_close |= is_rdonly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) else if (is_rdonly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) calldata->arg.fmode |= FMODE_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) if (state->n_wronly == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) call_close |= is_wronly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) else if (is_wronly)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) calldata->arg.fmode |= FMODE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) if (calldata->arg.fmode != (FMODE_READ|FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) call_close |= is_rdwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) } else if (is_rdwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) nfs4_sync_open_stateid(&calldata->arg.stateid, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) if (!nfs4_valid_open_stateid(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) call_close = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) spin_unlock(&state->owner->so_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) if (!call_close) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) /* Note: exit _without_ calling nfs4_close_done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) goto out_no_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) if (!calldata->lr.roc && nfs4_wait_on_layoutreturn(inode, task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) nfs_release_seqid(calldata->arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) goto out_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) lo = calldata->arg.lr_args ? calldata->arg.lr_args->layout : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) if (lo && !pnfs_layout_is_valid(lo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) calldata->arg.lr_args = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) calldata->res.lr_res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) if (calldata->arg.fmode == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) if (calldata->arg.fmode == 0 || calldata->arg.fmode == FMODE_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) /* Close-to-open cache consistency revalidation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) if (!nfs4_have_delegation(inode, FMODE_READ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) nfs4_bitmask_set(calldata->arg.bitmask_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) server->cache_consistency_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) inode, server, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) calldata->arg.bitmask = calldata->arg.bitmask_store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) calldata->arg.bitmask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) calldata->arg.share_access =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) nfs4_map_atomic_open_share(NFS_SERVER(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) calldata->arg.fmode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) if (calldata->res.fattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) calldata->arg.bitmask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) else if (calldata->arg.bitmask == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) calldata->res.fattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) calldata->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) if (nfs4_setup_sequence(NFS_SERVER(inode)->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) &calldata->arg.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) &calldata->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) task) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) nfs_release_seqid(calldata->arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) dprintk("%s: done!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) out_no_action:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) task->tk_action = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) out_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) nfs4_sequence_done(task, &calldata->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) static const struct rpc_call_ops nfs4_close_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) .rpc_call_prepare = nfs4_close_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) .rpc_call_done = nfs4_close_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) .rpc_release = nfs4_free_closedata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) * It is possible for data to be read/written from a mem-mapped file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) * after the sys_close call (which hits the vfs layer as a flush).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) * This means that we can't safely call nfsv4 close on a file until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) * the inode is cleared. This in turn means that we are not good
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) * NFSv4 citizens - we do not indicate to the server to update the file's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) * share state even when we are done with one of the three share
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) * stateid's in the inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) * NOTE: Caller must be holding the sp->so_owner semaphore!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) struct nfs4_closedata *calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) struct nfs4_state_owner *sp = state->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) .rpc_cred = state->owner->so_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) .rpc_client = server->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) .callback_ops = &nfs4_close_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) .workqueue = nfsiod_workqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) &task_setup_data.rpc_client, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) calldata = kzalloc(sizeof(*calldata), gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) if (calldata == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) nfs4_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) calldata->inode = state->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) calldata->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) calldata->arg.fh = NFS_FH(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) if (!nfs4_copy_open_stateid(&calldata->arg.stateid, state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) goto out_free_calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) /* Serialization for the sequence id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) alloc_seqid = server->nfs_client->cl_mvops->alloc_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) calldata->arg.seqid = alloc_seqid(&state->owner->so_seqid, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) if (IS_ERR(calldata->arg.seqid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) goto out_free_calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) nfs_fattr_init(&calldata->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) calldata->arg.fmode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) calldata->lr.arg.ld_private = &calldata->lr.ld_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) calldata->res.fattr = &calldata->fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) calldata->res.seqid = calldata->arg.seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) calldata->res.server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) calldata->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) calldata->lr.roc = pnfs_roc(state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) &calldata->lr.arg, &calldata->lr.res, msg.rpc_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) if (calldata->lr.roc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) calldata->arg.lr_args = &calldata->lr.arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) calldata->res.lr_res = &calldata->lr.res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) nfs_sb_active(calldata->inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) msg.rpc_argp = &calldata->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) msg.rpc_resp = &calldata->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) task_setup_data.callback_data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) status = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) out_free_calldata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) nfs4_put_open_state(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) nfs4_put_state_owner(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) static struct inode *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) int open_flags, struct iattr *attr, int *opened)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) struct nfs4_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) /* Protect against concurrent sillydeletes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) state = nfs4_do_open(dir, ctx, open_flags, attr, label, opened);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) nfs4_label_release_security(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) if (IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) return ERR_CAST(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) return state->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) if (ctx->state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) if (is_sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) nfs4_close_sync(ctx->state, _nfs4_ctx_to_openmode(ctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) nfs4_close_state(ctx->state, _nfs4_ctx_to_openmode(ctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) #define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_XATTR_SUPPORT - 1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) u32 bitmask[3] = {}, minorversion = server->nfs_client->cl_minorversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) struct nfs4_server_caps_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) .fhandle = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) struct nfs4_server_caps_res res = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) bitmask[0] = FATTR4_WORD0_SUPPORTED_ATTRS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) FATTR4_WORD0_FH_EXPIRE_TYPE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) FATTR4_WORD0_LINK_SUPPORT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) FATTR4_WORD0_SYMLINK_SUPPORT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) FATTR4_WORD0_ACLSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) if (minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) bitmask[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) /* Sanity check the server answers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) switch (minorversion) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) res.attr_bitmask[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) res.attr_bitmask[2] &= FATTR4_WORD2_NFS41_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) NFS_CAP_CTIME|NFS_CAP_MTIME|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) NFS_CAP_SECURITY_LABEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) if (res.attr_bitmask[0] & FATTR4_WORD0_ACL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) server->caps |= NFS_CAP_ACLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) if (res.has_links != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) server->caps |= NFS_CAP_HARDLINKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) if (res.has_symlinks != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) server->caps |= NFS_CAP_SYMLINKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) if (res.attr_bitmask[0] & FATTR4_WORD0_FILEID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) server->caps |= NFS_CAP_FILEID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) if (res.attr_bitmask[1] & FATTR4_WORD1_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) server->caps |= NFS_CAP_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) if (res.attr_bitmask[1] & FATTR4_WORD1_NUMLINKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) server->caps |= NFS_CAP_NLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) if (res.attr_bitmask[1] & FATTR4_WORD1_OWNER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) server->caps |= NFS_CAP_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) if (res.attr_bitmask[1] & FATTR4_WORD1_OWNER_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) server->caps |= NFS_CAP_OWNER_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_ACCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) server->caps |= NFS_CAP_ATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_METADATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) server->caps |= NFS_CAP_CTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) server->caps |= NFS_CAP_MTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) #ifdef CONFIG_NFS_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) server->caps |= NFS_CAP_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) memcpy(server->attr_bitmask_nl, res.attr_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) sizeof(server->attr_bitmask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) server->cache_consistency_bitmask[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) /* Avoid a regression due to buggy server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) for (i = 0; i < ARRAY_SIZE(res.exclcreat_bitmask); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) res.exclcreat_bitmask[i] &= res.attr_bitmask[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) memcpy(server->exclcreat_bitmask, res.exclcreat_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) sizeof(server->exclcreat_bitmask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) server->acl_bitmask = res.acl_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) server->fh_expire_type = res.fh_expire_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) err = nfs4_handle_exception(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) _nfs4_server_capabilities(server, fhandle),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) struct nfs_fsinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) u32 bitmask[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) struct nfs4_lookup_root_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) struct nfs4_lookup_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) .fattr = info->fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) .fh = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP_ROOT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) bitmask[0] = nfs4_fattr_bitmap[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) bitmask[1] = nfs4_fattr_bitmap[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) * Process the label in the upcoming getfattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) bitmask[2] = nfs4_fattr_bitmap[2] & ~FATTR4_WORD2_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) nfs_fattr_init(info->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) struct nfs_fsinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) err = _nfs4_lookup_root(server, fhandle, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) trace_nfs4_lookup_root(server, fhandle, info->fattr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) case -NFS4ERR_WRONGSEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) err = nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) struct nfs_fsinfo *info, rpc_authflavor_t flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) struct rpc_auth_create_args auth_args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) .pseudoflavor = flavor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) struct rpc_auth *auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) auth = rpcauth_create(&auth_args, server->client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) if (IS_ERR(auth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) return nfs4_lookup_root(server, fhandle, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) * Retry pseudoroot lookup with various security flavors. We do this when:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) * NFSv4.0: the PUTROOTFH operation returns NFS4ERR_WRONGSEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) * NFSv4.1: the server does not support the SECINFO_NO_NAME operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) * Returns zero on success, or a negative NFS4ERR value, or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) * negative errno value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) struct nfs_fsinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) /* Per 3530bis 15.33.5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) static const rpc_authflavor_t flav_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) RPC_AUTH_GSS_KRB5P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) RPC_AUTH_GSS_KRB5I,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) RPC_AUTH_GSS_KRB5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) RPC_AUTH_UNIX, /* courtesy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) RPC_AUTH_NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) int status = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) if (server->auth_info.flavor_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) /* try each flavor specified by user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) for (i = 0; i < server->auth_info.flavor_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) status = nfs4_lookup_root_sec(server, fhandle, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) server->auth_info.flavors[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) /* no flavors specified by user, try default list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) for (i = 0; i < ARRAY_SIZE(flav_array); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) status = nfs4_lookup_root_sec(server, fhandle, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) flav_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) * -EACCES could mean that the user doesn't have correct permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) * to access the mount. It could also mean that we tried to mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) * with a gss auth flavor, but rpc.gssd isn't running. Either way,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) * existing mount programs don't handle -EACCES very well so it should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) * be mapped to -EPERM instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) if (status == -EACCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) status = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) * nfs4_proc_get_rootfh - get file handle for server's pseudoroot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) * @server: initialized nfs_server handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) * @fhandle: we fill in the pseudo-fs root file handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) * @info: we fill in an FSINFO struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) * @auth_probe: probe the auth flavours
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) * Returns zero on success, or a negative errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) struct nfs_fsinfo *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) bool auth_probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) if (!auth_probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) status = nfs4_lookup_root(server, fhandle, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) if (auth_probe || status == NFS4ERR_WRONGSEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) status = server->nfs_client->cl_mvops->find_root_sec(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) fhandle, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) status = nfs4_server_capabilities(server, fhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) status = nfs4_do_fsinfo(server, fhandle, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) return nfs4_map_errors(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) struct nfs_fsinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) struct nfs_fattr *fattr = info->fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) struct nfs4_label *label = fattr->label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) error = nfs4_server_capabilities(server, mntfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) dprintk("nfs4_get_root: getcaps error = %d\n", -error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) error = nfs4_proc_getattr(server, mntfh, fattr, label, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) dprintk("nfs4_get_root: getattr error = %d\n", -error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) if (fattr->valid & NFS_ATTR_FATTR_FSID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) !nfs_fsid_equal(&server->fsid, &fattr->fsid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) * Get locations and (maybe) other attributes of a referral.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) * Note that we'll actually follow the referral later when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) * we detect fsid mismatch in inode revalidation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) const struct qstr *name, struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) struct nfs_fh *fhandle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) struct page *page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) struct nfs4_fs_locations *locations = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) page = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) if (page == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) if (locations == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) status = nfs4_proc_fs_locations(client, dir, name, locations, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) * If the fsid didn't change, this is a migration event, not a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) * referral. Cause us to drop into the exception handler, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) * will kick off migration recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) dprintk("%s: server did not return a different fsid for"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) " a referral at %s\n", __func__, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) status = -NFS4ERR_MOVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) nfs_fixup_referral_attributes(&locations->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) /* replace the lookup nfs_fattr with the locations nfs_fattr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) memset(fhandle, 0, sizeof(struct nfs_fh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) if (page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) __free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) kfree(locations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) struct nfs_fattr *fattr, struct nfs4_label *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) __u32 bitmask[NFS4_BITMASK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) struct nfs4_getattr_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) .fh = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) struct nfs4_getattr_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) .fattr = fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) .label = label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETATTR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) unsigned short task_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) /* Is this is an attribute revalidation, subject to softreval? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) task_flags |= RPC_TASK_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) nfs_fattr_init(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) return nfs4_do_call_sync(server->client, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) &args.seq_args, &res.seq_res, task_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) struct nfs_fattr *fattr, struct nfs4_label *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) err = _nfs4_proc_getattr(server, fhandle, fattr, label, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) trace_nfs4_getattr(server, fhandle, fattr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) err = nfs4_handle_exception(server, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) * The file is not closed if it is opened due to the a request to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) * the size of the file. The open call will not be needed once the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) * VFS layer lookup-intents are implemented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) * Close is called when the inode is destroyed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) * If we haven't opened the file for O_WRONLY, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) * need to in the size_change case to obtain a stateid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) * Got race?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) * Because OPEN is always done by name in nfsv4, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) * possible that we opened a different file by the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) * name. We can recognize this race condition, but we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) * can't do anything about it besides returning an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) * This will be fixed with VFS changes (lookup-intent).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) struct iattr *sattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) const struct cred *cred = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) struct nfs_open_context *ctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) struct nfs4_label *label = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) if (pnfs_ld_layoutret_on_setattr(inode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) sattr->ia_valid & ATTR_SIZE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) sattr->ia_size < i_size_read(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) pnfs_commit_and_return_layout(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) nfs_fattr_init(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) /* Deal with open(O_TRUNC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) if (sattr->ia_valid & ATTR_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) /* Optimization: if the end result is no change, don't RPC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) if ((sattr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) /* Search for an existing open(O_WRITE) file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) if (sattr->ia_valid & ATTR_FILE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) ctx = nfs_file_open_context(sattr->ia_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) if (ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) cred = ctx->cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) if (IS_ERR(label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) return PTR_ERR(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) /* Return any delegations if we're going to change ACLs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) if ((sattr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) nfs4_inode_make_writeable(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) status = nfs4_do_setattr(inode, cred, fattr, sattr, ctx, NULL, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) nfs_setattr_update_inode(inode, sattr, fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) nfs_setsecurity(inode, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) nfs4_label_free(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) struct dentry *dentry, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) struct nfs_fattr *fattr, struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) struct nfs4_lookup_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) .bitmask = server->attr_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) .dir_fh = NFS_FH(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) .name = &dentry->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) struct nfs4_lookup_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) .fattr = fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) .label = label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) .fh = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) unsigned short task_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) /* Is this is an attribute revalidation, subject to softreval? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) if (nfs_lookup_is_soft_revalidate(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) task_flags |= RPC_TASK_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) args.bitmask = nfs4_bitmask(server, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) nfs_fattr_init(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) dprintk("NFS call lookup %pd2\n", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) status = nfs4_do_call_sync(clnt, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) &args.seq_args, &res.seq_res, task_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) dprintk("NFS reply lookup: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_MOUNTPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) fattr->nlink = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) struct dentry *dentry, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) struct nfs_fattr *fattr, struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) struct rpc_clnt *client = *clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) const struct qstr *name = &dentry->d_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) trace_nfs4_lookup(dir, name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) case -NFS4ERR_BADNAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) case -NFS4ERR_MOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) err = nfs4_get_referral(client, dir, name, fattr, fhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) if (err == -NFS4ERR_MOVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) err = nfs4_handle_exception(NFS_SERVER(dir), err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) case -NFS4ERR_WRONGSEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) if (client != *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) client = nfs4_negotiate_security(client, dir, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) if (IS_ERR(client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) return PTR_ERR(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) exception.retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) err = nfs4_handle_exception(NFS_SERVER(dir), err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) *clnt = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) else if (client != *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) rpc_shutdown_client(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) static int nfs4_proc_lookup(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) struct nfs_fh *fhandle, struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) struct rpc_clnt *client = NFS_CLIENT(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) if (client != NFS_CLIENT(dir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) rpc_shutdown_client(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) nfs_fixup_secinfo_attributes(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) struct rpc_clnt *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) nfs4_proc_lookup_mountpoint(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) struct nfs_fh *fhandle, struct nfs_fattr *fattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) struct rpc_clnt *client = NFS_CLIENT(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) return ERR_PTR(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) static int _nfs4_proc_lookupp(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) struct nfs_fh *fhandle, struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) struct rpc_clnt *clnt = NFS_CLIENT(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) struct nfs4_lookupp_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) .bitmask = server->attr_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) struct nfs4_lookupp_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) .fattr = fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) .label = label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) .fh = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUPP],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) args.bitmask = nfs4_bitmask(server, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) nfs_fattr_init(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) dprintk("NFS call lookupp ino=0x%lx\n", inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) dprintk("NFS reply lookupp: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) struct nfs_fattr *fattr, struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) trace_nfs4_lookupp(inode, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) err = nfs4_handle_exception(NFS_SERVER(inode), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) struct nfs4_accessargs args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) .access = entry->mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) struct nfs4_accessres res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) .rpc_cred = entry->cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) if (!nfs4_have_delegation(inode, FMODE_READ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) res.fattr = nfs_alloc_fattr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) if (res.fattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) args.bitmask = server->cache_consistency_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) nfs_access_set_mask(entry, res.access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) if (res.fattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) nfs_refresh_inode(inode, res.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) nfs_free_fattr(res.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) err = _nfs4_proc_access(inode, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) trace_nfs4_access(inode, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) err = nfs4_handle_exception(NFS_SERVER(inode), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) * TODO: For the time being, we don't try to get any attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) * along with any of the zero-copy operations READ, READDIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) * READLINK, WRITE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) * In the case of the first three, we want to put the GETATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) * after the read-type operation -- this is because it is hard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) * to predict the length of a GETATTR response in v4, and thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) * align the READ data correctly. This means that the GETATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) * may end up partially falling into the page cache, and we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) * shift it into the 'tail' of the xdr_buf before processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) * To do this efficiently, we need to know the total length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) * of data received, which doesn't seem to be available outside
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) * of the RPC layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) * In the case of WRITE, we also want to put the GETATTR after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) * the operation -- in this case because we want to make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) * we get the post-operation mtime and size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) * Both of these changes to the XDR layer would in fact be quite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) * minor, but I decided to leave them for a subsequent patch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) unsigned int pgbase, unsigned int pglen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) struct nfs4_readlink args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) .pgbase = pgbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) .pglen = pglen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) .pages = &page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) struct nfs4_readlink_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) return nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) static int nfs4_proc_readlink(struct inode *inode, struct page *page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) unsigned int pgbase, unsigned int pglen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) err = _nfs4_proc_readlink(inode, page, pgbase, pglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) trace_nfs4_readlink(inode, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) err = nfs4_handle_exception(NFS_SERVER(inode), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) * This is just for mknod. open(O_CREAT) will always do ->open_context().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) struct nfs4_label l, *ilabel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) struct nfs4_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) ctx = alloc_nfs_open_context(dentry, FMODE_READ, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) if (IS_ERR(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) return PTR_ERR(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) ilabel = nfs4_label_init_security(dir, dentry, sattr, &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) sattr->ia_mode &= ~current_umask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) if (IS_ERR(state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) status = PTR_ERR(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) nfs4_label_release_security(ilabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) put_nfs_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) _nfs4_proc_remove(struct inode *dir, const struct qstr *name, u32 ftype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) struct nfs_removeargs args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) .fh = NFS_FH(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) .name = *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) struct nfs_removeres res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) unsigned long timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) spin_lock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) nfs4_update_changeattr_locked(dir, &res.cinfo, timestamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) /* Removing a directory decrements nlink in the parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) if (ftype == NF4DIR && dir->i_nlink > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) nfs4_dec_nlink_locked(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) spin_unlock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) static int nfs4_proc_remove(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) if (inode->i_nlink == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) nfs4_inode_return_delegation(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) nfs4_inode_make_writeable(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) err = _nfs4_proc_remove(dir, &dentry->d_name, NF4REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) trace_nfs4_remove(dir, &dentry->d_name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) err = nfs4_handle_exception(NFS_SERVER(dir), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) static int nfs4_proc_rmdir(struct inode *dir, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) err = _nfs4_proc_remove(dir, name, NF4DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) trace_nfs4_remove(dir, name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) err = nfs4_handle_exception(NFS_SERVER(dir), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) static void nfs4_proc_unlink_setup(struct rpc_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) struct nfs_removeargs *args = msg->rpc_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) struct nfs_removeres *res = msg->rpc_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) res->server = NFS_SB(dentry->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) nfs4_init_sequence(&args->seq_args, &res->seq_res, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) nfs_fattr_init(res->dir_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) if (inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) nfs4_inode_return_delegation(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) nfs4_setup_sequence(NFS_SB(data->dentry->d_sb)->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) &data->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) &data->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) struct nfs_unlinkdata *data = task->tk_calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) struct nfs_removeres *res = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) if (!nfs4_sequence_done(task, &res->seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) if (nfs4_async_handle_error(task, res->server, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) &data->timeout) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) if (task->tk_status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) nfs4_update_changeattr(dir, &res->cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) res->dir_attr->time_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) static void nfs4_proc_rename_setup(struct rpc_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) struct dentry *new_dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) struct nfs_renameargs *arg = msg->rpc_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) struct nfs_renameres *res = msg->rpc_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) struct inode *old_inode = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) struct inode *new_inode = d_inode(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) if (old_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) nfs4_inode_make_writeable(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) if (new_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) nfs4_inode_return_delegation(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) res->server = NFS_SB(old_dentry->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) nfs4_setup_sequence(NFS_SERVER(data->old_dir)->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) &data->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) &data->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) struct inode *new_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) struct nfs_renamedata *data = task->tk_calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) struct nfs_renameres *res = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) if (!nfs4_sequence_done(task, &res->seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) if (nfs4_async_handle_error(task, res->server, NULL, &data->timeout) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) if (task->tk_status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) if (new_dir != old_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) /* Note: If we moved a directory, nlink will change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) nfs4_update_changeattr(old_dir, &res->old_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) res->old_fattr->time_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) NFS_INO_INVALID_OTHER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) nfs4_update_changeattr(new_dir, &res->new_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) res->new_fattr->time_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) NFS_INO_INVALID_OTHER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) nfs4_update_changeattr(old_dir, &res->old_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) res->old_fattr->time_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) __u32 bitmask[NFS4_BITMASK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) struct nfs4_link_arg arg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) .dir_fh = NFS_FH(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) .name = name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) struct nfs4_link_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) .label = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) .rpc_argp = &arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) res.fattr = nfs_alloc_fattr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) if (res.fattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) res.label = nfs4_label_alloc(server, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) if (IS_ERR(res.label)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) status = PTR_ERR(res.label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) nfs4_inode_make_writeable(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) nfs4_bitmap_copy_adjust_setattr(bitmask, nfs4_bitmask(server, res.label), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) nfs4_update_changeattr(dir, &res.cinfo, res.fattr->time_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) status = nfs_post_op_update_inode(inode, res.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) nfs_setsecurity(inode, res.fattr, res.label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) nfs4_label_free(res.label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) nfs_free_fattr(res.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) static int nfs4_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) err = nfs4_handle_exception(NFS_SERVER(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) _nfs4_proc_link(inode, dir, name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) struct nfs4_createdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) struct rpc_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) struct nfs4_create_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) struct nfs4_create_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) struct nfs_fh fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) struct nfs_fattr fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) struct nfs4_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) const struct qstr *name, struct iattr *sattr, u32 ftype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) struct nfs4_createdata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) if (data != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) data->label = nfs4_label_alloc(server, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) if (IS_ERR(data->label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) data->msg.rpc_argp = &data->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) data->msg.rpc_resp = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) data->arg.dir_fh = NFS_FH(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) data->arg.server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) data->arg.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) data->arg.attrs = sattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) data->arg.ftype = ftype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) data->arg.bitmask = nfs4_bitmask(server, data->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) data->arg.umask = current_umask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) data->res.server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) data->res.fh = &data->fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) data->res.fattr = &data->fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) data->res.label = data->label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) nfs_fattr_init(data->res.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) int status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) &data->arg.seq_args, &data->res.seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) spin_lock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) nfs4_update_changeattr_locked(dir, &data->res.dir_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) data->res.fattr->time_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) NFS_INO_INVALID_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) /* Creating a directory bumps nlink in the parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) if (data->arg.ftype == NF4DIR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) nfs4_inc_nlink_locked(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) spin_unlock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) static void nfs4_free_createdata(struct nfs4_createdata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) nfs4_label_free(data->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) struct page *page, unsigned int len, struct iattr *sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) struct nfs4_createdata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) int status = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) if (len > NFS4_MAXPATHLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4LNK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) data->arg.u.symlink.pages = &page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) data->arg.u.symlink.len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) data->arg.label = label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) status = nfs4_do_create(dir, dentry, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) nfs4_free_createdata(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) struct page *page, unsigned int len, struct iattr *sattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) struct nfs4_label l, *label = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) label = nfs4_label_init_security(dir, dentry, sattr, &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) err = _nfs4_proc_symlink(dir, dentry, page, len, sattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) trace_nfs4_symlink(dir, &dentry->d_name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) err = nfs4_handle_exception(NFS_SERVER(dir), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) nfs4_label_release_security(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) struct iattr *sattr, struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) struct nfs4_createdata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) data->arg.label = label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) status = nfs4_do_create(dir, dentry, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) nfs4_free_createdata(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) struct iattr *sattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) struct nfs4_label l, *label = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) label = nfs4_label_init_security(dir, dentry, sattr, &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) sattr->ia_mode &= ~current_umask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) err = _nfs4_proc_mkdir(dir, dentry, sattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) trace_nfs4_mkdir(dir, &dentry->d_name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) err = nfs4_handle_exception(NFS_SERVER(dir), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) nfs4_label_release_security(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) static int _nfs4_proc_readdir(struct dentry *dentry, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) u64 cookie, struct page **pages, unsigned int count, bool plus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) struct inode *dir = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) struct nfs4_readdir_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) .fh = NFS_FH(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) .pages = pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) .pgbase = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) .count = count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) .plus = plus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) struct nfs4_readdir_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READDIR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) dprintk("%s: dentry = %pd2, cookie = %Lu\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) (unsigned long long)cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) if (!(server->caps & NFS_CAP_SECURITY_LABEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) args.bitmask = server->attr_bitmask_nl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) args.bitmask = server->attr_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) nfs4_setup_readdir(cookie, NFS_I(dir)->cookieverf, dentry, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) res.pgbase = args.pgbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) status = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) if (status >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) memcpy(NFS_I(dir)->cookieverf, res.verifier.data, NFS4_VERIFIER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) status += args.pgbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) nfs_invalidate_atime(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) dprintk("%s: returns %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) static int nfs4_proc_readdir(struct dentry *dentry, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) u64 cookie, struct page **pages, unsigned int count, bool plus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) err = _nfs4_proc_readdir(dentry, cred, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) pages, count, plus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) trace_nfs4_readdir(d_inode(dentry), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) err = nfs4_handle_exception(NFS_SERVER(d_inode(dentry)), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) struct iattr *sattr, struct nfs4_label *label, dev_t rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) struct nfs4_createdata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) int mode = sattr->ia_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4SOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) if (S_ISFIFO(mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) data->arg.ftype = NF4FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) else if (S_ISBLK(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) data->arg.ftype = NF4BLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) data->arg.u.device.specdata1 = MAJOR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) data->arg.u.device.specdata2 = MINOR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) else if (S_ISCHR(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) data->arg.ftype = NF4CHR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) data->arg.u.device.specdata1 = MAJOR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) data->arg.u.device.specdata2 = MINOR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) } else if (!S_ISSOCK(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) data->arg.label = label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) status = nfs4_do_create(dir, dentry, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) nfs4_free_createdata(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) struct iattr *sattr, dev_t rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) struct nfs4_label l, *label = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) label = nfs4_label_init_security(dir, dentry, sattr, &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) sattr->ia_mode &= ~current_umask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) trace_nfs4_mknod(dir, &dentry->d_name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) err = nfs4_handle_exception(NFS_SERVER(dir), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) nfs4_label_release_security(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) struct nfs_fsstat *fsstat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) struct nfs4_statfs_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) .fh = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) .bitmask = server->attr_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) struct nfs4_statfs_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) .fsstat = fsstat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) nfs_fattr_init(fsstat->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) err = nfs4_handle_exception(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) _nfs4_proc_statfs(server, fhandle, fsstat),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) struct nfs_fsinfo *fsinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) struct nfs4_fsinfo_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) .fh = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) .bitmask = server->attr_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) struct nfs4_fsinfo_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) .fsinfo = fsinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) err = _nfs4_do_fsinfo(server, fhandle, fsinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) nfs4_set_lease_period(server->nfs_client, fsinfo->lease_time * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) err = nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) nfs_fattr_init(fsinfo->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) error = nfs4_do_fsinfo(server, fhandle, fsinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) if (error == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) /* block layout checks this! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) server->pnfs_blksize = fsinfo->blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) set_pnfs_layoutdriver(server, fhandle, fsinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) struct nfs_pathconf *pathconf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) struct nfs4_pathconf_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) .fh = fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) .bitmask = server->attr_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) struct nfs4_pathconf_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) .pathconf = pathconf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) /* None of the pathconf attributes are mandatory to implement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) if ((args.bitmask[0] & nfs4_pathconf_bitmap[0]) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) memset(pathconf, 0, sizeof(*pathconf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) nfs_fattr_init(pathconf->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) struct nfs_pathconf *pathconf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) err = nfs4_handle_exception(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) _nfs4_proc_pathconf(server, fhandle, pathconf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) int nfs4_set_rw_stateid(nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) const struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) const struct nfs_lock_context *l_ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) return nfs4_select_rw_stateid(ctx->state, fmode, l_ctx, stateid, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) EXPORT_SYMBOL_GPL(nfs4_set_rw_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) static bool nfs4_stateid_is_current(nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) const struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) const struct nfs_lock_context *l_ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) fmode_t fmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) nfs4_stateid _current_stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) /* If the current stateid represents a lost lock, then exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) if (nfs4_set_rw_stateid(&_current_stateid, ctx, l_ctx, fmode) == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) return nfs4_stateid_match(stateid, &_current_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) static bool nfs4_error_stateid_expired(int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) case -NFS4ERR_DELEG_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) case -NFS4ERR_OLD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) case -NFS4ERR_OPENMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_pgio_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) struct nfs_server *server = NFS_SERVER(hdr->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) trace_nfs4_read(hdr, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) if (task->tk_status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) .inode = hdr->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) .state = hdr->args.context->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) .stateid = &hdr->args.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) task->tk_status = nfs4_async_handle_exception(task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) server, task->tk_status, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) if (exception.retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) if (task->tk_status > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) renew_lease(server, hdr->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) static bool nfs4_read_stateid_changed(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) struct nfs_pgio_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) if (!nfs4_error_stateid_expired(task->tk_status) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) nfs4_stateid_is_current(&args->stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) args->context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) args->lock_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) static bool nfs4_read_plus_not_supported(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) struct nfs_pgio_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) struct nfs_server *server = NFS_SERVER(hdr->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) struct rpc_message *msg = &task->tk_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) server->caps & NFS_CAP_READ_PLUS && task->tk_status == -ENOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) server->caps &= ~NFS_CAP_READ_PLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) if (!nfs4_sequence_done(task, &hdr->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) if (nfs4_read_stateid_changed(task, &hdr->args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) if (nfs4_read_plus_not_supported(task, hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) if (task->tk_status > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) nfs_invalidate_atime(hdr->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) return hdr->pgio_done_cb ? hdr->pgio_done_cb(task, hdr) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) nfs4_read_done_cb(task, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) #if defined CONFIG_NFS_V4_2 && defined CONFIG_NFS_V4_2_READ_PLUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) static void nfs42_read_plus_support(struct nfs_server *server, struct rpc_message *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) if (server->caps & NFS_CAP_READ_PLUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) static void nfs42_read_plus_support(struct nfs_server *server, struct rpc_message *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) #endif /* CONFIG_NFS_V4_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) static void nfs4_proc_read_setup(struct nfs_pgio_header *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) struct rpc_message *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) hdr->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) if (!hdr->pgio_done_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) hdr->pgio_done_cb = nfs4_read_done_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) nfs42_read_plus_support(NFS_SERVER(hdr->inode), msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) static int nfs4_proc_pgio_rpc_prepare(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) struct nfs_pgio_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) if (nfs4_setup_sequence(NFS_SERVER(hdr->inode)->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) &hdr->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) &hdr->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) if (nfs4_set_rw_stateid(&hdr->args.stateid, hdr->args.context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) hdr->args.lock_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) hdr->rw_mode) == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) if (unlikely(test_bit(NFS_CONTEXT_BAD, &hdr->args.context->flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) static int nfs4_write_done_cb(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) struct nfs_pgio_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) struct inode *inode = hdr->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) trace_nfs4_write(hdr, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) if (task->tk_status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) .inode = hdr->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) .state = hdr->args.context->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) .stateid = &hdr->args.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) task->tk_status = nfs4_async_handle_exception(task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) NFS_SERVER(inode), task->tk_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) if (exception.retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) if (task->tk_status >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) renew_lease(NFS_SERVER(inode), hdr->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) nfs_writeback_update_inode(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) static bool nfs4_write_stateid_changed(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) struct nfs_pgio_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) if (!nfs4_error_stateid_expired(task->tk_status) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) nfs4_stateid_is_current(&args->stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) args->context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) args->lock_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) static int nfs4_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) if (!nfs4_sequence_done(task, &hdr->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) if (nfs4_write_stateid_changed(task, &hdr->args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) return hdr->pgio_done_cb ? hdr->pgio_done_cb(task, hdr) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) nfs4_write_done_cb(task, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) bool nfs4_write_need_cache_consistency_data(struct nfs_pgio_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) /* Don't request attributes for pNFS or O_DIRECT writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) if (hdr->ds_clp != NULL || hdr->dreq != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) /* Otherwise, request attributes if and only if we don't hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) * a delegation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) return nfs4_have_delegation(hdr->inode, FMODE_READ) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) struct inode *inode, struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) memcpy(bitmask, src, sizeof(*bitmask) * NFS4_BITMASK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) if (cache_validity & (NFS_INO_INVALID_CHANGE | NFS_INO_REVAL_PAGECACHE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) bitmask[0] |= FATTR4_WORD0_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) if (cache_validity & NFS_INO_INVALID_ATIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) bitmask[1] |= FATTR4_WORD1_TIME_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) if (cache_validity & NFS_INO_INVALID_OTHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) bitmask[1] |= FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) FATTR4_WORD1_OWNER_GROUP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) FATTR4_WORD1_NUMLINKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) if (label && label->len && cache_validity & NFS_INO_INVALID_LABEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) if (cache_validity & NFS_INO_INVALID_CTIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) bitmask[1] |= FATTR4_WORD1_TIME_METADATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) if (cache_validity & NFS_INO_INVALID_MTIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) bitmask[1] |= FATTR4_WORD1_TIME_MODIFY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) if (cache_validity & NFS_INO_INVALID_BLOCKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) bitmask[1] |= FATTR4_WORD1_SPACE_USED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) if (nfs4_have_delegation(inode, FMODE_READ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) !(cache_validity & NFS_INO_REVAL_FORCED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) bitmask[0] &= ~FATTR4_WORD0_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) else if (cache_validity &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) (NFS_INO_INVALID_SIZE | NFS_INO_REVAL_PAGECACHE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) bitmask[0] |= FATTR4_WORD0_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) for (i = 0; i < NFS4_BITMASK_SZ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) bitmask[i] &= server->attr_bitmask[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) struct rpc_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) struct rpc_clnt **clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) struct nfs_server *server = NFS_SERVER(hdr->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) if (!nfs4_write_need_cache_consistency_data(hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) hdr->args.bitmask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) hdr->res.fattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) nfs4_bitmask_set(hdr->args.bitmask_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) server->cache_consistency_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) hdr->inode, server, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) hdr->args.bitmask = hdr->args.bitmask_store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) if (!hdr->pgio_done_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) hdr->pgio_done_cb = nfs4_write_done_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) hdr->res.server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) hdr->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) nfs4_state_protect_write(server->nfs_client, clnt, msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) nfs4_setup_sequence(NFS_SERVER(data->inode)->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) &data->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) &data->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_commit_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) struct inode *inode = data->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) trace_nfs4_commit(data, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) if (nfs4_async_handle_error(task, NFS_SERVER(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) NULL, NULL) == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) static int nfs4_commit_done(struct rpc_task *task, struct nfs_commit_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) if (!nfs4_sequence_done(task, &data->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) return data->commit_done_cb(task, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) struct rpc_clnt **clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) struct nfs_server *server = NFS_SERVER(data->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) if (data->commit_done_cb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) data->commit_done_cb = nfs4_commit_done_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) data->res.server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_COMMIT, clnt, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) static int _nfs4_proc_commit(struct file *dst, struct nfs_commitargs *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) struct nfs_commitres *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) struct inode *dst_inode = file_inode(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) struct nfs_server *server = NFS_SERVER(dst_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) .rpc_argp = args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) .rpc_resp = res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) args->fh = NFS_FH(dst_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) return nfs4_call_sync(server->client, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) &args->seq_args, &res->seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) int nfs4_proc_commit(struct file *dst, __u64 offset, __u32 count, struct nfs_commitres *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) struct nfs_commitargs args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) .offset = offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) .count = count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) struct nfs_server *dst_server = NFS_SERVER(file_inode(dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) struct nfs4_exception exception = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) status = _nfs4_proc_commit(dst, &args, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) status = nfs4_handle_exception(dst_server, status, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) struct nfs4_renewdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) struct nfs_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) unsigned long timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) * standalone procedure for queueing an asynchronous RENEW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) static void nfs4_renew_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) struct nfs4_renewdata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) struct nfs_client *clp = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) if (refcount_read(&clp->cl_count) > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) nfs4_schedule_state_renewal(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) static void nfs4_renew_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) struct nfs4_renewdata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) struct nfs_client *clp = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) unsigned long timestamp = data->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) trace_nfs4_renew_async(clp, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) case -NFS4ERR_LEASE_MOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) nfs4_schedule_lease_moved_recovery(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) /* Unless we're shutting down, schedule state recovery! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) if (task->tk_status != NFS4ERR_CB_PATH_DOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) nfs4_schedule_lease_recovery(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) nfs4_schedule_path_down_recovery(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) do_renew_lease(clp, timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) static const struct rpc_call_ops nfs4_renew_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) .rpc_call_done = nfs4_renew_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) .rpc_release = nfs4_renew_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) static int nfs4_proc_async_renew(struct nfs_client *clp, const struct cred *cred, unsigned renew_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) .rpc_argp = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) struct nfs4_renewdata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) if (renew_flags == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) if (!refcount_inc_not_zero(&clp->cl_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) data = kmalloc(sizeof(*data), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) if (data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) data->client = clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) data->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) &nfs4_renew_ops, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) static int nfs4_proc_renew(struct nfs_client *clp, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) .rpc_argp = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) do_renew_lease(clp, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) static inline int nfs4_server_supports_acls(struct nfs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) return server->caps & NFS_CAP_ACLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) * the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) int nfs4_buf_to_pages_noslab(const void *buf, size_t buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) struct page **pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) struct page *newpage, **spages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) spages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) len = min_t(size_t, PAGE_SIZE, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) newpage = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) if (newpage == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) goto unwind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) memcpy(page_address(newpage), buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) buf += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) buflen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) *pages++ = newpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) rc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) } while (buflen != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) unwind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) for(; rc > 0; rc--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) __free_page(spages[rc-1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) struct nfs4_cached_acl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) int cached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) char data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) kfree(nfsi->nfs4_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) nfsi->nfs4_acl = acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) static void nfs4_zap_acl_attr(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) nfs4_set_cached_acl(inode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) struct nfs4_cached_acl *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) acl = nfsi->nfs4_acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) if (acl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) if (buf == NULL) /* user is just asking for length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) goto out_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) if (acl->cached == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) ret = -ERANGE; /* see getxattr(2) man page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) if (acl->len > buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) memcpy(buf, acl->data, acl->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) out_len:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) ret = acl->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) struct nfs4_cached_acl *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) size_t buflen = sizeof(*acl) + acl_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) if (buflen <= PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) acl = kmalloc(buflen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) if (acl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) acl->cached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) _copy_from_pages(acl->data, pages, pgbase, acl_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) acl = kmalloc(sizeof(*acl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) if (acl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) acl->cached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) acl->len = acl_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) nfs4_set_cached_acl(inode, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) * The getxattr API returns the required buffer length when called with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) * NULL buf. The NFSv4 acl tool then calls getxattr again after allocating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) * the required buf. On a NULL buf, we send a page of data to the server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) * guessing that the ACL request can be serviced by a page. If so, we cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) * up to the page of ACL data, and the 2nd call to getxattr is serviced by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) * the cache. If not so, we throw away the page, and cache the required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) * length. The next getxattr call will then produce another round trip to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) * the server, this time with the input buf of the required size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) struct nfs_getaclargs args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) .acl_len = buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) struct nfs_getaclres res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) .acl_len = buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) unsigned int npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) int ret = -ENOMEM, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) if (buflen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) buflen = server->rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) pages = kmalloc_array(npages, sizeof(struct page *), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) if (!pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) args.acl_pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) for (i = 0; i < npages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) pages[i] = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) if (!pages[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) /* for decoding across pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) res.acl_scratch = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) if (!res.acl_scratch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) args.acl_len = npages * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) __func__, buf, buflen, npages, args.acl_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) /* Handle the case where the passed-in buffer is too short */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) if (res.acl_flags & NFS4_ACL_TRUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) /* Did the user only issue a request for the acl length? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) goto out_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) if (res.acl_len > buflen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) out_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) ret = res.acl_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) for (i = 0; i < npages; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) if (pages[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) __free_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) if (res.acl_scratch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) __free_page(res.acl_scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) kfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) ret = __nfs4_get_acl_uncached(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) trace_nfs4_get_acl(inode, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) if (!nfs4_server_supports_acls(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) ret = nfs_revalidate_inode(server, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) nfs_zap_acl_cache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) ret = nfs4_read_cached_acl(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) if (ret != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) /* -ENOENT is returned if there is no ACL or if there is an ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) * but no cached acl data, just the acl length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) return nfs4_get_acl_uncached(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) struct page *pages[NFS4ACL_MAXPAGES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) struct nfs_setaclargs arg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) .acl_pages = pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) .acl_len = buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) struct nfs_setaclres res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) .rpc_argp = &arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) /* You can't remove system.nfs4_acl: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) if (buflen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) if (!nfs4_server_supports_acls(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) if (npages > ARRAY_SIZE(pages))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) i = nfs4_buf_to_pages_noslab(buf, buflen, arg.acl_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) nfs4_inode_make_writeable(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) * Free each page after tx, so the only ref left is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) * held by the network stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) for (; i > 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) put_page(pages[i-1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) * Acl update can result in inode attribute update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) * so mark the attribute cache invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) | NFS_INO_INVALID_CTIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) | NFS_INO_REVAL_FORCED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) nfs_access_zap_cache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) nfs_zap_acl_cache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) struct nfs4_exception exception = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) err = __nfs4_proc_set_acl(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) trace_nfs4_set_acl(inode, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) if (err == -NFS4ERR_BADOWNER || err == -NFS4ERR_BADNAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) * no need to retry since the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) * isn't involved in encoding the ACEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) err = nfs4_handle_exception(NFS_SERVER(inode), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) #ifdef CONFIG_NFS_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) static int _nfs4_get_security_label(struct inode *inode, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) struct nfs_fattr fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) struct nfs4_label label = {0, 0, buflen, buf};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) struct nfs4_getattr_arg arg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) struct nfs4_getattr_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) .fattr = &fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) .label = &label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETATTR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) .rpc_argp = &arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) nfs_fattr_init(&fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) return label.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) static int nfs4_get_security_label(struct inode *inode, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) err = _nfs4_get_security_label(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) trace_nfs4_get_security_label(inode, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) err = nfs4_handle_exception(NFS_SERVER(inode), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) static int _nfs4_do_set_security_label(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) struct nfs4_label *ilabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) struct nfs4_label *olabel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) struct iattr sattr = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) const u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) struct nfs_setattrargs arg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) .iap = &sattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) .label = ilabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) struct nfs_setattrres res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) .fattr = fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) .label = olabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) .server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) .rpc_argp = &arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) nfs4_stateid_copy(&arg.stateid, &zero_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) dprintk("%s failed: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) static int nfs4_do_set_security_label(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) struct nfs4_label *ilabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) struct nfs4_label *olabel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) struct nfs4_exception exception = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) err = _nfs4_do_set_security_label(inode, ilabel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) fattr, olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) trace_nfs4_set_security_label(inode, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) err = nfs4_handle_exception(NFS_SERVER(inode), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) struct nfs4_label ilabel, *olabel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) struct nfs_fattr fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) nfs_fattr_init(&fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) ilabel.pi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) ilabel.lfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) ilabel.label = (char *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) ilabel.len = buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) if (IS_ERR(olabel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) status = -PTR_ERR(olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) status = nfs4_do_set_security_label(inode, &ilabel, &fattr, olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) nfs_setsecurity(inode, &fattr, olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) nfs4_label_free(olabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) #endif /* CONFIG_NFS_V4_SECURITY_LABEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) static void nfs4_init_boot_verifier(const struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) nfs4_verifier *bootverf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) __be32 verf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) /* An impossible timestamp guarantees this value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) * will never match a generated boot time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) verf[0] = cpu_to_be32(U32_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) verf[1] = cpu_to_be32(U32_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) u64 ns = ktime_to_ns(nn->boot_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) verf[0] = cpu_to_be32(ns >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) verf[1] = cpu_to_be32(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) memcpy(bootverf->data, verf, sizeof(bootverf->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) static size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) nfs4_get_uniquifier(struct nfs_client *clp, char *buf, size_t buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) struct nfs_netns_client *nn_clp = nn->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) const char *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) buf[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) if (nn_clp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) id = rcu_dereference(nn_clp->identifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) if (id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) strscpy(buf, id, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) if (nfs4_client_id_uniquifier[0] != '\0' && buf[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) strscpy(buf, nfs4_client_id_uniquifier, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) nfs4_init_nonuniform_client_string(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) char buf[NFS4_CLIENT_ID_UNIQ_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) size_t buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) if (clp->cl_owner_id != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) len = 14 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) strlen(clp->cl_rpcclient->cl_nodename) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) 1 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) strlen(rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) buflen = nfs4_get_uniquifier(clp, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) if (buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) len += buflen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) if (len > NFS4_OPAQUE_LIMIT + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) * Since this string is allocated at mount time, and held until the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) * nfs_client is destroyed, we can use GFP_KERNEL here w/o worrying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) * about a memory-reclaim deadlock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) str = kmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) if (buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) scnprintf(str, len, "Linux NFSv4.0 %s/%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) clp->cl_rpcclient->cl_nodename, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) rpc_peeraddr2str(clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) RPC_DISPLAY_ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) scnprintf(str, len, "Linux NFSv4.0 %s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) clp->cl_rpcclient->cl_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) rpc_peeraddr2str(clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) RPC_DISPLAY_ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) clp->cl_owner_id = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) nfs4_init_uniform_client_string(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) char buf[NFS4_CLIENT_ID_UNIQ_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) size_t buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) if (clp->cl_owner_id != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) len = 10 + 10 + 1 + 10 + 1 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) strlen(clp->cl_rpcclient->cl_nodename) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) buflen = nfs4_get_uniquifier(clp, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) if (buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) len += buflen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) if (len > NFS4_OPAQUE_LIMIT + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) * Since this string is allocated at mount time, and held until the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) * nfs_client is destroyed, we can use GFP_KERNEL here w/o worrying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) * about a memory-reclaim deadlock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) str = kmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) if (buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) scnprintf(str, len, "Linux NFSv%u.%u %s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) clp->rpc_ops->version, clp->cl_minorversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) buf, clp->cl_rpcclient->cl_nodename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) scnprintf(str, len, "Linux NFSv%u.%u %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) clp->rpc_ops->version, clp->cl_minorversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) clp->cl_rpcclient->cl_nodename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) clp->cl_owner_id = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) * nfs4_callback_up_net() starts only "tcp" and "tcp6" callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) * services. Advertise one based on the address family of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) * clientaddr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) nfs4_init_callback_netid(const struct nfs_client *clp, char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) if (strchr(clp->cl_ipaddr, ':') != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) return scnprintf(buf, len, "tcp6");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) return scnprintf(buf, len, "tcp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) static void nfs4_setclientid_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) struct nfs4_setclientid *sc = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) if (task->tk_status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) sc->sc_cred = get_rpccred(task->tk_rqstp->rq_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) static const struct rpc_call_ops nfs4_setclientid_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) .rpc_call_done = nfs4_setclientid_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) * nfs4_proc_setclientid - Negotiate client ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) * @clp: state data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) * @program: RPC program for NFSv4 callback service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) * @port: IP port number for NFS4 callback service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) * @cred: credential to use for this call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) * @res: where to place the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) * Returns zero, a negative errno, or a negative NFS4ERR status code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) unsigned short port, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) struct nfs4_setclientid_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) nfs4_verifier sc_verifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) struct nfs4_setclientid setclientid = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) .sc_verifier = &sc_verifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) .sc_prog = program,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) .sc_clnt = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) .rpc_argp = &setclientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294) .rpc_resp = res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) .rpc_client = clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) .callback_ops = &nfs4_setclientid_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) .callback_data = &setclientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) .flags = RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) /* nfs_client_id4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) nfs4_init_boot_verifier(clp, &sc_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) if (test_bit(NFS_CS_MIGRATION, &clp->cl_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) status = nfs4_init_uniform_client_string(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) status = nfs4_init_nonuniform_client_string(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) /* cb_client4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) setclientid.sc_netid_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) nfs4_init_callback_netid(clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) setclientid.sc_netid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) sizeof(setclientid.sc_netid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) sizeof(setclientid.sc_uaddr), "%s.%u.%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) clp->cl_ipaddr, port >> 8, port & 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) dprintk("NFS call setclientid auth=%s, '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) clp->cl_rpcclient->cl_auth->au_ops->au_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) clp->cl_owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) status = nfs4_call_sync_custom(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) if (setclientid.sc_cred) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) kfree(clp->cl_acceptor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334) clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) put_rpccred(setclientid.sc_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) do_renew_lease(clp, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) trace_nfs4_setclientid(clp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342) dprintk("NFS reply setclientid: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) * nfs4_proc_setclientid_confirm - Confirm client ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) * @clp: state data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) * @arg: result of a previous SETCLIENTID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) * @cred: credential to use for this call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) * Returns zero, a negative errno, or a negative NFS4ERR status code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) struct nfs4_setclientid_res *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) .rpc_argp = arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) dprintk("NFS call setclientid_confirm auth=%s, (client ID %llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) clp->cl_rpcclient->cl_auth->au_ops->au_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) clp->cl_clientid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) status = rpc_call_sync(clp->cl_rpcclient, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) trace_nfs4_setclientid_confirm(clp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) dprintk("NFS reply setclientid_confirm: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) struct nfs4_delegreturndata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) struct nfs4_delegreturnargs args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377) struct nfs4_delegreturnres res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) struct nfs_fh fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) nfs4_stateid stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) unsigned long timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) struct nfs4_layoutreturn_args arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) struct nfs4_layoutreturn_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) struct nfs4_xdr_opaque_data ld_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) u32 roc_barrier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386) bool roc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) } lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) struct nfs_fattr fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) int rpc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) struct nfs4_delegreturndata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) .inode = data->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) .stateid = &data->stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) .task_is_privileged = data->args.seq_args.sa_privileged,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) if (!nfs4_sequence_done(task, &data->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) /* Handle Layoutreturn errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) if (pnfs_roc_done(task, &data->args.lr_args, &data->res.lr_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) &data->res.lr_ret) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) renew_lease(data->res.server, data->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) case -NFS4ERR_DELEG_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) nfs4_free_revoked_stateid(data->res.server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) data->args.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) task->tk_msg.rpc_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) case -NFS4ERR_OLD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) if (!nfs4_refresh_delegation_stateid(&data->stateid, data->inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) nfs4_stateid_seqid_inc(&data->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) if (data->args.bitmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) data->args.bitmask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) data->res.fattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) case -NFS4ERR_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) if (data->args.bitmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) data->args.bitmask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) data->res.fattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) task->tk_status = nfs4_async_handle_exception(task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) data->res.server, task->tk_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) if (exception.retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) nfs_delegation_mark_returned(data->inode, data->args.stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) data->rpc_status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) out_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) static void nfs4_delegreturn_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) struct nfs4_delegreturndata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) struct inode *inode = data->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) if (data->lr.roc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) pnfs_roc_release(&data->lr.arg, &data->lr.res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) data->res.lr_ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) nfs_iput_and_deactive(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) struct nfs4_delegreturndata *d_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) struct pnfs_layout_hdr *lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478) d_data = (struct nfs4_delegreturndata *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) nfs4_sequence_done(task, &d_data->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) lo = d_data->args.lr_args ? d_data->args.lr_args->layout : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) if (lo && !pnfs_layout_is_valid(lo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) d_data->args.lr_args = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) d_data->res.lr_res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) nfs4_setup_sequence(d_data->res.server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) &d_data->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) &d_data->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) static const struct rpc_call_ops nfs4_delegreturn_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) .rpc_call_prepare = nfs4_delegreturn_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) .rpc_call_done = nfs4_delegreturn_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) .rpc_release = nfs4_delegreturn_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) struct nfs4_delegreturndata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) .rpc_client = server->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) .callback_ops = &nfs4_delegreturn_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) data = kzalloc(sizeof(*data), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) nfs4_state_protect(server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525) NFS_SP4_MACH_CRED_CLEANUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) &task_setup_data.rpc_client, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) data->args.fhandle = &data->fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) data->args.stateid = &data->stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) nfs4_bitmask_set(data->args.bitmask_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) server->cache_consistency_bitmask, inode, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) data->args.bitmask = data->args.bitmask_store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) nfs_copy_fh(&data->fh, NFS_FH(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) nfs4_stateid_copy(&data->stateid, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) data->res.fattr = &data->fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) data->res.server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) data->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) data->lr.arg.ld_private = &data->lr.ld_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) nfs_fattr_init(data->res.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) data->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) data->rpc_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) data->inode = nfs_igrab_and_active(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) if (data->inode || issync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) if (data->lr.roc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) data->args.lr_args = &data->lr.arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) data->res.lr_res = &data->lr.res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) if (!data->inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) task_setup_data.callback_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) msg.rpc_argp = &data->args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) msg.rpc_resp = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) if (!issync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) status = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) status = data->rpc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) int nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) struct nfs4_exception exception = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) trace_nfs4_delegreturn(inode, stateid, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) err = nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) struct inode *inode = state->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) struct nfs_lockt_args arg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) .fl = request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) struct nfs_lockt_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) .denied = request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) .rpc_argp = &arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) .rpc_cred = state->owner->so_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) struct nfs4_lock_state *lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) arg.lock_owner.clientid = clp->cl_clientid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) status = nfs4_set_lock_state(state, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) lsp = request->fl_u.nfs4_fl.owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) arg.lock_owner.id = lsp->ls_seqid.owner_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) arg.lock_owner.s_dev = server->s_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) request->fl_type = F_UNLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) case -NFS4ERR_DENIED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) request->fl_ops->fl_release_private(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) request->fl_ops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) err = _nfs4_proc_getlk(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) trace_nfs4_get_lock(request, state, cmd, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) err = nfs4_handle_exception(NFS_SERVER(state->inode), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) * Update the seqid of a lock stateid after receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) * NFS4ERR_OLD_STATEID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) static bool nfs4_refresh_lock_old_stateid(nfs4_stateid *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) struct nfs4_lock_state *lsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) struct nfs4_state *state = lsp->ls_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) spin_lock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) if (!nfs4_stateid_match_other(dst, &lsp->ls_stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) if (!nfs4_stateid_is_newer(&lsp->ls_stateid, dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) nfs4_stateid_seqid_inc(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) dst->seqid = lsp->ls_stateid.seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) spin_unlock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) static bool nfs4_sync_lock_stateid(nfs4_stateid *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) struct nfs4_lock_state *lsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) struct nfs4_state *state = lsp->ls_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) spin_lock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) ret = !nfs4_stateid_match_other(dst, &lsp->ls_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) nfs4_stateid_copy(dst, &lsp->ls_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) spin_unlock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) struct nfs4_unlockdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) struct nfs_locku_args arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) struct nfs_locku_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692) struct nfs4_lock_state *lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) struct nfs_lock_context *l_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) struct file_lock fl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) struct nfs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) unsigned long timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) struct nfs4_lock_state *lsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) struct nfs_seqid *seqid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) struct nfs4_unlockdata *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) struct nfs4_state *state = lsp->ls_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) struct inode *inode = state->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) p = kzalloc(sizeof(*p), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) if (p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) p->arg.fh = NFS_FH(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) p->arg.fl = &p->fl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) p->arg.seqid = seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) p->res.seqid = seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) p->lsp = lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) /* Ensure we don't close file until we're done freeing locks! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) p->ctx = get_nfs_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) p->l_ctx = nfs_get_lock_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720) locks_init_lock(&p->fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) locks_copy_lock(&p->fl, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) p->server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) spin_lock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) nfs4_stateid_copy(&p->arg.stateid, &lsp->ls_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) spin_unlock(&state->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) static void nfs4_locku_release_calldata(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) struct nfs4_unlockdata *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) nfs_free_seqid(calldata->arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) nfs4_put_lock_state(calldata->lsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) nfs_put_lock_context(calldata->l_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) put_nfs_open_context(calldata->ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) static void nfs4_locku_done(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) struct nfs4_unlockdata *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) .inode = calldata->lsp->ls_state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) .stateid = &calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) if (!nfs4_sequence_done(task, &calldata->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) renew_lease(calldata->server, calldata->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) locks_lock_inode_wait(calldata->lsp->ls_state->inode, &calldata->fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) if (nfs4_update_lock_stateid(calldata->lsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) &calldata->res.stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) nfs4_free_revoked_stateid(calldata->server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) &calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) task->tk_msg.rpc_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) if (nfs4_sync_lock_stateid(&calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) calldata->lsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) case -NFS4ERR_OLD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) if (nfs4_refresh_lock_old_stateid(&calldata->arg.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) calldata->lsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) task->tk_status = nfs4_async_handle_exception(task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) calldata->server, task->tk_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) if (exception.retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) nfs_release_seqid(calldata->arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) static void nfs4_locku_prepare(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) struct nfs4_unlockdata *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) if (test_bit(NFS_CONTEXT_UNLOCK, &calldata->l_ctx->open_context->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789) nfs_async_iocounter_wait(task, calldata->l_ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) goto out_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) if (test_bit(NFS_LOCK_INITIALIZED, &calldata->lsp->ls_flags) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) /* Note: exit _without_ running nfs4_locku_done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) goto out_no_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) calldata->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) if (nfs4_setup_sequence(calldata->server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) &calldata->arg.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) &calldata->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) task) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) nfs_release_seqid(calldata->arg.seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) out_no_action:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) task->tk_action = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) out_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) nfs4_sequence_done(task, &calldata->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) static const struct rpc_call_ops nfs4_locku_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) .rpc_call_prepare = nfs4_locku_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) .rpc_call_done = nfs4_locku_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) .rpc_release = nfs4_locku_release_calldata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) struct nfs4_lock_state *lsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) struct nfs_seqid *seqid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) struct nfs4_unlockdata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) .rpc_cred = ctx->cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) .rpc_client = NFS_CLIENT(lsp->ls_state->inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) .callback_ops = &nfs4_locku_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) .workqueue = nfsiod_workqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) .flags = RPC_TASK_ASYNC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) NFS_SP4_MACH_CRED_CLEANUP, &task_setup_data.rpc_client, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) /* Ensure this is an unlock - when canceling a lock, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) * canceled lock is passed in, and it won't be an unlock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) fl->fl_type = F_UNLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) if (fl->fl_flags & FL_CLOSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) set_bit(NFS_CONTEXT_UNLOCK, &ctx->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) data = nfs4_alloc_unlockdata(fl, ctx, lsp, seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) if (data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) nfs_free_seqid(seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) nfs4_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) msg.rpc_argp = &data->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) msg.rpc_resp = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) task_setup_data.callback_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) return rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) struct inode *inode = state->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) struct nfs4_state_owner *sp = state->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) struct nfs_seqid *seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) struct nfs4_lock_state *lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) unsigned char fl_flags = request->fl_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) status = nfs4_set_lock_state(state, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) /* Unlock _before_ we do the RPC call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) request->fl_flags |= FL_EXISTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) /* Exclude nfs_delegation_claim_locks() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) mutex_lock(&sp->so_delegreturn_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) /* Exclude nfs4_reclaim_open_stateid() - note nesting! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) down_read(&nfsi->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) if (locks_lock_inode_wait(inode, request) == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) up_read(&nfsi->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) mutex_unlock(&sp->so_delegreturn_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) up_read(&nfsi->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) mutex_unlock(&sp->so_delegreturn_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) /* Is this a delegated lock? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) lsp = request->fl_u.nfs4_fl.owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) alloc_seqid = NFS_SERVER(inode)->nfs_client->cl_mvops->alloc_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) seqid = alloc_seqid(&lsp->ls_seqid, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) if (IS_ERR(seqid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) task = nfs4_do_unlck(request, nfs_file_open_context(request->fl_file), lsp, seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) status = PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) status = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) request->fl_flags = fl_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) trace_nfs4_unlock(request, state, F_SETLK, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) struct nfs4_lockdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) struct nfs_lock_args arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) struct nfs_lock_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) struct nfs4_lock_state *lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) struct file_lock fl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) unsigned long timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) int rpc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) int cancelled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) struct nfs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) struct nfs_open_context *ctx, struct nfs4_lock_state *lsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) gfp_t gfp_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) struct nfs4_lockdata *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) struct inode *inode = lsp->ls_state->inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) p = kzalloc(sizeof(*p), gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) if (p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) p->arg.fh = NFS_FH(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) p->arg.fl = &p->fl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) if (IS_ERR(p->arg.open_seqid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) alloc_seqid = server->nfs_client->cl_mvops->alloc_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) p->arg.lock_seqid = alloc_seqid(&lsp->ls_seqid, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) if (IS_ERR(p->arg.lock_seqid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) goto out_free_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) p->arg.lock_owner.id = lsp->ls_seqid.owner_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) p->arg.lock_owner.s_dev = server->s_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) p->res.lock_seqid = p->arg.lock_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) p->lsp = lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) p->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) p->ctx = get_nfs_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) locks_init_lock(&p->fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) locks_copy_lock(&p->fl, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) out_free_seqid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) nfs_free_seqid(p->arg.open_seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) struct nfs4_lockdata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) struct nfs4_state *state = data->lsp->ls_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) dprintk("%s: begin!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) goto out_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) /* Do we need to do an open_to_lock_owner? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) if (!test_bit(NFS_LOCK_INITIALIZED, &data->lsp->ls_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) goto out_release_lock_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971) nfs4_stateid_copy(&data->arg.open_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) &state->open_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) data->arg.new_lock_owner = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) data->res.open_seqid = data->arg.open_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) data->arg.new_lock_owner = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) nfs4_stateid_copy(&data->arg.lock_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) &data->lsp->ls_stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) if (!nfs4_valid_open_stateid(state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) data->rpc_status = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) task->tk_action = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) goto out_release_open_seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) data->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) if (nfs4_setup_sequence(data->server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) &data->arg.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) &data->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) task) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) out_release_open_seqid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992) nfs_release_seqid(data->arg.open_seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) out_release_lock_seqid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) nfs_release_seqid(data->arg.lock_seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) out_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) nfs4_sequence_done(task, &data->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) static void nfs4_lock_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) struct nfs4_lockdata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) struct nfs4_lock_state *lsp = data->lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) dprintk("%s: begin!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) if (!nfs4_sequence_done(task, &data->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) data->rpc_status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) data->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) if (data->arg.new_lock && !data->cancelled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020) if (data->arg.new_lock_owner != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) nfs_confirm_seqid(&lsp->ls_seqid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) nfs4_stateid_copy(&lsp->ls_stateid, &data->res.stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) set_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) } else if (!nfs4_update_lock_stateid(lsp, &data->res.stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) case -NFS4ERR_OLD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) if (data->arg.new_lock_owner != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) if (!nfs4_stateid_match(&data->arg.open_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) &lsp->ls_state->open_stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) } else if (!nfs4_stateid_match(&data->arg.lock_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) &lsp->ls_stateid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) out_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) out_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) if (!data->cancelled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) goto out_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) static void nfs4_lock_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) struct nfs4_lockdata *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) dprintk("%s: begin!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) nfs_free_seqid(data->arg.open_seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) if (data->cancelled && data->rpc_status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) data->arg.lock_seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) if (!IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) rpc_put_task_async(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) dprintk("%s: cancelling lock!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062) nfs_free_seqid(data->arg.lock_seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) nfs4_put_lock_state(data->lsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) put_nfs_open_context(data->ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) dprintk("%s: done!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) static const struct rpc_call_ops nfs4_lock_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) .rpc_call_prepare = nfs4_lock_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) .rpc_call_done = nfs4_lock_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) .rpc_release = nfs4_lock_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) if (new_lock_owner != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) nfs4_schedule_stateid_recovery(server, lsp->ls_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) case -NFS4ERR_STALE_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) nfs4_schedule_lease_recovery(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) struct nfs4_lockdata *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) .rpc_cred = state->owner->so_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) .rpc_client = NFS_CLIENT(state->inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103) .callback_ops = &nfs4_lock_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) .workqueue = nfsiod_workqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) dprintk("%s: begin!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) fl->fl_u.nfs4_fl.owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) if (IS_SETLKW(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) data->arg.block = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117) nfs4_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) recovery_type > NFS_LOCK_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) msg.rpc_argp = &data->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120) msg.rpc_resp = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) task_setup_data.callback_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122) if (recovery_type > NFS_LOCK_NEW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) if (recovery_type == NFS_LOCK_RECLAIM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124) data->arg.reclaim = NFS_LOCK_RECLAIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) data->arg.new_lock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) ret = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) ret = data->rpc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134) nfs4_handle_setlk_error(data->server, data->lsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) data->arg.new_lock_owner, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) data->cancelled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138) trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140) dprintk("%s: done, ret = %d!\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) .inode = state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153) /* Cache the lock if possible... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) if (err != -NFS4ERR_DELAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) .inode = state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172) err = nfs4_set_lock_state(state, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175) if (!recover_lost_locks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) set_bit(NFS_LOCK_LOST, &request->fl_u.nfs4_fl.owner->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) case -NFS4ERR_GRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) static int nfs41_lock_expired(struct nfs4_state *state, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199) struct nfs4_lock_state *lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) status = nfs4_set_lock_state(state, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205) lsp = request->fl_u.nfs4_fl.owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) test_bit(NFS_LOCK_LOST, &lsp->ls_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) return nfs4_lock_expired(state, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213) static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) struct nfs_inode *nfsi = NFS_I(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216) struct nfs4_state_owner *sp = state->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) unsigned char fl_flags = request->fl_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) request->fl_flags |= FL_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) status = locks_lock_inode_wait(state->inode, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) mutex_lock(&sp->so_delegreturn_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) down_read(&nfsi->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226) if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) /* Yes: cache locks! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228) /* ...but avoid races with delegation recall... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) request->fl_flags = fl_flags & ~FL_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) status = locks_lock_inode_wait(state->inode, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) up_read(&nfsi->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) mutex_unlock(&sp->so_delegreturn_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) up_read(&nfsi->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236) mutex_unlock(&sp->so_delegreturn_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) status = _nfs4_do_setlk(state, cmd, request, NFS_LOCK_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) request->fl_flags = fl_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243) static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246) .state = state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247) .inode = state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253) err = _nfs4_proc_setlk(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) if (err == -NFS4ERR_DENIED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255) err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256) err = nfs4_handle_exception(NFS_SERVER(state->inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262) #define NFS4_LOCK_MINTIMEOUT (1 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) #define NFS4_LOCK_MAXTIMEOUT (30 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266) nfs4_retry_setlk_simple(struct nfs4_state *state, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) int status = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270) unsigned long timeout = NFS4_LOCK_MINTIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) while(!signalled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273) status = nfs4_proc_setlk(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274) if ((status != -EAGAIN) || IS_SETLK(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276) freezable_schedule_timeout_interruptible(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277) timeout *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278) timeout = min_t(unsigned long, NFS4_LOCK_MAXTIMEOUT, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) status = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285) struct nfs4_lock_waiter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286) struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) struct nfs_lowner *owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) nfs4_wake_lock_waiter(wait_queue_entry_t *wait, unsigned int mode, int flags, void *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) struct nfs4_lock_waiter *waiter = wait->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297) /* NULL key means to wake up everyone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) if (key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299) struct cb_notify_lock_args *cbnl = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300) struct nfs_lowner *lowner = &cbnl->cbnl_owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301) *wowner = waiter->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303) /* Only wake if the callback was for the same owner. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) if (lowner->id != wowner->id || lowner->s_dev != wowner->s_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) /* Make sure it's for the right inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) if (nfs_compare_fh(NFS_FH(waiter->inode), &cbnl->cbnl_fh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312) /* override "private" so we can use default_wake_function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) wait->private = waiter->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) ret = woken_wake_function(wait, mode, flags, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) list_del_init(&wait->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) wait->private = waiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322) nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324) int status = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325) struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328) wait_queue_head_t *q = &clp->cl_lock_waitq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329) struct nfs_lowner owner = { .clientid = clp->cl_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330) .id = lsp->ls_seqid.owner_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) .s_dev = server->s_dev };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) struct nfs4_lock_waiter waiter = { .task = current,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333) .inode = state->inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) .owner = &owner};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335) wait_queue_entry_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) /* Don't bother with waitqueue if we don't expect a callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) if (!test_bit(NFS_STATE_MAY_NOTIFY_LOCK, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) return nfs4_retry_setlk_simple(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341) init_wait(&wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) wait.private = &waiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343) wait.func = nfs4_wake_lock_waiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) while(!signalled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) add_wait_queue(q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347) status = nfs4_proc_setlk(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348) if ((status != -EAGAIN) || IS_SETLK(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349) finish_wait(q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353) status = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354) freezer_do_not_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355) wait_woken(&wait, TASK_INTERRUPTIBLE, NFS4_LOCK_MAXTIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356) freezer_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357) finish_wait(q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362) #else /* !CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364) nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366) return nfs4_retry_setlk_simple(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371) nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) struct nfs4_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377) /* verify open state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378) ctx = nfs_file_open_context(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) state = ctx->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381) if (IS_GETLK(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) if (state != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383) return nfs4_proc_getlk(state, F_GETLK, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387) if (!(IS_SETLK(cmd) || IS_SETLKW(cmd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390) if (request->fl_type == F_UNLCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) if (state != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) return nfs4_proc_unlck(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396) if (state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) return -ENOLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399) if ((request->fl_flags & FL_POSIX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400) !test_bit(NFS_STATE_POSIX_LOCKS, &state->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) return -ENOLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) * Don't rely on the VFS having checked the file open mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) * since it won't do this for flock() locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) switch (request->fl_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408) case F_RDLCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409) if (!(filp->f_mode & FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) case F_WRLCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413) if (!(filp->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417) status = nfs4_set_lock_state(state, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421) return nfs4_retry_setlk(state, cmd, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424) int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426) struct nfs_server *server = NFS_SERVER(state->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429) err = nfs4_set_lock_state(state, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433) err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434) if (err != -NFS4ERR_DELAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437) } while (err == -NFS4ERR_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438) return nfs4_handle_delegation_recall_error(server, state, stateid, fl, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441) struct nfs_release_lockowner_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442) struct nfs4_lock_state *lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) struct nfs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444) struct nfs_release_lockowner_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445) struct nfs_release_lockowner_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) unsigned long timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449) static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451) struct nfs_release_lockowner_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) struct nfs_server *server = data->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453) nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7454) &data->res.seq_res, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7455) data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456) data->timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459) static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461) struct nfs_release_lockowner_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) struct nfs_server *server = data->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464) nfs40_sequence_done(task, &data->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468) renew_lease(server, data->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470) case -NFS4ERR_STALE_CLIENTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472) nfs4_schedule_lease_recovery(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) case -NFS4ERR_LEASE_MOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) if (nfs4_async_handle_error(task, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477) NULL, NULL) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482) static void nfs4_release_lockowner_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484) struct nfs_release_lockowner_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) nfs4_free_lock_state(data->server, data->lsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489) static const struct rpc_call_ops nfs4_release_lockowner_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) .rpc_call_prepare = nfs4_release_lockowner_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491) .rpc_call_done = nfs4_release_lockowner_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) .rpc_release = nfs4_release_lockowner_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) struct nfs_release_lockowner_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503) if (server->nfs_client->cl_mvops->minor_version != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506) data = kmalloc(sizeof(*data), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) data->lsp = lsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510) data->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) data->args.lock_owner.id = lsp->ls_seqid.owner_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) data->args.lock_owner.s_dev = server->s_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515) msg.rpc_argp = &data->args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) msg.rpc_resp = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523) static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525) const char *key, const void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526) size_t buflen, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) return nfs4_proc_set_acl(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7532) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7533) const char *key, void *buf, size_t buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7534) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7536) return nfs4_proc_get_acl(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7539) static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7541) return nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7544) #ifdef CONFIG_NFS_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7546) static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7547) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7548) const char *key, const void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7549) size_t buflen, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7551) if (security_ismaclabel(key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7552) return nfs4_set_security_label(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7554) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7557) static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7558) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7559) const char *key, void *buf, size_t buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7560) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7562) if (security_ismaclabel(key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7563) return nfs4_get_security_label(inode, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7564) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7567) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7568) nfs4_listxattr_nfs4_label(struct inode *inode, char *list, size_t list_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7570) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7572) if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7573) len = security_inode_listsecurity(inode, list, list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7574) if (len >= 0 && list_len && len > list_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7575) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7577) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7580) static const struct xattr_handler nfs4_xattr_nfs4_label_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7581) .prefix = XATTR_SECURITY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7582) .get = nfs4_xattr_get_nfs4_label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7583) .set = nfs4_xattr_set_nfs4_label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7584) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7586) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7588) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7589) nfs4_listxattr_nfs4_label(struct inode *inode, char *list, size_t list_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7594) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7596) #ifdef CONFIG_NFS_V4_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7597) static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7598) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7599) const char *key, const void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7600) size_t buflen, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7602) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7603) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7605) if (!nfs_server_capable(inode, NFS_CAP_XATTR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7606) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7608) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7609) * There is no mapping from the MAY_* flags to the NFS_ACCESS_XA*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7610) * flags right now. Handling of xattr operations use the normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7611) * file read/write permissions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7612) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7613) * Just in case the server has other ideas (which RFC 8276 allows),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7614) * do a cached access check for the XA* flags to possibly avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7615) * doing an RPC and getting EACCES back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7617) if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7618) if (!(mask & NFS_ACCESS_XAWRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7619) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7622) if (buf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7623) ret = nfs42_proc_removexattr(inode, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7624) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7625) nfs4_xattr_cache_remove(inode, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7626) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7627) ret = nfs42_proc_setxattr(inode, key, buf, buflen, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7628) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7629) nfs4_xattr_cache_add(inode, key, buf, NULL, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7632) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7635) static int nfs4_xattr_get_nfs4_user(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7636) struct dentry *unused, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7637) const char *key, void *buf, size_t buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7638) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7640) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7641) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7643) if (!nfs_server_capable(inode, NFS_CAP_XATTR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7644) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7646) if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7647) if (!(mask & NFS_ACCESS_XAREAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7648) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7651) ret = nfs_revalidate_inode(NFS_SERVER(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7652) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7653) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7655) ret = nfs4_xattr_cache_get(inode, key, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7656) if (ret >= 0 || (ret < 0 && ret != -ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7657) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7659) ret = nfs42_proc_getxattr(inode, key, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7661) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7664) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7665) nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7667) u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7668) bool eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7669) ssize_t ret, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7670) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7671) size_t buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7672) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7674) if (!nfs_server_capable(inode, NFS_CAP_XATTR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7677) if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7678) if (!(mask & NFS_ACCESS_XALIST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7682) ret = nfs_revalidate_inode(NFS_SERVER(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7683) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7684) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7686) ret = nfs4_xattr_cache_list(inode, list, list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7687) if (ret >= 0 || (ret < 0 && ret != -ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7688) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7690) cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7691) eof = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7692) buflen = list_len ? list_len : XATTR_LIST_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7693) buf = list_len ? list : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7694) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7696) while (!eof) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7697) ret = nfs42_proc_listxattrs(inode, buf, buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7698) &cookie, &eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7699) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7700) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7702) if (list_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7703) buf += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7704) buflen -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7706) size += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7709) if (list_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7710) nfs4_xattr_cache_set_list(inode, list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7712) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7715) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7717) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7718) nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7720) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7722) #endif /* CONFIG_NFS_V4_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7725) * nfs_fhget will use either the mounted_on_fileid or the fileid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7727) static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7729) if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7730) (fattr->valid & NFS_ATTR_FATTR_FILEID)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7731) (fattr->valid & NFS_ATTR_FATTR_FSID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7732) (fattr->valid & NFS_ATTR_FATTR_V4_LOCATIONS)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7733) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7735) fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7736) NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_V4_REFERRAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7737) fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7738) fattr->nlink = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7741) static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7742) const struct qstr *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7743) struct nfs4_fs_locations *fs_locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7744) struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7746) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7747) u32 bitmask[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7748) struct nfs4_fs_locations_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7749) .dir_fh = NFS_FH(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7750) .name = name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7751) .page = page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7752) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7753) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7754) struct nfs4_fs_locations_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7755) .fs_locations = fs_locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7756) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7757) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7758) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7759) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7760) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7761) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7762) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7764) dprintk("%s: start\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7766) bitmask[0] = nfs4_fattr_bitmap[0] | FATTR4_WORD0_FS_LOCATIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7767) bitmask[1] = nfs4_fattr_bitmap[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7769) /* Ask for the fileid of the absent filesystem if mounted_on_fileid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7770) * is not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7771) if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7772) bitmask[0] &= ~FATTR4_WORD0_FILEID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7773) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7774) bitmask[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7776) nfs_fattr_init(&fs_locations->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7777) fs_locations->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7778) fs_locations->nlocations = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7779) status = nfs4_call_sync(client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7780) dprintk("%s: returned status = %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7781) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7784) int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7785) const struct qstr *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7786) struct nfs4_fs_locations *fs_locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7787) struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7789) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7790) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7791) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7792) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7793) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7794) err = _nfs4_proc_fs_locations(client, dir, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7795) fs_locations, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7796) trace_nfs4_get_fs_locations(dir, name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7797) err = nfs4_handle_exception(NFS_SERVER(dir), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7798) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7799) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7800) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7803) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7804) * This operation also signals the server that this client is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7805) * performing migration recovery. The server can stop returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7806) * NFS4ERR_LEASE_MOVED to this client. A RENEW operation is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7807) * appended to this compound to identify the client ID which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7808) * performing recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7810) static int _nfs40_proc_get_locations(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7811) struct nfs4_fs_locations *locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7812) struct page *page, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7814) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7815) struct rpc_clnt *clnt = server->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7816) u32 bitmask[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7817) [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7818) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7819) struct nfs4_fs_locations_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7820) .clientid = server->nfs_client->cl_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7821) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7822) .page = page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7823) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7824) .migration = 1, /* skip LOOKUP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7825) .renew = 1, /* append RENEW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7827) struct nfs4_fs_locations_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7828) .fs_locations = locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7829) .migration = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7830) .renew = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7831) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7832) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7833) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7834) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7835) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7836) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7837) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7838) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7839) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7841) nfs_fattr_init(&locations->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7842) locations->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7843) locations->nlocations = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7845) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7846) status = nfs4_call_sync_sequence(clnt, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7847) &args.seq_args, &res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7848) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7849) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7851) renew_lease(server, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7852) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7855) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7857) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7858) * This operation also signals the server that this client is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7859) * performing migration recovery. The server can stop asserting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7860) * SEQ4_STATUS_LEASE_MOVED for this client. The client ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7861) * performing this operation is identified in the SEQUENCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7862) * operation in this compound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7863) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7864) * When the client supports GETATTR(fs_locations_info), it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7865) * be plumbed in here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7867) static int _nfs41_proc_get_locations(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7868) struct nfs4_fs_locations *locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7869) struct page *page, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7871) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7872) struct rpc_clnt *clnt = server->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7873) u32 bitmask[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7874) [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7876) struct nfs4_fs_locations_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7877) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7878) .page = page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7879) .bitmask = bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7880) .migration = 1, /* skip LOOKUP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7881) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7882) struct nfs4_fs_locations_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7883) .fs_locations = locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7884) .migration = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7885) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7886) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7887) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7888) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7889) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7890) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7891) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7892) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7894) nfs_fattr_init(&locations->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7895) locations->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7896) locations->nlocations = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7898) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7899) status = nfs4_call_sync_sequence(clnt, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7900) &args.seq_args, &res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7901) if (status == NFS4_OK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7902) res.seq_res.sr_status_flags & SEQ4_STATUS_LEASE_MOVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7903) status = -NFS4ERR_LEASE_MOVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7904) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7907) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7909) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7910) * nfs4_proc_get_locations - discover locations for a migrated FSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7911) * @inode: inode on FSID that is migrating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7912) * @locations: result of query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7913) * @page: buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7914) * @cred: credential to use for this operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7915) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7916) * Returns NFS4_OK on success, a negative NFS4ERR status code if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7917) * operation failed, or a negative errno if a local error occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7918) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7919) * On success, "locations" is filled in, but if the server has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7920) * no locations information, NFS_ATTR_FATTR_V4_LOCATIONS is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7921) * asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7922) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7923) * -NFS4ERR_LEASE_MOVED is returned if the server still has leases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7924) * from this client that require migration recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7926) int nfs4_proc_get_locations(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7927) struct nfs4_fs_locations *locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7928) struct page *page, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7930) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7931) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7932) const struct nfs4_mig_recovery_ops *ops =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7933) clp->cl_mvops->mig_recovery_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7934) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7935) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7936) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7937) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7939) dprintk("%s: FSID %llx:%llx on \"%s\"\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7940) (unsigned long long)server->fsid.major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7941) (unsigned long long)server->fsid.minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7942) clp->cl_hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7943) nfs_display_fhandle(NFS_FH(inode), __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7945) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7946) status = ops->get_locations(inode, locations, page, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7947) if (status != -NFS4ERR_DELAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7948) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7949) nfs4_handle_exception(server, status, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7950) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7951) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7954) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7955) * This operation also signals the server that this client is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7956) * performing "lease moved" recovery. The server can stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7957) * returning NFS4ERR_LEASE_MOVED to this client. A RENEW operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7958) * is appended to this compound to identify the client ID which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7959) * performing recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7960) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7961) static int _nfs40_proc_fsid_present(struct inode *inode, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7963) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7964) struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7965) struct rpc_clnt *clnt = server->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7966) struct nfs4_fsid_present_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7967) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7968) .clientid = clp->cl_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7969) .renew = 1, /* append RENEW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7970) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7971) struct nfs4_fsid_present_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7972) .renew = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7974) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7975) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSID_PRESENT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7976) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7977) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7978) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7979) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7980) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7981) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7983) res.fh = nfs_alloc_fhandle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7984) if (res.fh == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7985) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7987) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7988) status = nfs4_call_sync_sequence(clnt, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7989) &args.seq_args, &res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7990) nfs_free_fhandle(res.fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7991) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7992) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7994) do_renew_lease(clp, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7995) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7998) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8000) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8001) * This operation also signals the server that this client is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8002) * performing "lease moved" recovery. The server can stop asserting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8003) * SEQ4_STATUS_LEASE_MOVED for this client. The client ID performing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8004) * this operation is identified in the SEQUENCE operation in this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8005) * compound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8006) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8007) static int _nfs41_proc_fsid_present(struct inode *inode, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8009) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8010) struct rpc_clnt *clnt = server->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8011) struct nfs4_fsid_present_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8012) .fh = NFS_FH(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8014) struct nfs4_fsid_present_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8015) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8016) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8017) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSID_PRESENT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8018) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8019) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8020) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8021) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8022) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8024) res.fh = nfs_alloc_fhandle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8025) if (res.fh == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8026) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8028) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8029) status = nfs4_call_sync_sequence(clnt, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8030) &args.seq_args, &res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8031) nfs_free_fhandle(res.fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8032) if (status == NFS4_OK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8033) res.seq_res.sr_status_flags & SEQ4_STATUS_LEASE_MOVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8034) status = -NFS4ERR_LEASE_MOVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8035) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8038) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8040) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8041) * nfs4_proc_fsid_present - Is this FSID present or absent on server?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8042) * @inode: inode on FSID to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8043) * @cred: credential to use for this operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8045) * Server indicates whether the FSID is present, moved, or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8046) * recognized. This operation is necessary to clear a LEASE_MOVED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8047) * condition for this client ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8048) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8049) * Returns NFS4_OK if the FSID is present on this server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8050) * -NFS4ERR_MOVED if the FSID is no longer present, a negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8051) * NFS4ERR code if some error occurred on the server, or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8052) * negative errno if a local failure occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8053) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8054) int nfs4_proc_fsid_present(struct inode *inode, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8056) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8057) struct nfs_client *clp = server->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8058) const struct nfs4_mig_recovery_ops *ops =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8059) clp->cl_mvops->mig_recovery_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8060) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8061) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8062) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8063) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8065) dprintk("%s: FSID %llx:%llx on \"%s\"\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8066) (unsigned long long)server->fsid.major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8067) (unsigned long long)server->fsid.minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8068) clp->cl_hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8069) nfs_display_fhandle(NFS_FH(inode), __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8071) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8072) status = ops->fsid_present(inode, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8073) if (status != -NFS4ERR_DELAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8074) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8075) nfs4_handle_exception(server, status, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8076) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8077) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8080) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8081) * If 'use_integrity' is true and the state managment nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8082) * cl_rpcclient is using krb5i/p, use the integrity protected cl_rpcclient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8083) * and the machine credential as per RFC3530bis and RFC5661 Security
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8084) * Considerations sections. Otherwise, just use the user cred with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8085) * filesystem's rpc_client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8087) static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors, bool use_integrity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8089) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8090) struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8091) struct nfs_client *clp = NFS_SERVER(dir)->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8092) struct nfs4_secinfo_arg args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8093) .dir_fh = NFS_FH(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8094) .name = name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8095) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8096) struct nfs4_secinfo_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8097) .flavors = flavors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8098) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8099) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8100) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SECINFO],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8101) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8102) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8104) struct nfs4_call_sync_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8105) .seq_server = NFS_SERVER(dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8106) .seq_args = &args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8107) .seq_res = &res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8109) struct rpc_task_setup task_setup = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8110) .rpc_client = clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8111) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8112) .callback_ops = clp->cl_mvops->call_sync_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8113) .callback_data = &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8114) .flags = RPC_TASK_NO_ROUND_ROBIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8116) const struct cred *cred = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8118) if (use_integrity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8119) clnt = clp->cl_rpcclient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8120) task_setup.rpc_client = clnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8122) cred = nfs4_get_clid_cred(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8123) msg.rpc_cred = cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8126) dprintk("NFS call secinfo %s\n", name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8128) nfs4_state_protect(clp, NFS_SP4_MACH_CRED_SECINFO, &clnt, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8129) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8130) status = nfs4_call_sync_custom(&task_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8132) dprintk("NFS reply secinfo: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8134) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8135) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8138) int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8139) struct nfs4_secinfo_flavors *flavors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8141) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8142) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8144) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8145) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8146) err = -NFS4ERR_WRONGSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8148) /* try to use integrity protection with machine cred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8149) if (_nfs4_is_integrity_protected(NFS_SERVER(dir)->nfs_client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8150) err = _nfs4_proc_secinfo(dir, name, flavors, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8153) * if unable to use integrity protection, or SECINFO with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8154) * integrity protection returns NFS4ERR_WRONGSEC (which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8155) * disallowed by spec, but exists in deployed servers) use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8156) * the current filesystem's rpc_client and the user cred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8158) if (err == -NFS4ERR_WRONGSEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8159) err = _nfs4_proc_secinfo(dir, name, flavors, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8161) trace_nfs4_secinfo(dir, name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8162) err = nfs4_handle_exception(NFS_SERVER(dir), err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8163) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8164) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8165) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8168) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8170) * Check the exchange flags returned by the server for invalid flags, having
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8171) * both PNFS and NON_PNFS flags set, and not having one of NON_PNFS, PNFS, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8172) * DS flags set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8174) static int nfs4_check_cl_exchange_flags(u32 flags, u32 version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8176) if (version >= 2 && (flags & ~EXCHGID4_2_FLAG_MASK_R))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8177) goto out_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8178) else if (version < 2 && (flags & ~EXCHGID4_FLAG_MASK_R))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8179) goto out_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8180) if ((flags & EXCHGID4_FLAG_USE_PNFS_MDS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8181) (flags & EXCHGID4_FLAG_USE_NON_PNFS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8182) goto out_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8183) if (!(flags & (EXCHGID4_FLAG_MASK_PNFS)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8184) goto out_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8185) return NFS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8186) out_inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8187) return -NFS4ERR_INVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8190) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8191) nfs41_same_server_scope(struct nfs41_server_scope *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8192) struct nfs41_server_scope *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8194) if (a->server_scope_sz != b->server_scope_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8195) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8196) return memcmp(a->server_scope, b->server_scope, a->server_scope_sz) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8199) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8200) nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8202) struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8203) struct nfs41_bind_conn_to_session_res *res = task->tk_msg.rpc_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8204) struct nfs_client *clp = args->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8206) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8207) case -NFS4ERR_BADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8208) case -NFS4ERR_DEADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8209) nfs4_schedule_session_recovery(clp->cl_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8210) task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8211) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8213) if (args->dir == NFS4_CDFC4_FORE_OR_BOTH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8214) res->dir != NFS4_CDFS4_BOTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8215) rpc_task_close_connection(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8216) if (args->retries++ < MAX_BIND_CONN_TO_SESSION_RETRIES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8217) rpc_restart_call(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8221) static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8222) .rpc_call_done = nfs4_bind_one_conn_to_session_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8226) * nfs4_proc_bind_one_conn_to_session()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8228) * The 4.1 client currently uses the same TCP connection for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8229) * fore and backchannel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8231) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8232) int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8233) struct rpc_xprt *xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8234) struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8235) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8237) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8238) struct nfs41_bind_conn_to_session_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8239) .client = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8240) .dir = NFS4_CDFC4_FORE_OR_BOTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8241) .retries = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8243) struct nfs41_bind_conn_to_session_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8244) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8245) .rpc_proc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8246) &nfs4_procedures[NFSPROC4_CLNT_BIND_CONN_TO_SESSION],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8247) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8248) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8249) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8251) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8252) .rpc_client = clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8253) .rpc_xprt = xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8254) .callback_ops = &nfs4_bind_one_conn_to_session_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8255) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8256) .flags = RPC_TASK_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8258) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8260) nfs4_copy_sessionid(&args.sessionid, &clp->cl_session->sess_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8261) if (!(clp->cl_session->flags & SESSION4_BACK_CHAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8262) args.dir = NFS4_CDFC4_FORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8264) /* Do not set the backchannel flag unless this is clnt->cl_xprt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8265) if (xprt != rcu_access_pointer(clnt->cl_xprt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8266) args.dir = NFS4_CDFC4_FORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8268) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8269) if (!IS_ERR(task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8270) status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8271) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8272) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8273) status = PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8274) trace_nfs4_bind_conn_to_session(clp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8275) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8276) if (memcmp(res.sessionid.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8277) clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8278) dprintk("NFS: %s: Session ID mismatch\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8279) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8281) if ((res.dir & args.dir) != res.dir || res.dir == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8282) dprintk("NFS: %s: Unexpected direction from server\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8283) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8284) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8286) if (res.use_conn_in_rdma_mode != args.use_conn_in_rdma_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8287) dprintk("NFS: %s: Server returned RDMA mode = true\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8288) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8289) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8293) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8296) struct rpc_bind_conn_calldata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8297) struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8298) const struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8299) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8301) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8302) nfs4_proc_bind_conn_to_session_callback(struct rpc_clnt *clnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8303) struct rpc_xprt *xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8304) void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8306) struct rpc_bind_conn_calldata *p = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8308) return nfs4_proc_bind_one_conn_to_session(clnt, xprt, p->clp, p->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8311) int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8313) struct rpc_bind_conn_calldata data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8314) .clp = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8315) .cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8317) return rpc_clnt_iterate_for_each_xprt(clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8318) nfs4_proc_bind_conn_to_session_callback, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8322) * Minimum set of SP4_MACH_CRED operations from RFC 5661 in the enforce map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8323) * and operations we'd like to see to enable certain features in the allow map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8325) static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8326) .how = SP4_MACH_CRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8327) .enforce.u.words = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8328) [1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8329) 1 << (OP_EXCHANGE_ID - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8330) 1 << (OP_CREATE_SESSION - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8331) 1 << (OP_DESTROY_SESSION - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8332) 1 << (OP_DESTROY_CLIENTID - 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8333) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8334) .allow.u.words = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8335) [0] = 1 << (OP_CLOSE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8336) 1 << (OP_OPEN_DOWNGRADE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8337) 1 << (OP_LOCKU) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8338) 1 << (OP_DELEGRETURN) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8339) 1 << (OP_COMMIT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8340) [1] = 1 << (OP_SECINFO - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8341) 1 << (OP_SECINFO_NO_NAME - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8342) 1 << (OP_LAYOUTRETURN - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8343) 1 << (OP_TEST_STATEID - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8344) 1 << (OP_FREE_STATEID - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8345) 1 << (OP_WRITE - 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8347) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8350) * Select the state protection mode for client `clp' given the server results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8351) * from exchange_id in `sp'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8352) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8353) * Returns 0 on success, negative errno otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8354) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8355) static int nfs4_sp4_select_mode(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8356) struct nfs41_state_protection *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8358) static const u32 supported_enforce[NFS4_OP_MAP_NUM_WORDS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8359) [1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8360) 1 << (OP_EXCHANGE_ID - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8361) 1 << (OP_CREATE_SESSION - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8362) 1 << (OP_DESTROY_SESSION - 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8363) 1 << (OP_DESTROY_CLIENTID - 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8365) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8366) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8367) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8369) if (sp->how == SP4_MACH_CRED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8370) /* Print state protect result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8371) dfprintk(MOUNT, "Server SP4_MACH_CRED support:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8372) for (i = 0; i <= LAST_NFS4_OP; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8373) if (test_bit(i, sp->enforce.u.longs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8374) dfprintk(MOUNT, " enforce op %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8375) if (test_bit(i, sp->allow.u.longs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8376) dfprintk(MOUNT, " allow op %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8379) /* make sure nothing is on enforce list that isn't supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8380) for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8381) if (sp->enforce.u.words[i] & ~supported_enforce[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8382) dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8383) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8384) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8388) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8389) * Minimal mode - state operations are allowed to use machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8390) * credential. Note this already happens by default, so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8391) * client doesn't have to do anything more than the negotiation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8393) * NOTE: we don't care if EXCHANGE_ID is in the list -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8394) * we're already using the machine cred for exchange_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8395) * and will never use a different cred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8397) if (test_bit(OP_BIND_CONN_TO_SESSION, sp->enforce.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8398) test_bit(OP_CREATE_SESSION, sp->enforce.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8399) test_bit(OP_DESTROY_SESSION, sp->enforce.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8400) test_bit(OP_DESTROY_CLIENTID, sp->enforce.u.longs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8401) dfprintk(MOUNT, "sp4_mach_cred:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8402) dfprintk(MOUNT, " minimal mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8403) __set_bit(NFS_SP4_MACH_CRED_MINIMAL, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8404) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8405) dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8406) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8407) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8410) if (test_bit(OP_CLOSE, sp->allow.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8411) test_bit(OP_OPEN_DOWNGRADE, sp->allow.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8412) test_bit(OP_DELEGRETURN, sp->allow.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8413) test_bit(OP_LOCKU, sp->allow.u.longs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8414) dfprintk(MOUNT, " cleanup mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8415) __set_bit(NFS_SP4_MACH_CRED_CLEANUP, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8418) if (test_bit(OP_LAYOUTRETURN, sp->allow.u.longs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8419) dfprintk(MOUNT, " pnfs cleanup mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8420) __set_bit(NFS_SP4_MACH_CRED_PNFS_CLEANUP, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8423) if (test_bit(OP_SECINFO, sp->allow.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8424) test_bit(OP_SECINFO_NO_NAME, sp->allow.u.longs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8425) dfprintk(MOUNT, " secinfo mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8426) __set_bit(NFS_SP4_MACH_CRED_SECINFO, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8429) if (test_bit(OP_TEST_STATEID, sp->allow.u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8430) test_bit(OP_FREE_STATEID, sp->allow.u.longs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8431) dfprintk(MOUNT, " stateid mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8432) __set_bit(NFS_SP4_MACH_CRED_STATEID, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8435) if (test_bit(OP_WRITE, sp->allow.u.longs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8436) dfprintk(MOUNT, " write mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8437) __set_bit(NFS_SP4_MACH_CRED_WRITE, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8440) if (test_bit(OP_COMMIT, sp->allow.u.longs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8441) dfprintk(MOUNT, " commit mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8442) __set_bit(NFS_SP4_MACH_CRED_COMMIT, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8445) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8446) clp->cl_sp4_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8447) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8450) struct nfs41_exchange_id_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8451) struct nfs41_exchange_id_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8452) struct nfs41_exchange_id_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8455) static void nfs4_exchange_id_release(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8457) struct nfs41_exchange_id_data *cdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8458) (struct nfs41_exchange_id_data *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8460) nfs_put_client(cdata->args.client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8461) kfree(cdata->res.impl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8462) kfree(cdata->res.server_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8463) kfree(cdata->res.server_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8464) kfree(cdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8467) static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8468) .rpc_release = nfs4_exchange_id_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8469) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8472) * _nfs4_proc_exchange_id()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8474) * Wrapper for EXCHANGE_ID operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8476) static struct rpc_task *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8477) nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8478) u32 sp4_how, struct rpc_xprt *xprt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8480) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8481) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8482) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8483) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8484) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8485) .rpc_client = clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8486) .callback_ops = &nfs4_exchange_id_call_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8487) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8488) .flags = RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8489) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8490) struct nfs41_exchange_id_data *calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8491) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8493) if (!refcount_inc_not_zero(&clp->cl_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8494) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8496) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8497) calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8498) if (!calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8499) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8501) nfs4_init_boot_verifier(clp, &calldata->args.verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8503) status = nfs4_init_uniform_client_string(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8504) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8505) goto out_calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8507) calldata->res.server_owner = kzalloc(sizeof(struct nfs41_server_owner),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8508) GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8509) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8510) if (unlikely(calldata->res.server_owner == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8511) goto out_calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8513) calldata->res.server_scope = kzalloc(sizeof(struct nfs41_server_scope),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8514) GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8515) if (unlikely(calldata->res.server_scope == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8516) goto out_server_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8518) calldata->res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8519) if (unlikely(calldata->res.impl_id == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8520) goto out_server_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8522) switch (sp4_how) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8523) case SP4_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8524) calldata->args.state_protect.how = SP4_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8527) case SP4_MACH_CRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8528) calldata->args.state_protect = nfs4_sp4_mach_cred_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8531) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8532) /* unsupported! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8533) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8534) status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8535) goto out_impl_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8537) if (xprt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8538) task_setup_data.rpc_xprt = xprt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8539) task_setup_data.flags |= RPC_TASK_SOFTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8540) memcpy(calldata->args.verifier.data, clp->cl_confirm.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8541) sizeof(calldata->args.verifier.data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8543) calldata->args.client = clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8544) calldata->args.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8545) EXCHGID4_FLAG_BIND_PRINC_STATEID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8546) #ifdef CONFIG_NFS_V4_1_MIGRATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8547) calldata->args.flags |= EXCHGID4_FLAG_SUPP_MOVED_MIGR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8548) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8549) msg.rpc_argp = &calldata->args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8550) msg.rpc_resp = &calldata->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8551) task_setup_data.callback_data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8553) return rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8555) out_impl_id:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8556) kfree(calldata->res.impl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8557) out_server_scope:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8558) kfree(calldata->res.server_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8559) out_server_owner:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8560) kfree(calldata->res.server_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8561) out_calldata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8562) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8563) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8564) nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8565) return ERR_PTR(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8568) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8569) * _nfs4_proc_exchange_id()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8570) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8571) * Wrapper for EXCHANGE_ID operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8572) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8573) static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8574) u32 sp4_how)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8576) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8577) struct nfs41_exchange_id_args *argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8578) struct nfs41_exchange_id_res *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8579) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8580) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8582) task = nfs4_run_exchange_id(clp, cred, sp4_how, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8583) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8584) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8586) argp = task->tk_msg.rpc_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8587) resp = task->tk_msg.rpc_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8588) status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8589) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8590) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8592) status = nfs4_check_cl_exchange_flags(resp->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8593) clp->cl_mvops->minor_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8594) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8595) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8597) status = nfs4_sp4_select_mode(clp, &resp->state_protect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8598) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8599) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8601) do_renew_lease(clp, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8603) clp->cl_clientid = resp->clientid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8604) clp->cl_exchange_flags = resp->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8605) clp->cl_seqid = resp->seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8606) /* Client ID is not confirmed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8607) if (!(resp->flags & EXCHGID4_FLAG_CONFIRMED_R))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8608) clear_bit(NFS4_SESSION_ESTABLISHED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8609) &clp->cl_session->session_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8611) if (clp->cl_serverscope != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8612) !nfs41_same_server_scope(clp->cl_serverscope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8613) resp->server_scope)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8614) dprintk("%s: server_scope mismatch detected\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8615) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8616) set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8619) swap(clp->cl_serverowner, resp->server_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8620) swap(clp->cl_serverscope, resp->server_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8621) swap(clp->cl_implid, resp->impl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8623) /* Save the EXCHANGE_ID verifier session trunk tests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8624) memcpy(clp->cl_confirm.data, argp->verifier.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8625) sizeof(clp->cl_confirm.data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8626) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8627) trace_nfs4_exchange_id(clp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8628) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8629) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8632) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8633) * nfs4_proc_exchange_id()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8634) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8635) * Returns zero, a negative errno, or a negative NFS4ERR status code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8636) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8637) * Since the clientid has expired, all compounds using sessions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8638) * associated with the stale clientid will be returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8639) * NFS4ERR_BADSESSION in the sequence operation, and will therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8640) * be in some phase of session reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8641) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8642) * Will attempt to negotiate SP4_MACH_CRED if krb5i / krb5p auth is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8644) int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8646) rpc_authflavor_t authflavor = clp->cl_rpcclient->cl_auth->au_flavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8647) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8649) /* try SP4_MACH_CRED if krb5i/p */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8650) if (authflavor == RPC_AUTH_GSS_KRB5I ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8651) authflavor == RPC_AUTH_GSS_KRB5P) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8652) status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8653) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8657) /* try SP4_NONE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8658) return _nfs4_proc_exchange_id(clp, cred, SP4_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8661) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8662) * nfs4_test_session_trunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8664) * This is an add_xprt_test() test function called from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8665) * rpc_clnt_setup_test_and_add_xprt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8666) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8667) * The rpc_xprt_switch is referrenced by rpc_clnt_setup_test_and_add_xprt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8668) * and is dereferrenced in nfs4_exchange_id_release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8669) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8670) * Upon success, add the new transport to the rpc_clnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8671) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8672) * @clnt: struct rpc_clnt to get new transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8673) * @xprt: the rpc_xprt to test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8674) * @data: call data for _nfs4_proc_exchange_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8676) void nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8677) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8679) struct nfs4_add_xprt_data *adata = (struct nfs4_add_xprt_data *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8680) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8681) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8683) u32 sp4_how;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8685) dprintk("--> %s try %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8686) xprt->address_strings[RPC_DISPLAY_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8688) sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8690) /* Test connection for session trunking. Async exchange_id call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8691) task = nfs4_run_exchange_id(adata->clp, adata->cred, sp4_how, xprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8692) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8693) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8695) status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8696) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8697) status = nfs4_detect_session_trunking(adata->clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8698) task->tk_msg.rpc_resp, xprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8700) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8701) rpc_clnt_xprt_switch_add_xprt(clnt, xprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8703) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8705) EXPORT_SYMBOL_GPL(nfs4_test_session_trunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8707) static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8708) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8710) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8711) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_CLIENTID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8712) .rpc_argp = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8713) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8714) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8715) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8717) status = rpc_call_sync(clp->cl_rpcclient, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8718) RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8719) trace_nfs4_destroy_clientid(clp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8720) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8721) dprintk("NFS: Got error %d from the server %s on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8722) "DESTROY_CLIENTID.", status, clp->cl_hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8723) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8726) static int nfs4_proc_destroy_clientid(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8727) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8729) unsigned int loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8730) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8732) for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8733) ret = _nfs4_proc_destroy_clientid(clp, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8734) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8735) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8736) case -NFS4ERR_CLIENTID_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8737) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8739) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8740) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8743) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8746) int nfs4_destroy_clientid(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8748) const struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8749) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8751) if (clp->cl_mvops->minor_version < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8752) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8753) if (clp->cl_exchange_flags == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8754) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8755) if (clp->cl_preserve_clid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8756) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8757) cred = nfs4_get_clid_cred(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8758) ret = nfs4_proc_destroy_clientid(clp, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8759) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8760) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8761) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8762) case -NFS4ERR_STALE_CLIENTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8763) clp->cl_exchange_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8765) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8766) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8769) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8771) struct nfs4_get_lease_time_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8772) struct nfs4_get_lease_time_args *args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8773) struct nfs4_get_lease_time_res *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8774) struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8775) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8777) static void nfs4_get_lease_time_prepare(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8778) void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8780) struct nfs4_get_lease_time_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8781) (struct nfs4_get_lease_time_data *)calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8783) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8784) /* just setup sequence, do not trigger session recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8785) since we're invoked within one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8786) nfs4_setup_sequence(data->clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8787) &data->args->la_seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8788) &data->res->lr_seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8789) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8790) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8794) * Called from nfs4_state_manager thread for session setup, so don't recover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8795) * from sequence operation or clientid errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8797) static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8799) struct nfs4_get_lease_time_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8800) (struct nfs4_get_lease_time_data *)calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8802) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8803) if (!nfs4_sequence_done(task, &data->res->lr_seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8804) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8805) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8806) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8807) case -NFS4ERR_GRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8808) dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8809) rpc_delay(task, NFS4_POLL_RETRY_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8810) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8811) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8812) case -NFS4ERR_RETRY_UNCACHED_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8813) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8814) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8816) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8819) static const struct rpc_call_ops nfs4_get_lease_time_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8820) .rpc_call_prepare = nfs4_get_lease_time_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8821) .rpc_call_done = nfs4_get_lease_time_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8822) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8824) int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8826) struct nfs4_get_lease_time_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8827) struct nfs4_get_lease_time_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8828) .lr_fsinfo = fsinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8829) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8830) struct nfs4_get_lease_time_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8831) .args = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8832) .res = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8833) .clp = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8834) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8835) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8836) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GET_LEASE_TIME],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8837) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8838) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8839) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8840) struct rpc_task_setup task_setup = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8841) .rpc_client = clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8842) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8843) .callback_ops = &nfs4_get_lease_time_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8844) .callback_data = &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8845) .flags = RPC_TASK_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8846) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8848) nfs4_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8849) return nfs4_call_sync_custom(&task_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8852) #ifdef CONFIG_NFS_V4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8854) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8855) * Initialize the values to be used by the client in CREATE_SESSION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8856) * If nfs4_init_session set the fore channel request and response sizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8857) * use them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8858) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8859) * Set the back channel max_resp_sz_cached to zero to force the client to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8860) * always set csa_cachethis to FALSE because the current implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8861) * of the back channel DRC only supports caching the CB_SEQUENCE operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8863) static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8864) struct rpc_clnt *clnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8866) unsigned int max_rqst_sz, max_resp_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8867) unsigned int max_bc_payload = rpc_max_bc_payload(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8868) unsigned int max_bc_slots = rpc_num_bc_slots(clnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8870) max_rqst_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxwrite_overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8871) max_resp_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxread_overhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8873) /* Fore channel attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8874) args->fc_attrs.max_rqst_sz = max_rqst_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8875) args->fc_attrs.max_resp_sz = max_resp_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8876) args->fc_attrs.max_ops = NFS4_MAX_OPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8877) args->fc_attrs.max_reqs = max_session_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8879) dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8880) "max_ops=%u max_reqs=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8881) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8882) args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8883) args->fc_attrs.max_ops, args->fc_attrs.max_reqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8885) /* Back channel attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8886) args->bc_attrs.max_rqst_sz = max_bc_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8887) args->bc_attrs.max_resp_sz = max_bc_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8888) args->bc_attrs.max_resp_sz_cached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8889) args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8890) args->bc_attrs.max_reqs = max_t(unsigned short, max_session_cb_slots, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8891) if (args->bc_attrs.max_reqs > max_bc_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8892) args->bc_attrs.max_reqs = max_bc_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8894) dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8895) "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8896) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8897) args->bc_attrs.max_rqst_sz, args->bc_attrs.max_resp_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8898) args->bc_attrs.max_resp_sz_cached, args->bc_attrs.max_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8899) args->bc_attrs.max_reqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8902) static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8903) struct nfs41_create_session_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8905) struct nfs4_channel_attrs *sent = &args->fc_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8906) struct nfs4_channel_attrs *rcvd = &res->fc_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8908) if (rcvd->max_resp_sz > sent->max_resp_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8909) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8910) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8911) * Our requested max_ops is the minimum we need; we're not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8912) * prepared to break up compounds into smaller pieces than that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8913) * So, no point even trying to continue if the server won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8914) * cooperate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8916) if (rcvd->max_ops < sent->max_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8917) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8918) if (rcvd->max_reqs == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8919) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8920) if (rcvd->max_reqs > NFS4_MAX_SLOT_TABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8921) rcvd->max_reqs = NFS4_MAX_SLOT_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8922) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8925) static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8926) struct nfs41_create_session_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8928) struct nfs4_channel_attrs *sent = &args->bc_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8929) struct nfs4_channel_attrs *rcvd = &res->bc_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8931) if (!(res->flags & SESSION4_BACK_CHAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8932) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8933) if (rcvd->max_rqst_sz > sent->max_rqst_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8934) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8935) if (rcvd->max_resp_sz < sent->max_resp_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8936) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8937) if (rcvd->max_resp_sz_cached > sent->max_resp_sz_cached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8938) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8939) if (rcvd->max_ops > sent->max_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8940) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8941) if (rcvd->max_reqs > sent->max_reqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8942) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8943) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8944) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8947) static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8948) struct nfs41_create_session_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8950) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8952) ret = nfs4_verify_fore_channel_attrs(args, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8953) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8954) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8955) return nfs4_verify_back_channel_attrs(args, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8958) static void nfs4_update_session(struct nfs4_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8959) struct nfs41_create_session_res *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8961) nfs4_copy_sessionid(&session->sess_id, &res->sessionid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8962) /* Mark client id and session as being confirmed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8963) session->clp->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8964) set_bit(NFS4_SESSION_ESTABLISHED, &session->session_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8965) session->flags = res->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8966) memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8967) if (res->flags & SESSION4_BACK_CHAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8968) memcpy(&session->bc_attrs, &res->bc_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8969) sizeof(session->bc_attrs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8972) static int _nfs4_proc_create_session(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8973) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8975) struct nfs4_session *session = clp->cl_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8976) struct nfs41_create_session_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8977) .client = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8978) .clientid = clp->cl_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8979) .seqid = clp->cl_seqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8980) .cb_program = NFS4_CALLBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8981) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8982) struct nfs41_create_session_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8984) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8985) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8986) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8987) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8988) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8989) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8990) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8992) nfs4_init_channel_attrs(&args, clp->cl_rpcclient);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8993) args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8995) status = rpc_call_sync(session->clp->cl_rpcclient, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8996) RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8997) trace_nfs4_create_session(clp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8999) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9000) case -NFS4ERR_STALE_CLIENTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9001) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9002) case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9003) case -EACCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9004) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9005) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9008) clp->cl_seqid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9009) if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9010) /* Verify the session's negotiated channel_attrs values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9011) status = nfs4_verify_channel_attrs(&args, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9012) /* Increment the clientid slot sequence id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9013) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9014) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9015) nfs4_update_session(session, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9017) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9018) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9022) * Issues a CREATE_SESSION operation to the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9023) * It is the responsibility of the caller to verify the session is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9024) * expired before calling this routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9025) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9026) int nfs4_proc_create_session(struct nfs_client *clp, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9028) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9029) unsigned *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9030) struct nfs4_session *session = clp->cl_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9032) dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9034) status = _nfs4_proc_create_session(clp, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9035) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9036) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9038) /* Init or reset the session slot tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9039) status = nfs4_setup_session_slot_tables(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9040) dprintk("slot table setup returned %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9041) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9042) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9044) ptr = (unsigned *)&session->sess_id.data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9045) dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9046) clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9047) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9048) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9049) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9053) * Issue the over-the-wire RPC DESTROY_SESSION.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9054) * The caller must serialize access to this routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9056) int nfs4_proc_destroy_session(struct nfs4_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9057) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9059) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9060) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9061) .rpc_argp = session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9062) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9063) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9064) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9066) dprintk("--> nfs4_proc_destroy_session\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9068) /* session is still being setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9069) if (!test_and_clear_bit(NFS4_SESSION_ESTABLISHED, &session->session_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9070) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9072) status = rpc_call_sync(session->clp->cl_rpcclient, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9073) RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9074) trace_nfs4_destroy_session(session->clp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9076) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9077) dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9078) "Session has been destroyed regardless...\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9080) dprintk("<-- nfs4_proc_destroy_session\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9081) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9084) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9085) * Renew the cl_session lease.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9087) struct nfs4_sequence_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9088) struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9089) struct nfs4_sequence_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9090) struct nfs4_sequence_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9091) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9093) static void nfs41_sequence_release(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9095) struct nfs4_sequence_data *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9096) struct nfs_client *clp = calldata->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9098) if (refcount_read(&clp->cl_count) > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9099) nfs4_schedule_state_renewal(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9100) nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9101) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9104) static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9106) switch(task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9107) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9108) rpc_delay(task, NFS4_POLL_RETRY_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9109) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9110) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9111) nfs4_schedule_lease_recovery(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9116) static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9118) struct nfs4_sequence_data *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9119) struct nfs_client *clp = calldata->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9121) if (!nfs41_sequence_done(task, task->tk_msg.rpc_resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9122) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9124) trace_nfs4_sequence(clp, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9125) if (task->tk_status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9126) dprintk("%s ERROR %d\n", __func__, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9127) if (refcount_read(&clp->cl_count) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9128) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9130) if (nfs41_sequence_handle_errors(task, clp) == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9131) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9132) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9135) dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9136) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9137) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9140) static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9142) struct nfs4_sequence_data *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9143) struct nfs_client *clp = calldata->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9144) struct nfs4_sequence_args *args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9145) struct nfs4_sequence_res *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9147) args = task->tk_msg.rpc_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9148) res = task->tk_msg.rpc_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9150) nfs4_setup_sequence(clp, args, res, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9153) static const struct rpc_call_ops nfs41_sequence_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9154) .rpc_call_done = nfs41_sequence_call_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9155) .rpc_call_prepare = nfs41_sequence_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9156) .rpc_release = nfs41_sequence_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9159) static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9160) const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9161) struct nfs4_slot *slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9162) bool is_privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9164) struct nfs4_sequence_data *calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9165) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9166) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9167) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9169) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9170) .rpc_client = clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9171) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9172) .callback_ops = &nfs41_sequence_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9173) .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9175) struct rpc_task *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9177) ret = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9178) if (!refcount_inc_not_zero(&clp->cl_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9179) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9181) ret = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9182) calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9183) if (calldata == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9184) goto out_put_clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9185) nfs4_init_sequence(&calldata->args, &calldata->res, 0, is_privileged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9186) nfs4_sequence_attach_slot(&calldata->args, &calldata->res, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9187) msg.rpc_argp = &calldata->args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9188) msg.rpc_resp = &calldata->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9189) calldata->clp = clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9190) task_setup_data.callback_data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9192) ret = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9193) if (IS_ERR(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9194) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9195) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9196) out_put_clp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9197) nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9198) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9199) nfs41_release_slot(slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9200) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9203) static int nfs41_proc_async_sequence(struct nfs_client *clp, const struct cred *cred, unsigned renew_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9205) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9206) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9208) if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9209) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9210) task = _nfs41_proc_sequence(clp, cred, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9211) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9212) ret = PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9213) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9214) rpc_put_task_async(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9215) dprintk("<-- %s status=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9219) static int nfs4_proc_sequence(struct nfs_client *clp, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9221) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9222) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9224) task = _nfs41_proc_sequence(clp, cred, NULL, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9225) if (IS_ERR(task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9226) ret = PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9227) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9229) ret = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9230) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9231) ret = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9232) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9233) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9234) dprintk("<-- %s status=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9235) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9238) struct nfs4_reclaim_complete_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9239) struct nfs_client *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9240) struct nfs41_reclaim_complete_args arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9241) struct nfs41_reclaim_complete_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9244) static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9246) struct nfs4_reclaim_complete_data *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9248) nfs4_setup_sequence(calldata->clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9249) &calldata->arg.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9250) &calldata->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9251) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9254) static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9256) switch(task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9257) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9258) wake_up_all(&clp->cl_lock_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9259) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9260) case -NFS4ERR_COMPLETE_ALREADY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9261) case -NFS4ERR_WRONG_CRED: /* What to do here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9263) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9264) rpc_delay(task, NFS4_POLL_RETRY_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9265) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9266) case -NFS4ERR_RETRY_UNCACHED_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9267) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9268) case -NFS4ERR_BADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9269) case -NFS4ERR_DEADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9270) case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9272) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9273) nfs4_schedule_lease_recovery(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9278) static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9280) struct nfs4_reclaim_complete_data *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9281) struct nfs_client *clp = calldata->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9282) struct nfs4_sequence_res *res = &calldata->res.seq_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9284) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9285) if (!nfs41_sequence_done(task, res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9286) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9288) trace_nfs4_reclaim_complete(clp, task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9289) if (nfs41_reclaim_complete_handle_errors(task, clp) == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9290) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9291) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9293) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9296) static void nfs4_free_reclaim_complete_data(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9298) struct nfs4_reclaim_complete_data *calldata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9300) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9303) static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9304) .rpc_call_prepare = nfs4_reclaim_complete_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9305) .rpc_call_done = nfs4_reclaim_complete_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9306) .rpc_release = nfs4_free_reclaim_complete_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9310) * Issue a global reclaim complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9312) static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9313) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9315) struct nfs4_reclaim_complete_data *calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9316) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9317) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9318) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9320) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9321) .rpc_client = clp->cl_rpcclient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9322) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9323) .callback_ops = &nfs4_reclaim_complete_call_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9324) .flags = RPC_TASK_NO_ROUND_ROBIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9326) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9328) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9329) calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9330) if (calldata == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9331) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9332) calldata->clp = clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9333) calldata->arg.one_fs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9335) nfs4_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9336) msg.rpc_argp = &calldata->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9337) msg.rpc_resp = &calldata->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9338) task_setup_data.callback_data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9339) status = nfs4_call_sync_custom(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9340) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9341) dprintk("<-- %s status=%d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9342) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9345) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9346) nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9348) struct nfs4_layoutget *lgp = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9349) struct nfs_server *server = NFS_SERVER(lgp->args.inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9351) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9352) nfs4_setup_sequence(server->nfs_client, &lgp->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9353) &lgp->res.seq_res, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9354) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9357) static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9359) struct nfs4_layoutget *lgp = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9361) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9362) nfs41_sequence_process(task, &lgp->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9363) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9366) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9367) nfs4_layoutget_handle_exception(struct rpc_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9368) struct nfs4_layoutget *lgp, struct nfs4_exception *exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9370) struct inode *inode = lgp->args.inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9371) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9372) struct pnfs_layout_hdr *lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9373) int nfs4err = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9374) int err, status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9375) LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9377) dprintk("--> %s tk_status => %d\n", __func__, -task->tk_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9379) nfs4_sequence_free_slot(&lgp->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9381) switch (nfs4err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9382) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9383) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9386) * NFS4ERR_LAYOUTUNAVAILABLE means we are not supposed to use pnfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9387) * on the file. set tk_status to -ENODATA to tell upper layer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9388) * retry go inband.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9390) case -NFS4ERR_LAYOUTUNAVAILABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9391) status = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9392) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9394) * NFS4ERR_BADLAYOUT means the MDS cannot return a layout of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9395) * length lgp->args.minlength != 0 (see RFC5661 section 18.43.3).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9397) case -NFS4ERR_BADLAYOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9398) status = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9399) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9401) * NFS4ERR_LAYOUTTRYLATER is a conflict with another client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9402) * (or clients) writing to the same RAID stripe except when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9403) * the minlength argument is 0 (see RFC5661 section 18.43.3).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9405) * Treat it like we would RECALLCONFLICT -- we retry for a little
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9406) * while, and then eventually give up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9408) case -NFS4ERR_LAYOUTTRYLATER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9409) if (lgp->args.minlength == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9410) status = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9411) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9413) status = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9415) case -NFS4ERR_RECALLCONFLICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9416) status = -ERECALLCONFLICT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9418) case -NFS4ERR_DELEG_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9419) case -NFS4ERR_ADMIN_REVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9420) case -NFS4ERR_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9421) case -NFS4ERR_BAD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9422) exception->timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9423) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9424) lo = NFS_I(inode)->layout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9425) /* If the open stateid was bad, then recover it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9426) if (!lo || test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9427) !nfs4_stateid_match_other(&lgp->args.stateid, &lo->plh_stateid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9428) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9429) exception->state = lgp->args.ctx->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9430) exception->stateid = &lgp->args.stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9434) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9435) * Mark the bad layout state as invalid, then retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9437) pnfs_mark_layout_stateid_invalid(lo, &head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9438) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9439) nfs_commit_inode(inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9440) pnfs_free_lseg_list(&head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9441) status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9442) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9445) err = nfs4_handle_exception(server, nfs4err, exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9446) if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9447) if (exception->retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9448) status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9449) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9450) status = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9452) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9453) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9454) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9457) size_t max_response_pages(struct nfs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9459) u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9460) return nfs_page_array_len(0, max_resp_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9463) static void nfs4_layoutget_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9465) struct nfs4_layoutget *lgp = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9467) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9468) nfs4_sequence_free_slot(&lgp->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9469) pnfs_layoutget_free(lgp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9470) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9473) static const struct rpc_call_ops nfs4_layoutget_call_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9474) .rpc_call_prepare = nfs4_layoutget_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9475) .rpc_call_done = nfs4_layoutget_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9476) .rpc_release = nfs4_layoutget_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9479) struct pnfs_layout_segment *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9480) nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9482) struct inode *inode = lgp->args.inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9483) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9484) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9485) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9486) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9487) .rpc_argp = &lgp->args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9488) .rpc_resp = &lgp->res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9489) .rpc_cred = lgp->cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9490) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9491) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9492) .rpc_client = server->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9493) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9494) .callback_ops = &nfs4_layoutget_call_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9495) .callback_data = lgp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9496) .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9497) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9498) struct pnfs_layout_segment *lseg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9499) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9500) .inode = inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9501) .timeout = *timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9503) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9505) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9507) /* nfs4_layoutget_release calls pnfs_put_layout_hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9508) pnfs_get_layout_hdr(NFS_I(inode)->layout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9510) nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9512) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9514) status = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9515) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9516) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9518) if (task->tk_status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9519) status = nfs4_layoutget_handle_exception(task, lgp, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9520) *timeout = exception.timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9521) } else if (lgp->res.layoutp->len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9522) status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9523) *timeout = nfs4_update_delay(&exception.timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9524) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9525) lseg = pnfs_layout_process(lgp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9526) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9527) trace_nfs4_layoutget(lgp->args.ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9528) &lgp->args.range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9529) &lgp->res.range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9530) &lgp->res.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9531) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9533) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9534) dprintk("<-- %s status=%d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9535) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9536) return ERR_PTR(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9537) return lseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9540) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9541) nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9543) struct nfs4_layoutreturn *lrp = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9545) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9546) nfs4_setup_sequence(lrp->clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9547) &lrp->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9548) &lrp->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9549) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9550) if (!pnfs_layout_is_valid(lrp->args.layout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9551) rpc_exit(task, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9554) static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9556) struct nfs4_layoutreturn *lrp = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9557) struct nfs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9559) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9561) if (!nfs41_sequence_process(task, &lrp->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9562) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9565) * Was there an RPC level error? Assume the call succeeded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9566) * and that we need to release the layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9568) if (task->tk_rpc_status != 0 && RPC_WAS_SENT(task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9569) lrp->res.lrs_present = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9570) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9573) server = NFS_SERVER(lrp->args.inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9574) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9575) case -NFS4ERR_OLD_STATEID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9576) if (nfs4_layout_refresh_old_stateid(&lrp->args.stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9577) &lrp->args.range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9578) lrp->args.inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9579) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9580) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9581) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9582) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9583) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9584) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9586) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9587) if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9588) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9589) goto out_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9591) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9592) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9593) out_restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9594) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9595) nfs4_sequence_free_slot(&lrp->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9596) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9599) static void nfs4_layoutreturn_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9601) struct nfs4_layoutreturn *lrp = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9602) struct pnfs_layout_hdr *lo = lrp->args.layout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9604) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9605) pnfs_layoutreturn_free_lsegs(lo, &lrp->args.stateid, &lrp->args.range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9606) lrp->res.lrs_present ? &lrp->res.stateid : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9607) nfs4_sequence_free_slot(&lrp->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9608) if (lrp->ld_private.ops && lrp->ld_private.ops->free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9609) lrp->ld_private.ops->free(&lrp->ld_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9610) pnfs_put_layout_hdr(lrp->args.layout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9611) nfs_iput_and_deactive(lrp->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9612) put_cred(lrp->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9613) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9614) dprintk("<-- %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9617) static const struct rpc_call_ops nfs4_layoutreturn_call_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9618) .rpc_call_prepare = nfs4_layoutreturn_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9619) .rpc_call_done = nfs4_layoutreturn_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9620) .rpc_release = nfs4_layoutreturn_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9621) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9623) int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9625) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9626) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9627) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9628) .rpc_argp = &lrp->args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9629) .rpc_resp = &lrp->res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9630) .rpc_cred = lrp->cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9631) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9632) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9633) .rpc_client = NFS_SERVER(lrp->args.inode)->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9634) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9635) .callback_ops = &nfs4_layoutreturn_call_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9636) .callback_data = lrp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9638) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9640) nfs4_state_protect(NFS_SERVER(lrp->args.inode)->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9641) NFS_SP4_MACH_CRED_PNFS_CLEANUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9642) &task_setup_data.rpc_client, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9644) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9645) lrp->inode = nfs_igrab_and_active(lrp->args.inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9646) if (!sync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9647) if (!lrp->inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9648) nfs4_layoutreturn_release(lrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9649) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9651) task_setup_data.flags |= RPC_TASK_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9653) if (!lrp->inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9654) nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9655) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9656) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9657) nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9658) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9659) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9660) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9661) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9662) if (sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9663) status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9664) trace_nfs4_layoutreturn(lrp->args.inode, &lrp->args.stateid, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9665) dprintk("<-- %s status=%d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9666) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9667) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9670) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9671) _nfs4_proc_getdeviceinfo(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9672) struct pnfs_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9673) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9675) struct nfs4_getdeviceinfo_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9676) .pdev = pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9677) .notify_types = NOTIFY_DEVICEID4_CHANGE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9678) NOTIFY_DEVICEID4_DELETE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9679) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9680) struct nfs4_getdeviceinfo_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9681) .pdev = pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9682) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9683) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9684) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETDEVICEINFO],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9685) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9686) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9687) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9688) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9689) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9691) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9692) status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9693) if (res.notification & ~args.notify_types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9694) dprintk("%s: unsupported notification\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9695) if (res.notification != args.notify_types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9696) pdev->nocache = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9698) dprintk("<-- %s status=%d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9700) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9703) int nfs4_proc_getdeviceinfo(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9704) struct pnfs_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9705) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9707) struct nfs4_exception exception = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9708) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9710) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9711) err = nfs4_handle_exception(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9712) _nfs4_proc_getdeviceinfo(server, pdev, cred),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9713) &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9714) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9715) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9717) EXPORT_SYMBOL_GPL(nfs4_proc_getdeviceinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9719) static void nfs4_layoutcommit_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9721) struct nfs4_layoutcommit_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9722) struct nfs_server *server = NFS_SERVER(data->args.inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9724) nfs4_setup_sequence(server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9725) &data->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9726) &data->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9727) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9730) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9731) nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9733) struct nfs4_layoutcommit_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9734) struct nfs_server *server = NFS_SERVER(data->args.inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9736) if (!nfs41_sequence_done(task, &data->res.seq_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9737) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9739) switch (task->tk_status) { /* Just ignore these failures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9740) case -NFS4ERR_DELEG_REVOKED: /* layout was recalled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9741) case -NFS4ERR_BADIOMODE: /* no IOMODE_RW layout for range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9742) case -NFS4ERR_BADLAYOUT: /* no layout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9743) case -NFS4ERR_GRACE: /* loca_recalim always false */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9744) task->tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9745) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9746) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9747) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9748) if (nfs4_async_handle_error(task, server, NULL, NULL) == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9749) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9750) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9755) static void nfs4_layoutcommit_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9757) struct nfs4_layoutcommit_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9759) pnfs_cleanup_layoutcommit(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9760) nfs_post_op_update_inode_force_wcc(data->args.inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9761) data->res.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9762) put_cred(data->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9763) nfs_iput_and_deactive(data->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9764) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9767) static const struct rpc_call_ops nfs4_layoutcommit_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9768) .rpc_call_prepare = nfs4_layoutcommit_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9769) .rpc_call_done = nfs4_layoutcommit_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9770) .rpc_release = nfs4_layoutcommit_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9771) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9773) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9774) nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9776) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9777) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTCOMMIT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9778) .rpc_argp = &data->args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9779) .rpc_resp = &data->res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9780) .rpc_cred = data->cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9781) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9782) struct rpc_task_setup task_setup_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9783) .task = &data->task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9784) .rpc_client = NFS_CLIENT(data->args.inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9785) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9786) .callback_ops = &nfs4_layoutcommit_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9787) .callback_data = data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9788) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9789) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9790) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9792) dprintk("NFS: initiating layoutcommit call. sync %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9793) "lbw: %llu inode %lu\n", sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9794) data->args.lastbytewritten,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9795) data->args.inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9797) if (!sync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9798) data->inode = nfs_igrab_and_active(data->args.inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9799) if (data->inode == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9800) nfs4_layoutcommit_release(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9801) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9803) task_setup_data.flags = RPC_TASK_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9805) nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9806) task = rpc_run_task(&task_setup_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9807) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9808) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9809) if (sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9810) status = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9811) trace_nfs4_layoutcommit(data->args.inode, &data->args.stateid, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9812) dprintk("%s: status %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9813) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9814) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9817) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9818) * Use the state managment nfs_client cl_rpcclient, which uses krb5i (if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9819) * possible) as per RFC3530bis and RFC5661 Security Considerations sections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9821) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9822) _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9823) struct nfs_fsinfo *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9824) struct nfs4_secinfo_flavors *flavors, bool use_integrity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9826) struct nfs41_secinfo_no_name_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9827) .style = SECINFO_STYLE_CURRENT_FH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9828) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9829) struct nfs4_secinfo_res res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9830) .flavors = flavors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9831) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9832) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9833) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SECINFO_NO_NAME],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9834) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9835) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9836) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9837) struct nfs4_call_sync_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9838) .seq_server = server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9839) .seq_args = &args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9840) .seq_res = &res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9842) struct rpc_task_setup task_setup = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9843) .rpc_client = server->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9844) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9845) .callback_ops = server->nfs_client->cl_mvops->call_sync_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9846) .callback_data = &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9847) .flags = RPC_TASK_NO_ROUND_ROBIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9848) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9849) const struct cred *cred = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9850) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9852) if (use_integrity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9853) task_setup.rpc_client = server->nfs_client->cl_rpcclient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9855) cred = nfs4_get_clid_cred(server->nfs_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9856) msg.rpc_cred = cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9859) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9860) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9861) status = nfs4_call_sync_custom(&task_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9862) dprintk("<-- %s status=%d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9864) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9866) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9869) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9870) nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9871) struct nfs_fsinfo *info, struct nfs4_secinfo_flavors *flavors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9873) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9874) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9876) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9877) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9878) /* first try using integrity protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9879) err = -NFS4ERR_WRONGSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9881) /* try to use integrity protection with machine cred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9882) if (_nfs4_is_integrity_protected(server->nfs_client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9883) err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9884) flavors, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9886) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9887) * if unable to use integrity protection, or SECINFO with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9888) * integrity protection returns NFS4ERR_WRONGSEC (which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9889) * disallowed by spec, but exists in deployed servers) use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9890) * the current filesystem's rpc_client and the user cred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9892) if (err == -NFS4ERR_WRONGSEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9893) err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9894) flavors, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9896) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9897) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9898) case -NFS4ERR_WRONGSEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9899) case -ENOTSUPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9900) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9901) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9902) err = nfs4_handle_exception(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9904) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9905) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9906) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9909) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9910) nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9911) struct nfs_fsinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9912) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9913) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9914) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9915) rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9916) struct nfs4_secinfo_flavors *flavors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9917) struct nfs4_secinfo4 *secinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9918) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9920) page = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9921) if (!page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9922) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9923) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9926) flavors = page_address(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9927) err = nfs41_proc_secinfo_no_name(server, fhandle, info, flavors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9930) * Fall back on "guess and check" method if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9931) * the server doesn't support SECINFO_NO_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9933) if (err == -NFS4ERR_WRONGSEC || err == -ENOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9934) err = nfs4_find_root_sec(server, fhandle, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9935) goto out_freepage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9937) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9938) goto out_freepage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9940) for (i = 0; i < flavors->num_flavors; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9941) secinfo = &flavors->flavors[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9943) switch (secinfo->flavor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9944) case RPC_AUTH_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9945) case RPC_AUTH_UNIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9946) case RPC_AUTH_GSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9947) flavor = rpcauth_get_pseudoflavor(secinfo->flavor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9948) &secinfo->flavor_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9950) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9951) flavor = RPC_AUTH_MAXFLAVOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9952) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9955) if (!nfs_auth_info_match(&server->auth_info, flavor))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9956) flavor = RPC_AUTH_MAXFLAVOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9958) if (flavor != RPC_AUTH_MAXFLAVOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9959) err = nfs4_lookup_root_sec(server, fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9960) info, flavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9961) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9962) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9966) if (flavor == RPC_AUTH_MAXFLAVOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9967) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9969) out_freepage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9970) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9971) if (err == -EACCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9972) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9973) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9974) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9977) static int _nfs41_test_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9978) nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9979) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9981) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9982) struct nfs41_test_stateid_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9983) .stateid = stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9984) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9985) struct nfs41_test_stateid_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9986) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9987) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_TEST_STATEID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9988) .rpc_argp = &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9989) .rpc_resp = &res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9990) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9991) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9992) struct rpc_clnt *rpc_client = server->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9994) nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9995) &rpc_client, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9997) dprintk("NFS call test_stateid %p\n", stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9998) nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9999) status = nfs4_call_sync_sequence(rpc_client, server, &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10000) &args.seq_args, &res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10001) if (status != NFS_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10002) dprintk("NFS reply test_stateid: failed, %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10003) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10005) dprintk("NFS reply test_stateid: succeeded, %d\n", -res.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10006) return -res.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10009) static void nfs4_handle_delay_or_session_error(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10010) int err, struct nfs4_exception *exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10012) exception->retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10013) switch(err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10014) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10015) case -NFS4ERR_RETRY_UNCACHED_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10016) nfs4_handle_exception(server, err, exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10017) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10018) case -NFS4ERR_BADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10019) case -NFS4ERR_BADSLOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10020) case -NFS4ERR_BAD_HIGH_SLOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10021) case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10022) case -NFS4ERR_DEADSESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10023) nfs4_do_handle_exception(server, err, exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10027) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10028) * nfs41_test_stateid - perform a TEST_STATEID operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10029) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10030) * @server: server / transport on which to perform the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10031) * @stateid: state ID to test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10032) * @cred: credential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10033) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10034) * Returns NFS_OK if the server recognizes that "stateid" is valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10035) * Otherwise a negative NFS4ERR value is returned if the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10036) * failed or the state ID is not currently valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10037) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10038) static int nfs41_test_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10039) nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10040) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10042) struct nfs4_exception exception = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10043) .interruptible = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10044) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10045) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10046) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10047) err = _nfs41_test_stateid(server, stateid, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10048) nfs4_handle_delay_or_session_error(server, err, &exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10049) } while (exception.retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10050) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10053) struct nfs_free_stateid_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10054) struct nfs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10055) struct nfs41_free_stateid_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10056) struct nfs41_free_stateid_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10057) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10059) static void nfs41_free_stateid_prepare(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10061) struct nfs_free_stateid_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10062) nfs4_setup_sequence(data->server->nfs_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10063) &data->args.seq_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10064) &data->res.seq_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10065) task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10068) static void nfs41_free_stateid_done(struct rpc_task *task, void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10070) struct nfs_free_stateid_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10072) nfs41_sequence_done(task, &data->res.seq_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10074) switch (task->tk_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10075) case -NFS4ERR_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10076) if (nfs4_async_handle_error(task, data->server, NULL, NULL) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10077) rpc_restart_call_prepare(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10081) static void nfs41_free_stateid_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10083) kfree(calldata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10086) static const struct rpc_call_ops nfs41_free_stateid_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10087) .rpc_call_prepare = nfs41_free_stateid_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10088) .rpc_call_done = nfs41_free_stateid_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10089) .rpc_release = nfs41_free_stateid_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10090) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10092) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10093) * nfs41_free_stateid - perform a FREE_STATEID operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10094) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10095) * @server: server / transport on which to perform the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10096) * @stateid: state ID to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10097) * @cred: credential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10098) * @privileged: set to true if this call needs to be privileged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10099) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10100) * Note: this function is always asynchronous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10102) static int nfs41_free_stateid(struct nfs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10103) const nfs4_stateid *stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10104) const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10105) bool privileged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10107) struct rpc_message msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10108) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FREE_STATEID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10109) .rpc_cred = cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10111) struct rpc_task_setup task_setup = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10112) .rpc_client = server->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10113) .rpc_message = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10114) .callback_ops = &nfs41_free_stateid_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10115) .flags = RPC_TASK_ASYNC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10117) struct nfs_free_stateid_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10118) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10120) nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10121) &task_setup.rpc_client, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10123) dprintk("NFS call free_stateid %p\n", stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10124) data = kmalloc(sizeof(*data), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10125) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10126) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10127) data->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10128) nfs4_stateid_copy(&data->args.stateid, stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10130) task_setup.callback_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10132) msg.rpc_argp = &data->args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10133) msg.rpc_resp = &data->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10134) nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, privileged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10135) task = rpc_run_task(&task_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10136) if (IS_ERR(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10137) return PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10138) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10142) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10143) nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10145) const struct cred *cred = lsp->ls_state->owner->so_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10147) nfs41_free_stateid(server, &lsp->ls_stateid, cred, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10148) nfs4_free_lock_state(server, lsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10151) static bool nfs41_match_stateid(const nfs4_stateid *s1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10152) const nfs4_stateid *s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10154) if (s1->type != s2->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10155) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10157) if (memcmp(s1->other, s2->other, sizeof(s1->other)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10158) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10160) if (s1->seqid == s2->seqid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10161) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10163) return s1->seqid == 0 || s2->seqid == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10166) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10168) static bool nfs4_match_stateid(const nfs4_stateid *s1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10169) const nfs4_stateid *s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10171) return nfs4_stateid_match(s1, s2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10175) static const struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10176) .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10177) .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10178) .recover_open = nfs4_open_reclaim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10179) .recover_lock = nfs4_lock_reclaim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10180) .establish_clid = nfs4_init_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10181) .detect_trunking = nfs40_discover_server_trunking,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10184) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10185) static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10186) .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10187) .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10188) .recover_open = nfs4_open_reclaim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10189) .recover_lock = nfs4_lock_reclaim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10190) .establish_clid = nfs41_init_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10191) .reclaim_complete = nfs41_proc_reclaim_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10192) .detect_trunking = nfs41_discover_server_trunking,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10194) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10196) static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10197) .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10198) .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10199) .recover_open = nfs40_open_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10200) .recover_lock = nfs4_lock_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10201) .establish_clid = nfs4_init_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10204) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10205) static const struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10206) .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10207) .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10208) .recover_open = nfs41_open_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10209) .recover_lock = nfs41_lock_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10210) .establish_clid = nfs41_init_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10212) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10214) static const struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10215) .sched_state_renewal = nfs4_proc_async_renew,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10216) .get_state_renewal_cred = nfs4_get_renew_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10217) .renew_lease = nfs4_proc_renew,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10220) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10221) static const struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10222) .sched_state_renewal = nfs41_proc_async_sequence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10223) .get_state_renewal_cred = nfs4_get_machine_cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10224) .renew_lease = nfs4_proc_sequence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10225) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10226) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10228) static const struct nfs4_mig_recovery_ops nfs40_mig_recovery_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10229) .get_locations = _nfs40_proc_get_locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10230) .fsid_present = _nfs40_proc_fsid_present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10233) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10234) static const struct nfs4_mig_recovery_ops nfs41_mig_recovery_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10235) .get_locations = _nfs41_proc_get_locations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10236) .fsid_present = _nfs41_proc_fsid_present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10238) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10240) static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10241) .minor_version = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10242) .init_caps = NFS_CAP_READDIRPLUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10243) | NFS_CAP_ATOMIC_OPEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10244) | NFS_CAP_POSIX_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10245) .init_client = nfs40_init_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10246) .shutdown_client = nfs40_shutdown_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10247) .match_stateid = nfs4_match_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10248) .find_root_sec = nfs4_find_root_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10249) .free_lock_state = nfs4_release_lockowner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10250) .test_and_free_expired = nfs40_test_and_free_expired_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10251) .alloc_seqid = nfs_alloc_seqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10252) .call_sync_ops = &nfs40_call_sync_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10253) .reboot_recovery_ops = &nfs40_reboot_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10254) .nograce_recovery_ops = &nfs40_nograce_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10255) .state_renewal_ops = &nfs40_state_renewal_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10256) .mig_recovery_ops = &nfs40_mig_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10259) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10260) static struct nfs_seqid *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10261) nfs_alloc_no_seqid(struct nfs_seqid_counter *arg1, gfp_t arg2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10263) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10266) static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10267) .minor_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10268) .init_caps = NFS_CAP_READDIRPLUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10269) | NFS_CAP_ATOMIC_OPEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10270) | NFS_CAP_POSIX_LOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10271) | NFS_CAP_STATEID_NFSV41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10272) | NFS_CAP_ATOMIC_OPEN_V1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10273) | NFS_CAP_LGOPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10274) .init_client = nfs41_init_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10275) .shutdown_client = nfs41_shutdown_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10276) .match_stateid = nfs41_match_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10277) .find_root_sec = nfs41_find_root_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10278) .free_lock_state = nfs41_free_lock_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10279) .test_and_free_expired = nfs41_test_and_free_expired_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10280) .alloc_seqid = nfs_alloc_no_seqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10281) .session_trunk = nfs4_test_session_trunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10282) .call_sync_ops = &nfs41_call_sync_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10283) .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10284) .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10285) .state_renewal_ops = &nfs41_state_renewal_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10286) .mig_recovery_ops = &nfs41_mig_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10288) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10290) #if defined(CONFIG_NFS_V4_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10291) static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10292) .minor_version = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10293) .init_caps = NFS_CAP_READDIRPLUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10294) | NFS_CAP_ATOMIC_OPEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10295) | NFS_CAP_POSIX_LOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10296) | NFS_CAP_STATEID_NFSV41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10297) | NFS_CAP_ATOMIC_OPEN_V1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10298) | NFS_CAP_LGOPEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10299) | NFS_CAP_ALLOCATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10300) | NFS_CAP_COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10301) | NFS_CAP_OFFLOAD_CANCEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10302) | NFS_CAP_COPY_NOTIFY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10303) | NFS_CAP_DEALLOCATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10304) | NFS_CAP_SEEK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10305) | NFS_CAP_LAYOUTSTATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10306) | NFS_CAP_CLONE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10307) | NFS_CAP_LAYOUTERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10308) | NFS_CAP_READ_PLUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10309) .init_client = nfs41_init_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10310) .shutdown_client = nfs41_shutdown_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10311) .match_stateid = nfs41_match_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10312) .find_root_sec = nfs41_find_root_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10313) .free_lock_state = nfs41_free_lock_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10314) .call_sync_ops = &nfs41_call_sync_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10315) .test_and_free_expired = nfs41_test_and_free_expired_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10316) .alloc_seqid = nfs_alloc_no_seqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10317) .session_trunk = nfs4_test_session_trunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10318) .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10319) .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10320) .state_renewal_ops = &nfs41_state_renewal_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10321) .mig_recovery_ops = &nfs41_mig_recovery_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10323) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10325) const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10326) [0] = &nfs_v4_0_minor_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10327) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10328) [1] = &nfs_v4_1_minor_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10329) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10330) #if defined(CONFIG_NFS_V4_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10331) [2] = &nfs_v4_2_minor_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10332) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10335) static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10337) ssize_t error, error2, error3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10339) error = generic_listxattr(dentry, list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10340) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10341) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10342) if (list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10343) list += error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10344) size -= error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10347) error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10348) if (error2 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10349) return error2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10351) if (list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10352) list += error2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10353) size -= error2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10356) error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10357) if (error3 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10358) return error3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10360) return error + error2 + error3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10363) static const struct inode_operations nfs4_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10364) .create = nfs_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10365) .lookup = nfs_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10366) .atomic_open = nfs_atomic_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10367) .link = nfs_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10368) .unlink = nfs_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10369) .symlink = nfs_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10370) .mkdir = nfs_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10371) .rmdir = nfs_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10372) .mknod = nfs_mknod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10373) .rename = nfs_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10374) .permission = nfs_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10375) .getattr = nfs_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10376) .setattr = nfs_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10377) .listxattr = nfs4_listxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10380) static const struct inode_operations nfs4_file_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10381) .permission = nfs_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10382) .getattr = nfs_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10383) .setattr = nfs_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10384) .listxattr = nfs4_listxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10385) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10387) const struct nfs_rpc_ops nfs_v4_clientops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10388) .version = 4, /* protocol version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10389) .dentry_ops = &nfs4_dentry_operations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10390) .dir_inode_ops = &nfs4_dir_inode_operations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10391) .file_inode_ops = &nfs4_file_inode_operations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10392) .file_ops = &nfs4_file_operations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10393) .getroot = nfs4_proc_get_root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10394) .submount = nfs4_submount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10395) .try_get_tree = nfs4_try_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10396) .getattr = nfs4_proc_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10397) .setattr = nfs4_proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10398) .lookup = nfs4_proc_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10399) .lookupp = nfs4_proc_lookupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10400) .access = nfs4_proc_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10401) .readlink = nfs4_proc_readlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10402) .create = nfs4_proc_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10403) .remove = nfs4_proc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10404) .unlink_setup = nfs4_proc_unlink_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10405) .unlink_rpc_prepare = nfs4_proc_unlink_rpc_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10406) .unlink_done = nfs4_proc_unlink_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10407) .rename_setup = nfs4_proc_rename_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10408) .rename_rpc_prepare = nfs4_proc_rename_rpc_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10409) .rename_done = nfs4_proc_rename_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10410) .link = nfs4_proc_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10411) .symlink = nfs4_proc_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10412) .mkdir = nfs4_proc_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10413) .rmdir = nfs4_proc_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10414) .readdir = nfs4_proc_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10415) .mknod = nfs4_proc_mknod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10416) .statfs = nfs4_proc_statfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10417) .fsinfo = nfs4_proc_fsinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10418) .pathconf = nfs4_proc_pathconf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10419) .set_capabilities = nfs4_server_capabilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10420) .decode_dirent = nfs4_decode_dirent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10421) .pgio_rpc_prepare = nfs4_proc_pgio_rpc_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10422) .read_setup = nfs4_proc_read_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10423) .read_done = nfs4_read_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10424) .write_setup = nfs4_proc_write_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10425) .write_done = nfs4_write_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10426) .commit_setup = nfs4_proc_commit_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10427) .commit_rpc_prepare = nfs4_proc_commit_rpc_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10428) .commit_done = nfs4_commit_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10429) .lock = nfs4_proc_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10430) .clear_acl_cache = nfs4_zap_acl_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10431) .close_context = nfs4_close_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10432) .open_context = nfs4_atomic_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10433) .have_delegation = nfs4_have_delegation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10434) .alloc_client = nfs4_alloc_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10435) .init_client = nfs4_init_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10436) .free_client = nfs4_free_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10437) .create_server = nfs4_create_server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10438) .clone_server = nfs_clone_server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10441) static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10442) .name = XATTR_NAME_NFSV4_ACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10443) .list = nfs4_xattr_list_nfs4_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10444) .get = nfs4_xattr_get_nfs4_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10445) .set = nfs4_xattr_set_nfs4_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10448) #ifdef CONFIG_NFS_V4_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10449) static const struct xattr_handler nfs4_xattr_nfs4_user_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10450) .prefix = XATTR_USER_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10451) .get = nfs4_xattr_get_nfs4_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10452) .set = nfs4_xattr_set_nfs4_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10454) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10456) const struct xattr_handler *nfs4_xattr_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10457) &nfs4_xattr_nfs4_acl_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10458) #ifdef CONFIG_NFS_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10459) &nfs4_xattr_nfs4_label_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10460) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10461) #ifdef CONFIG_NFS_V4_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10462) &nfs4_xattr_nfs4_user_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10463) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10464) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10465) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10467) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10468) * Local variables:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10469) * c-basic-offset: 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10470) * End:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10471) */