b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) /* SPDX-License-Identifier: GPL-2.0 */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 2) /*
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 3) * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 4) *
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 5) * This file describes the layout of the file handles as passed
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 6) * over the wire.
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 7) */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 8) #ifndef _LINUX_NFSD_NFSFH_H
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 9) #define _LINUX_NFSD_NFSFH_H
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 10)
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 11) #include <linux/crc32.h>
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 12) #include <linux/sunrpc/svc.h>
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 13) #include <uapi/linux/nfsd/nfsfh.h>
1f15a550f5f3e (Jeff Layton 2017-12-11 06:35:16 -0500 14) #include <linux/iversion.h>
3cc55f4434b42 (J. Bruce Fields 2021-01-29 14:26:29 -0500 15) #include <linux/exportfs.h>
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 16)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 17) static inline __u32 ino_t_to_u32(ino_t ino)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 18) {
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 19) return (__u32) ino;
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 20) }
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 21)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 22) static inline ino_t u32_to_ino_t(__u32 uino)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 23) {
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 24) return (ino_t) uino;
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 25) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 26)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 27) /*
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 28) * This is the internal representation of an NFS handle used in knfsd.
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 29) * pre_mtime/post_version will be used to support wcc_attr's in NFSv3.
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 30) */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 31) typedef struct svc_fh {
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 32) struct knfsd_fh fh_handle; /* FH data */
fcaba026a5580 (Jeff Layton 2015-09-17 08:28:38 -0400 33) int fh_maxsize; /* max size for fh_handle */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 34) struct dentry * fh_dentry; /* validated dentry */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 35) struct svc_export * fh_export; /* export pointer */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 36)
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 37) bool fh_locked; /* inode locked by us */
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 38) bool fh_want_write; /* remount protection taken */
daab110e47f8d (Jeff Layton 2020-11-30 17:03:14 -0500 39) bool fh_no_wcc; /* no wcc data needed */
716a8bc7f706e (Trond Myklebust 2020-11-30 23:14:27 -0500 40) bool fh_no_atomic_attr;
716a8bc7f706e (Trond Myklebust 2020-11-30 23:14:27 -0500 41) /*
716a8bc7f706e (Trond Myklebust 2020-11-30 23:14:27 -0500 42) * wcc data is not atomic with
716a8bc7f706e (Trond Myklebust 2020-11-30 23:14:27 -0500 43) * operation
716a8bc7f706e (Trond Myklebust 2020-11-30 23:14:27 -0500 44) */
b9e8638e3d9ed (Olga Kornievskaia 2019-10-07 10:56:48 -0400 45) int fh_flags; /* FH flags */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 46) #ifdef CONFIG_NFSD_V3
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 47) bool fh_post_saved; /* post-op attrs saved */
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 48) bool fh_pre_saved; /* pre-op attrs saved */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 49)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 50) /* Pre-op attributes saved during fh_lock */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 51) __u64 fh_pre_size; /* size before operation */
92c5e46911c0c (Arnd Bergmann 2019-10-31 14:55:32 +0100 52) struct timespec64 fh_pre_mtime; /* mtime before oper */
92c5e46911c0c (Arnd Bergmann 2019-10-31 14:55:32 +0100 53) struct timespec64 fh_pre_ctime; /* ctime before oper */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 54) /*
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 55) * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 56) * to find out if it is valid.
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 57) */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 58) u64 fh_pre_change;
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 59)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 60) /* Post-op attributes saved in fh_unlock */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 61) struct kstat fh_post_attr; /* full attrs after operation */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 62) u64 fh_post_change; /* nfsv4 change; see above */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 63) #endif /* CONFIG_NFSD_V3 */
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 64) } svc_fh;
b9e8638e3d9ed (Olga Kornievskaia 2019-10-07 10:56:48 -0400 65) #define NFSD4_FH_FOREIGN (1<<0)
b9e8638e3d9ed (Olga Kornievskaia 2019-10-07 10:56:48 -0400 66) #define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f))
b9e8638e3d9ed (Olga Kornievskaia 2019-10-07 10:56:48 -0400 67) #define HAS_FH_FLAG(c, f) ((c)->fh_flags & (f))
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 68)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 69) enum nfsd_fsid {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 70) FSID_DEV = 0,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 71) FSID_NUM,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 72) FSID_MAJOR_MINOR,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 73) FSID_ENCODE_DEV,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 74) FSID_UUID4_INUM,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 75) FSID_UUID8,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 76) FSID_UUID16,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 77) FSID_UUID16_INUM,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 78) };
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 79)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 80) enum fsid_source {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 81) FSIDSOURCE_DEV,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 82) FSIDSOURCE_FSID,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 83) FSIDSOURCE_UUID,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 84) };
2c42f804d30f6 (Chuck Lever 2020-10-21 11:58:41 -0400 85) extern enum fsid_source fsid_source(const struct svc_fh *fhp);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 86)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 87)
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 88) /*
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 89) * This might look a little large to "inline" but in all calls except
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 90) * one, 'vers' is constant so moste of the function disappears.
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 91) *
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 92) * In some cases the values are considered to be host endian and in
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 93) * others, net endian. fsidv is always considered to be u32 as the
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 94) * callers don't know which it will be. So we must use __force to keep
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 95) * sparse from complaining. Since these values are opaque to the
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 96) * client, that shouldn't be a problem.
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 97) */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 98) static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 99) u32 fsid, unsigned char *uuid)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 100) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 101) u32 *up;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 102) switch(vers) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 103) case FSID_DEV:
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 104) fsidv[0] = (__force __u32)htonl((MAJOR(dev)<<16) |
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 105) MINOR(dev));
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 106) fsidv[1] = ino_t_to_u32(ino);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 107) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 108) case FSID_NUM:
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 109) fsidv[0] = fsid;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 110) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 111) case FSID_MAJOR_MINOR:
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 112) fsidv[0] = (__force __u32)htonl(MAJOR(dev));
94ec938b612eb (Jeff Layton 2014-06-17 07:44:14 -0400 113) fsidv[1] = (__force __u32)htonl(MINOR(dev));
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 114) fsidv[2] = ino_t_to_u32(ino);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 115) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 116)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 117) case FSID_ENCODE_DEV:
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 118) fsidv[0] = new_encode_dev(dev);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 119) fsidv[1] = ino_t_to_u32(ino);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 120) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 121)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 122) case FSID_UUID4_INUM:
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 123) /* 4 byte fsid and inode number */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 124) up = (u32*)uuid;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 125) fsidv[0] = ino_t_to_u32(ino);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 126) fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 127) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 128)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 129) case FSID_UUID8:
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 130) /* 8 byte fsid */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 131) up = (u32*)uuid;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 132) fsidv[0] = up[0] ^ up[2];
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 133) fsidv[1] = up[1] ^ up[3];
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 134) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 135)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 136) case FSID_UUID16:
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 137) /* 16 byte fsid - NFSv3+ only */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 138) memcpy(fsidv, uuid, 16);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 139) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 140)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 141) case FSID_UUID16_INUM:
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 142) /* 8 byte inode and 16 byte fsid */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 143) *(u64*)fsidv = (u64)ino;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 144) memcpy(fsidv+2, uuid, 16);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 145) break;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 146) default: BUG();
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 147) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 148) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 149)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 150) static inline int key_len(int type)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 151) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 152) switch(type) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 153) case FSID_DEV: return 8;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 154) case FSID_NUM: return 4;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 155) case FSID_MAJOR_MINOR: return 12;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 156) case FSID_ENCODE_DEV: return 8;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 157) case FSID_UUID4_INUM: return 8;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 158) case FSID_UUID8: return 8;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 159) case FSID_UUID16: return 16;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 160) case FSID_UUID16_INUM: return 24;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 161) default: return 0;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 162) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 163) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 164)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 165) /*
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 166) * Shorthand for dprintk()'s
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 167) */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 168) extern char * SVCFH_fmt(struct svc_fh *fhp);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 169)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 170) /*
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 171) * Function prototypes
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 172) */
175a4eb7ea531 (Al Viro 2011-07-26 03:30:54 -0400 173) __be32 fh_verify(struct svc_rqst *, struct svc_fh *, umode_t, int);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 174) __be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 175) __be32 fh_update(struct svc_fh *);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 176) void fh_put(struct svc_fh *);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 177)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 178) static __inline__ struct svc_fh *
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 179) fh_copy(struct svc_fh *dst, struct svc_fh *src)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 180) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 181) WARN_ON(src->fh_dentry || src->fh_locked);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 182)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 183) *dst = *src;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 184) return dst;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 185) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 186)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 187) static inline void
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 188) fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 189) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 190) dst->fh_size = src->fh_size;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 191) memcpy(&dst->fh_base, &src->fh_base, src->fh_size);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 192) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 193)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 194) static __inline__ struct svc_fh *
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 195) fh_init(struct svc_fh *fhp, int maxsize)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 196) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 197) memset(fhp, 0, sizeof(*fhp));
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 198) fhp->fh_maxsize = maxsize;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 199) return fhp;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 200) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 201)
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 202) static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 203) {
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 204) if (fh1->fh_size != fh2->fh_size)
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 205) return false;
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 206) if (memcmp(fh1->fh_base.fh_pad, fh2->fh_base.fh_pad, fh1->fh_size) != 0)
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 207) return false;
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 208) return true;
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 209) }
4d94c2ef2008a (Christoph Hellwig 2014-08-14 08:41:48 +0200 210)
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 211) static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 212) {
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 213) if (fh1->fh_fsid_type != fh2->fh_fsid_type)
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 214) return false;
0ab39de6b3411 (Dan Carpenter 2015-02-11 16:08:32 +0300 215) if (memcmp(fh1->fh_fsid, fh2->fh_fsid, key_len(fh1->fh_fsid_type)) != 0)
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 216) return false;
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 217) return true;
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 218) }
9558f2500a202 (Christoph Hellwig 2014-08-13 20:56:13 +0200 219)
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 220) #ifdef CONFIG_CRC32
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 221) /**
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 222) * knfsd_fh_hash - calculate the crc32 hash for the filehandle
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 223) * @fh - pointer to filehandle
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 224) *
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 225) * returns a crc32 hash for the filehandle that is compatible with
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 226) * the one displayed by "wireshark".
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 227) */
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 228)
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 229) static inline u32
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 230) knfsd_fh_hash(struct knfsd_fh *fh)
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 231) {
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 232) return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size);
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 233) }
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 234) #else
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 235) static inline u32
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 236) knfsd_fh_hash(struct knfsd_fh *fh)
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 237) {
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 238) return 0;
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 239) }
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 240) #endif
6e8b50d16a757 (Jeff Layton 2015-11-17 06:52:23 -0500 241)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 242) #ifdef CONFIG_NFSD_V3
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 243) /*
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 244) * The wcc data stored in current_fh should be cleared
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 245) * between compound ops.
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 246) */
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 247) static inline void
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 248) fh_clear_wcc(struct svc_fh *fhp)
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 249) {
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 250) fhp->fh_post_saved = false;
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 251) fhp->fh_pre_saved = false;
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 252) }
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 253)
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 254) /*
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 255) * We could use i_version alone as the change attribute. However,
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 256) * i_version can go backwards after a reboot. On its own that doesn't
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 257) * necessarily cause a problem, but if i_version goes backwards and then
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 258) * is incremented again it could reuse a value that was previously used
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 259) * before boot, and a client who queried the two values might
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 260) * incorrectly assume nothing changed.
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 261) *
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 262) * By using both ctime and the i_version counter we guarantee that as
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 263) * long as time doesn't go backwards we never reuse an old value.
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 264) */
39ca1bf624b6b (Amir Goldstein 2018-01-03 17:14:35 +0200 265) static inline u64 nfsd4_change_attribute(struct kstat *stat,
39ca1bf624b6b (Amir Goldstein 2018-01-03 17:14:35 +0200 266) struct inode *inode)
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 267) {
3cc55f4434b42 (J. Bruce Fields 2021-01-29 14:26:29 -0500 268) if (inode->i_sb->s_export_op->fetch_iversion)
3cc55f4434b42 (J. Bruce Fields 2021-01-29 14:26:29 -0500 269) return inode->i_sb->s_export_op->fetch_iversion(inode);
3cc55f4434b42 (J. Bruce Fields 2021-01-29 14:26:29 -0500 270) else if (IS_I_VERSION(inode)) {
4b03d99794eee (J. Bruce Fields 2020-11-30 17:46:16 -0500 271) u64 chattr;
4b03d99794eee (J. Bruce Fields 2020-11-30 17:46:16 -0500 272)
70b87f77294d1 (J. Bruce Fields 2020-11-30 17:46:14 -0500 273) chattr = stat->ctime.tv_sec;
70b87f77294d1 (J. Bruce Fields 2020-11-30 17:46:14 -0500 274) chattr <<= 30;
70b87f77294d1 (J. Bruce Fields 2020-11-30 17:46:14 -0500 275) chattr += stat->ctime.tv_nsec;
70b87f77294d1 (J. Bruce Fields 2020-11-30 17:46:14 -0500 276) chattr += inode_query_iversion(inode);
4b03d99794eee (J. Bruce Fields 2020-11-30 17:46:16 -0500 277) return chattr;
4b03d99794eee (J. Bruce Fields 2020-11-30 17:46:16 -0500 278) } else
4b03d99794eee (J. Bruce Fields 2020-11-30 17:46:16 -0500 279) return time_to_chattr(&stat->ctime);
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 280) }
630458e730b82 (J. Bruce Fields 2017-05-11 14:45:06 -0400 281)
39ca1bf624b6b (Amir Goldstein 2018-01-03 17:14:35 +0200 282) extern void fill_pre_wcc(struct svc_fh *fhp);
39ca1bf624b6b (Amir Goldstein 2018-01-03 17:14:35 +0200 283) extern void fill_post_wcc(struct svc_fh *fhp);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 284) #else
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 285) #define fh_clear_wcc(ignored)
2336745e87a64 (Kinglong Mee 2014-03-29 10:23:47 +0800 286) #define fill_pre_wcc(ignored)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 287) #define fill_post_wcc(notused)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 288) #endif /* CONFIG_NFSD_V3 */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 289)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 290)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 291) /*
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 292) * Lock a file handle/inode
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 293) * NOTE: both fh_lock and fh_unlock are done "by hand" in
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 294) * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 295) * so, any changes here should be reflected there.
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 296) */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 297)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 298) static inline void
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 299) fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 300) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 301) struct dentry *dentry = fhp->fh_dentry;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 302) struct inode *inode;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 303)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 304) BUG_ON(!dentry);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 305)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 306) if (fhp->fh_locked) {
a6a9f18f0a9f9 (Al Viro 2013-09-16 10:57:01 -0400 307) printk(KERN_WARNING "fh_lock: %pd2 already locked!\n",
a6a9f18f0a9f9 (Al Viro 2013-09-16 10:57:01 -0400 308) dentry);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 309) return;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 310) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 311)
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 312) inode = d_inode(dentry);
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 313) inode_lock_nested(inode, subclass);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 314) fill_pre_wcc(fhp);
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 315) fhp->fh_locked = true;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 316) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 317)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 318) static inline void
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 319) fh_lock(struct svc_fh *fhp)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 320) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 321) fh_lock_nested(fhp, I_MUTEX_NORMAL);
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 322) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 323)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 324) /*
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 325) * Unlock a file handle/inode
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 326) */
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 327) static inline void
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 328) fh_unlock(struct svc_fh *fhp)
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 329) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 330) if (fhp->fh_locked) {
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 331) fill_post_wcc(fhp);
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 332) inode_unlock(d_inode(fhp->fh_dentry));
aaf91ec148910 (Jeff Layton 2015-09-17 08:28:39 -0400 333) fhp->fh_locked = false;
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 334) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 335) }
1557aca7904ed (J. Bruce Fields 2009-12-04 19:36:06 -0500 336)
9c69de4c94fcb (Christoph Hellwig 2014-05-06 19:37:13 +0200 337) #endif /* _LINUX_NFSD_NFSFH_H */