Blame view
fs/nfsd/nfsfh.h
7.49 KB
b24413180 License cleanup: ... |
1 |
/* SPDX-License-Identifier: GPL-2.0 */ |
9c69de4c9 nfsd: remove <lin... |
2 3 4 5 6 7 8 9 |
/* * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> * * This file describes the layout of the file handles as passed * over the wire. */ #ifndef _LINUX_NFSD_NFSFH_H #define _LINUX_NFSD_NFSFH_H |
6e8b50d16 nfsd: add new io ... |
10 |
#include <linux/crc32.h> |
9c69de4c9 nfsd: remove <lin... |
11 12 |
#include <linux/sunrpc/svc.h> #include <uapi/linux/nfsd/nfsfh.h> |
1f15a550f nfsd: convert to ... |
13 |
#include <linux/iversion.h> |
9c69de4c9 nfsd: remove <lin... |
14 15 16 17 18 19 20 21 22 23 |
static inline __u32 ino_t_to_u32(ino_t ino) { return (__u32) ino; } static inline ino_t u32_to_ino_t(__u32 uino) { return (ino_t) uino; } |
1557aca79 nfsd: move most o... |
24 |
|
9c69de4c9 nfsd: remove <lin... |
25 26 27 28 29 30 |
/* * This is the internal representation of an NFS handle used in knfsd. * pre_mtime/post_version will be used to support wcc_attr's in NFSv3. */ typedef struct svc_fh { struct knfsd_fh fh_handle; /* FH data */ |
fcaba026a nfsd: move svc_fh... |
31 |
int fh_maxsize; /* max size for fh_handle */ |
9c69de4c9 nfsd: remove <lin... |
32 33 |
struct dentry * fh_dentry; /* validated dentry */ struct svc_export * fh_export; /* export pointer */ |
9c69de4c9 nfsd: remove <lin... |
34 |
|
aaf91ec14 nfsd: switch unsi... |
35 36 |
bool fh_locked; /* inode locked by us */ bool fh_want_write; /* remount protection taken */ |
9c69de4c9 nfsd: remove <lin... |
37 38 |
#ifdef CONFIG_NFSD_V3 |
aaf91ec14 nfsd: switch unsi... |
39 40 |
bool fh_post_saved; /* post-op attrs saved */ bool fh_pre_saved; /* pre-op attrs saved */ |
9c69de4c9 nfsd: remove <lin... |
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
/* Pre-op attributes saved during fh_lock */ __u64 fh_pre_size; /* size before operation */ struct timespec fh_pre_mtime; /* mtime before oper */ struct timespec fh_pre_ctime; /* ctime before oper */ /* * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode) * to find out if it is valid. */ u64 fh_pre_change; /* Post-op attributes saved in fh_unlock */ struct kstat fh_post_attr; /* full attrs after operation */ u64 fh_post_change; /* nfsv4 change; see above */ #endif /* CONFIG_NFSD_V3 */ |
1557aca79 nfsd: move most o... |
56 |
|
9c69de4c9 nfsd: remove <lin... |
57 |
} svc_fh; |
1557aca79 nfsd: move most o... |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
enum nfsd_fsid { FSID_DEV = 0, FSID_NUM, FSID_MAJOR_MINOR, FSID_ENCODE_DEV, FSID_UUID4_INUM, FSID_UUID8, FSID_UUID16, FSID_UUID16_INUM, }; enum fsid_source { FSIDSOURCE_DEV, FSIDSOURCE_FSID, FSIDSOURCE_UUID, }; extern enum fsid_source fsid_source(struct svc_fh *fhp); |
94ec938b6 nfsd: add appropr... |
76 77 |
/* * This might look a little large to "inline" but in all calls except |
1557aca79 nfsd: move most o... |
78 |
* one, 'vers' is constant so moste of the function disappears. |
94ec938b6 nfsd: add appropr... |
79 80 81 82 83 84 |
* * In some cases the values are considered to be host endian and in * others, net endian. fsidv is always considered to be u32 as the * callers don't know which it will be. So we must use __force to keep * sparse from complaining. Since these values are opaque to the * client, that shouldn't be a problem. |
1557aca79 nfsd: move most o... |
85 86 87 88 89 90 91 |
*/ static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino, u32 fsid, unsigned char *uuid) { u32 *up; switch(vers) { case FSID_DEV: |
94ec938b6 nfsd: add appropr... |
92 |
fsidv[0] = (__force __u32)htonl((MAJOR(dev)<<16) | |
1557aca79 nfsd: move most o... |
93 94 95 96 97 98 99 |
MINOR(dev)); fsidv[1] = ino_t_to_u32(ino); break; case FSID_NUM: fsidv[0] = fsid; break; case FSID_MAJOR_MINOR: |
94ec938b6 nfsd: add appropr... |
100 101 |
fsidv[0] = (__force __u32)htonl(MAJOR(dev)); fsidv[1] = (__force __u32)htonl(MINOR(dev)); |
1557aca79 nfsd: move most o... |
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
fsidv[2] = ino_t_to_u32(ino); break; case FSID_ENCODE_DEV: fsidv[0] = new_encode_dev(dev); fsidv[1] = ino_t_to_u32(ino); break; case FSID_UUID4_INUM: /* 4 byte fsid and inode number */ up = (u32*)uuid; fsidv[0] = ino_t_to_u32(ino); fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3]; break; case FSID_UUID8: /* 8 byte fsid */ up = (u32*)uuid; fsidv[0] = up[0] ^ up[2]; fsidv[1] = up[1] ^ up[3]; break; case FSID_UUID16: /* 16 byte fsid - NFSv3+ only */ memcpy(fsidv, uuid, 16); break; case FSID_UUID16_INUM: /* 8 byte inode and 16 byte fsid */ *(u64*)fsidv = (u64)ino; memcpy(fsidv+2, uuid, 16); break; default: BUG(); } } static inline int key_len(int type) { switch(type) { case FSID_DEV: return 8; case FSID_NUM: return 4; case FSID_MAJOR_MINOR: return 12; case FSID_ENCODE_DEV: return 8; case FSID_UUID4_INUM: return 8; case FSID_UUID8: return 8; case FSID_UUID16: return 16; case FSID_UUID16_INUM: return 24; default: return 0; } } /* * Shorthand for dprintk()'s */ extern char * SVCFH_fmt(struct svc_fh *fhp); /* * Function prototypes */ |
175a4eb7e fs: propagate umo... |
161 |
__be32 fh_verify(struct svc_rqst *, struct svc_fh *, umode_t, int); |
1557aca79 nfsd: move most o... |
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
__be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *); __be32 fh_update(struct svc_fh *); void fh_put(struct svc_fh *); static __inline__ struct svc_fh * fh_copy(struct svc_fh *dst, struct svc_fh *src) { WARN_ON(src->fh_dentry || src->fh_locked); *dst = *src; return dst; } static inline void fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src) { dst->fh_size = src->fh_size; memcpy(&dst->fh_base, &src->fh_base, src->fh_size); } static __inline__ struct svc_fh * fh_init(struct svc_fh *fhp, int maxsize) { memset(fhp, 0, sizeof(*fhp)); fhp->fh_maxsize = maxsize; return fhp; } |
4d94c2ef2 nfsd: move nfsd_f... |
189 190 191 192 193 194 195 196 |
static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) { if (fh1->fh_size != fh2->fh_size) return false; if (memcmp(fh1->fh_base.fh_pad, fh2->fh_base.fh_pad, fh1->fh_size) != 0) return false; return true; } |
9558f2500 nfsd: add fh_fsid... |
197 198 199 200 |
static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) { if (fh1->fh_fsid_type != fh2->fh_fsid_type) return false; |
0ab39de6b nfsd: fix compari... |
201 |
if (memcmp(fh1->fh_fsid, fh2->fh_fsid, key_len(fh1->fh_fsid_type)) != 0) |
9558f2500 nfsd: add fh_fsid... |
202 203 204 |
return false; return true; } |
6e8b50d16 nfsd: add new io ... |
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
#ifdef CONFIG_CRC32 /** * knfsd_fh_hash - calculate the crc32 hash for the filehandle * @fh - pointer to filehandle * * returns a crc32 hash for the filehandle that is compatible with * the one displayed by "wireshark". */ static inline u32 knfsd_fh_hash(struct knfsd_fh *fh) { return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size); } #else static inline u32 knfsd_fh_hash(struct knfsd_fh *fh) { return 0; } #endif |
1557aca79 nfsd: move most o... |
226 227 |
#ifdef CONFIG_NFSD_V3 /* |
2336745e8 NFSD: Clear wcc d... |
228 229 230 231 232 233 |
* The wcc data stored in current_fh should be cleared * between compound ops. */ static inline void fh_clear_wcc(struct svc_fh *fhp) { |
aaf91ec14 nfsd: switch unsi... |
234 235 |
fhp->fh_post_saved = false; fhp->fh_pre_saved = false; |
2336745e8 NFSD: Clear wcc d... |
236 237 238 |
} /* |
630458e73 nfsd4: factor cti... |
239 240 241 242 243 244 245 246 247 248 |
* We could use i_version alone as the change attribute. However, * i_version can go backwards after a reboot. On its own that doesn't * necessarily cause a problem, but if i_version goes backwards and then * is incremented again it could reuse a value that was previously used * before boot, and a client who queried the two values might * incorrectly assume nothing changed. * * By using both ctime and the i_version counter we guarantee that as * long as time doesn't go backwards we never reuse an old value. */ |
39ca1bf62 nfsd: store stat ... |
249 250 |
static inline u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode) |
630458e73 nfsd4: factor cti... |
251 252 |
{ u64 chattr; |
39ca1bf62 nfsd: store stat ... |
253 |
chattr = stat->ctime.tv_sec; |
630458e73 nfsd4: factor cti... |
254 |
chattr <<= 30; |
39ca1bf62 nfsd: store stat ... |
255 |
chattr += stat->ctime.tv_nsec; |
1f15a550f nfsd: convert to ... |
256 |
chattr += inode_query_iversion(inode); |
630458e73 nfsd4: factor cti... |
257 258 |
return chattr; } |
39ca1bf62 nfsd: store stat ... |
259 260 |
extern void fill_pre_wcc(struct svc_fh *fhp); extern void fill_post_wcc(struct svc_fh *fhp); |
1557aca79 nfsd: move most o... |
261 |
#else |
2336745e8 NFSD: Clear wcc d... |
262 263 |
#define fh_clear_wcc(ignored) #define fill_pre_wcc(ignored) |
1557aca79 nfsd: move most o... |
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
#define fill_post_wcc(notused) #endif /* CONFIG_NFSD_V3 */ /* * Lock a file handle/inode * NOTE: both fh_lock and fh_unlock are done "by hand" in * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once * so, any changes here should be reflected there. */ static inline void fh_lock_nested(struct svc_fh *fhp, unsigned int subclass) { struct dentry *dentry = fhp->fh_dentry; struct inode *inode; BUG_ON(!dentry); if (fhp->fh_locked) { |
a6a9f18f0 nfsd: switch to %... |
284 285 286 |
printk(KERN_WARNING "fh_lock: %pd2 already locked! ", dentry); |
1557aca79 nfsd: move most o... |
287 288 |
return; } |
2b0143b5c VFS: normal files... |
289 |
inode = d_inode(dentry); |
5955102c9 wrappers for ->i_... |
290 |
inode_lock_nested(inode, subclass); |
1557aca79 nfsd: move most o... |
291 |
fill_pre_wcc(fhp); |
aaf91ec14 nfsd: switch unsi... |
292 |
fhp->fh_locked = true; |
1557aca79 nfsd: move most o... |
293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
} static inline void fh_lock(struct svc_fh *fhp) { fh_lock_nested(fhp, I_MUTEX_NORMAL); } /* * Unlock a file handle/inode */ static inline void fh_unlock(struct svc_fh *fhp) { |
1557aca79 nfsd: move most o... |
307 308 |
if (fhp->fh_locked) { fill_post_wcc(fhp); |
5955102c9 wrappers for ->i_... |
309 |
inode_unlock(d_inode(fhp->fh_dentry)); |
aaf91ec14 nfsd: switch unsi... |
310 |
fhp->fh_locked = false; |
1557aca79 nfsd: move most o... |
311 312 |
} } |
9c69de4c9 nfsd: remove <lin... |
313 |
#endif /* _LINUX_NFSD_NFSFH_H */ |