0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _LINUX_NFSD_NFSFH_H
0009 #define _LINUX_NFSD_NFSFH_H
0010
0011 #include <linux/crc32.h>
0012 #include <linux/sunrpc/svc.h>
0013 #include <linux/iversion.h>
0014 #include <linux/exportfs.h>
0015 #include <linux/nfs4.h>
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 struct knfsd_fh {
0048 unsigned int fh_size;
0049
0050
0051
0052 union {
0053 char fh_raw[NFS4_FHSIZE];
0054 struct {
0055 u8 fh_version;
0056 u8 fh_auth_type;
0057 u8 fh_fsid_type;
0058 u8 fh_fileid_type;
0059 u32 fh_fsid[];
0060 };
0061 };
0062 };
0063
0064 static inline __u32 ino_t_to_u32(ino_t ino)
0065 {
0066 return (__u32) ino;
0067 }
0068
0069 static inline ino_t u32_to_ino_t(__u32 uino)
0070 {
0071 return (ino_t) uino;
0072 }
0073
0074
0075
0076
0077
0078 typedef struct svc_fh {
0079 struct knfsd_fh fh_handle;
0080 int fh_maxsize;
0081 struct dentry * fh_dentry;
0082 struct svc_export * fh_export;
0083
0084 bool fh_want_write;
0085 bool fh_no_wcc;
0086 bool fh_no_atomic_attr;
0087
0088
0089
0090
0091 int fh_flags;
0092 bool fh_post_saved;
0093 bool fh_pre_saved;
0094
0095
0096 __u64 fh_pre_size;
0097 struct timespec64 fh_pre_mtime;
0098 struct timespec64 fh_pre_ctime;
0099
0100
0101
0102
0103 u64 fh_pre_change;
0104
0105
0106 struct kstat fh_post_attr;
0107 u64 fh_post_change;
0108 } svc_fh;
0109 #define NFSD4_FH_FOREIGN (1<<0)
0110 #define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f))
0111 #define HAS_FH_FLAG(c, f) ((c)->fh_flags & (f))
0112
0113 enum nfsd_fsid {
0114 FSID_DEV = 0,
0115 FSID_NUM,
0116 FSID_MAJOR_MINOR,
0117 FSID_ENCODE_DEV,
0118 FSID_UUID4_INUM,
0119 FSID_UUID8,
0120 FSID_UUID16,
0121 FSID_UUID16_INUM,
0122 };
0123
0124 enum fsid_source {
0125 FSIDSOURCE_DEV,
0126 FSIDSOURCE_FSID,
0127 FSIDSOURCE_UUID,
0128 };
0129 extern enum fsid_source fsid_source(const struct svc_fh *fhp);
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
0143 u32 fsid, unsigned char *uuid)
0144 {
0145 u32 *up;
0146 switch(vers) {
0147 case FSID_DEV:
0148 fsidv[0] = (__force __u32)htonl((MAJOR(dev)<<16) |
0149 MINOR(dev));
0150 fsidv[1] = ino_t_to_u32(ino);
0151 break;
0152 case FSID_NUM:
0153 fsidv[0] = fsid;
0154 break;
0155 case FSID_MAJOR_MINOR:
0156 fsidv[0] = (__force __u32)htonl(MAJOR(dev));
0157 fsidv[1] = (__force __u32)htonl(MINOR(dev));
0158 fsidv[2] = ino_t_to_u32(ino);
0159 break;
0160
0161 case FSID_ENCODE_DEV:
0162 fsidv[0] = new_encode_dev(dev);
0163 fsidv[1] = ino_t_to_u32(ino);
0164 break;
0165
0166 case FSID_UUID4_INUM:
0167
0168 up = (u32*)uuid;
0169 fsidv[0] = ino_t_to_u32(ino);
0170 fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
0171 break;
0172
0173 case FSID_UUID8:
0174
0175 up = (u32*)uuid;
0176 fsidv[0] = up[0] ^ up[2];
0177 fsidv[1] = up[1] ^ up[3];
0178 break;
0179
0180 case FSID_UUID16:
0181
0182 memcpy(fsidv, uuid, 16);
0183 break;
0184
0185 case FSID_UUID16_INUM:
0186
0187 *(u64*)fsidv = (u64)ino;
0188 memcpy(fsidv+2, uuid, 16);
0189 break;
0190 default: BUG();
0191 }
0192 }
0193
0194 static inline int key_len(int type)
0195 {
0196 switch(type) {
0197 case FSID_DEV: return 8;
0198 case FSID_NUM: return 4;
0199 case FSID_MAJOR_MINOR: return 12;
0200 case FSID_ENCODE_DEV: return 8;
0201 case FSID_UUID4_INUM: return 8;
0202 case FSID_UUID8: return 8;
0203 case FSID_UUID16: return 16;
0204 case FSID_UUID16_INUM: return 24;
0205 default: return 0;
0206 }
0207 }
0208
0209
0210
0211
0212 extern char * SVCFH_fmt(struct svc_fh *fhp);
0213
0214
0215
0216
0217 __be32 fh_verify(struct svc_rqst *, struct svc_fh *, umode_t, int);
0218 __be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
0219 __be32 fh_update(struct svc_fh *);
0220 void fh_put(struct svc_fh *);
0221
0222 static __inline__ struct svc_fh *
0223 fh_copy(struct svc_fh *dst, struct svc_fh *src)
0224 {
0225 WARN_ON(src->fh_dentry);
0226
0227 *dst = *src;
0228 return dst;
0229 }
0230
0231 static inline void
0232 fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src)
0233 {
0234 dst->fh_size = src->fh_size;
0235 memcpy(&dst->fh_raw, &src->fh_raw, src->fh_size);
0236 }
0237
0238 static __inline__ struct svc_fh *
0239 fh_init(struct svc_fh *fhp, int maxsize)
0240 {
0241 memset(fhp, 0, sizeof(*fhp));
0242 fhp->fh_maxsize = maxsize;
0243 return fhp;
0244 }
0245
0246 static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
0247 {
0248 if (fh1->fh_size != fh2->fh_size)
0249 return false;
0250 if (memcmp(fh1->fh_raw, fh2->fh_raw, fh1->fh_size) != 0)
0251 return false;
0252 return true;
0253 }
0254
0255 static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
0256 {
0257 if (fh1->fh_fsid_type != fh2->fh_fsid_type)
0258 return false;
0259 if (memcmp(fh1->fh_fsid, fh2->fh_fsid, key_len(fh1->fh_fsid_type)) != 0)
0260 return false;
0261 return true;
0262 }
0263
0264 #ifdef CONFIG_CRC32
0265
0266
0267
0268
0269
0270
0271
0272 static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh)
0273 {
0274 return ~crc32_le(0xFFFFFFFF, fh->fh_raw, fh->fh_size);
0275 }
0276 #else
0277 static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh)
0278 {
0279 return 0;
0280 }
0281 #endif
0282
0283
0284
0285
0286
0287
0288 static inline void fh_clear_pre_post_attrs(struct svc_fh *fhp)
0289 {
0290 fhp->fh_post_saved = false;
0291 fhp->fh_pre_saved = false;
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 static inline u64 nfsd4_change_attribute(struct kstat *stat,
0306 struct inode *inode)
0307 {
0308 if (inode->i_sb->s_export_op->fetch_iversion)
0309 return inode->i_sb->s_export_op->fetch_iversion(inode);
0310 else if (IS_I_VERSION(inode)) {
0311 u64 chattr;
0312
0313 chattr = stat->ctime.tv_sec;
0314 chattr <<= 30;
0315 chattr += stat->ctime.tv_nsec;
0316 chattr += inode_query_iversion(inode);
0317 return chattr;
0318 } else
0319 return time_to_chattr(&stat->ctime);
0320 }
0321
0322 extern void fh_fill_pre_attrs(struct svc_fh *fhp);
0323 extern void fh_fill_post_attrs(struct svc_fh *fhp);
0324 extern void fh_fill_both_attrs(struct svc_fh *fhp);
0325 #endif