nfsfh.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
  3. *
  4. * This file describes the layout of the file handles as passed
  5. * over the wire.
  6. */
  7. #ifndef _LINUX_NFSD_NFSFH_H
  8. #define _LINUX_NFSD_NFSFH_H
  9. #include <linux/crc32.h>
  10. #include <linux/sunrpc/svc.h>
  11. #include <uapi/linux/nfsd/nfsfh.h>
  12. static inline __u32 ino_t_to_u32(ino_t ino)
  13. {
  14. return (__u32) ino;
  15. }
  16. static inline ino_t u32_to_ino_t(__u32 uino)
  17. {
  18. return (ino_t) uino;
  19. }
  20. /*
  21. * This is the internal representation of an NFS handle used in knfsd.
  22. * pre_mtime/post_version will be used to support wcc_attr's in NFSv3.
  23. */
  24. typedef struct svc_fh {
  25. struct knfsd_fh fh_handle; /* FH data */
  26. int fh_maxsize; /* max size for fh_handle */
  27. struct dentry * fh_dentry; /* validated dentry */
  28. struct svc_export * fh_export; /* export pointer */
  29. bool fh_locked; /* inode locked by us */
  30. bool fh_want_write; /* remount protection taken */
  31. #ifdef CONFIG_NFSD_V3
  32. bool fh_post_saved; /* post-op attrs saved */
  33. bool fh_pre_saved; /* pre-op attrs saved */
  34. /* Pre-op attributes saved during fh_lock */
  35. __u64 fh_pre_size; /* size before operation */
  36. struct timespec fh_pre_mtime; /* mtime before oper */
  37. struct timespec fh_pre_ctime; /* ctime before oper */
  38. /*
  39. * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
  40. * to find out if it is valid.
  41. */
  42. u64 fh_pre_change;
  43. /* Post-op attributes saved in fh_unlock */
  44. struct kstat fh_post_attr; /* full attrs after operation */
  45. u64 fh_post_change; /* nfsv4 change; see above */
  46. #endif /* CONFIG_NFSD_V3 */
  47. } svc_fh;
  48. enum nfsd_fsid {
  49. FSID_DEV = 0,
  50. FSID_NUM,
  51. FSID_MAJOR_MINOR,
  52. FSID_ENCODE_DEV,
  53. FSID_UUID4_INUM,
  54. FSID_UUID8,
  55. FSID_UUID16,
  56. FSID_UUID16_INUM,
  57. };
  58. enum fsid_source {
  59. FSIDSOURCE_DEV,
  60. FSIDSOURCE_FSID,
  61. FSIDSOURCE_UUID,
  62. };
  63. extern enum fsid_source fsid_source(struct svc_fh *fhp);
  64. /*
  65. * This might look a little large to "inline" but in all calls except
  66. * one, 'vers' is constant so moste of the function disappears.
  67. *
  68. * In some cases the values are considered to be host endian and in
  69. * others, net endian. fsidv is always considered to be u32 as the
  70. * callers don't know which it will be. So we must use __force to keep
  71. * sparse from complaining. Since these values are opaque to the
  72. * client, that shouldn't be a problem.
  73. */
  74. static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
  75. u32 fsid, unsigned char *uuid)
  76. {
  77. u32 *up;
  78. switch(vers) {
  79. case FSID_DEV:
  80. fsidv[0] = (__force __u32)htonl((MAJOR(dev)<<16) |
  81. MINOR(dev));
  82. fsidv[1] = ino_t_to_u32(ino);
  83. break;
  84. case FSID_NUM:
  85. fsidv[0] = fsid;
  86. break;
  87. case FSID_MAJOR_MINOR:
  88. fsidv[0] = (__force __u32)htonl(MAJOR(dev));
  89. fsidv[1] = (__force __u32)htonl(MINOR(dev));
  90. fsidv[2] = ino_t_to_u32(ino);
  91. break;
  92. case FSID_ENCODE_DEV:
  93. fsidv[0] = new_encode_dev(dev);
  94. fsidv[1] = ino_t_to_u32(ino);
  95. break;
  96. case FSID_UUID4_INUM:
  97. /* 4 byte fsid and inode number */
  98. up = (u32*)uuid;
  99. fsidv[0] = ino_t_to_u32(ino);
  100. fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
  101. break;
  102. case FSID_UUID8:
  103. /* 8 byte fsid */
  104. up = (u32*)uuid;
  105. fsidv[0] = up[0] ^ up[2];
  106. fsidv[1] = up[1] ^ up[3];
  107. break;
  108. case FSID_UUID16:
  109. /* 16 byte fsid - NFSv3+ only */
  110. memcpy(fsidv, uuid, 16);
  111. break;
  112. case FSID_UUID16_INUM:
  113. /* 8 byte inode and 16 byte fsid */
  114. *(u64*)fsidv = (u64)ino;
  115. memcpy(fsidv+2, uuid, 16);
  116. break;
  117. default: BUG();
  118. }
  119. }
  120. static inline int key_len(int type)
  121. {
  122. switch(type) {
  123. case FSID_DEV: return 8;
  124. case FSID_NUM: return 4;
  125. case FSID_MAJOR_MINOR: return 12;
  126. case FSID_ENCODE_DEV: return 8;
  127. case FSID_UUID4_INUM: return 8;
  128. case FSID_UUID8: return 8;
  129. case FSID_UUID16: return 16;
  130. case FSID_UUID16_INUM: return 24;
  131. default: return 0;
  132. }
  133. }
  134. /*
  135. * Shorthand for dprintk()'s
  136. */
  137. extern char * SVCFH_fmt(struct svc_fh *fhp);
  138. /*
  139. * Function prototypes
  140. */
  141. __be32 fh_verify(struct svc_rqst *, struct svc_fh *, umode_t, int);
  142. __be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
  143. __be32 fh_update(struct svc_fh *);
  144. void fh_put(struct svc_fh *);
  145. static __inline__ struct svc_fh *
  146. fh_copy(struct svc_fh *dst, struct svc_fh *src)
  147. {
  148. WARN_ON(src->fh_dentry || src->fh_locked);
  149. *dst = *src;
  150. return dst;
  151. }
  152. static inline void
  153. fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src)
  154. {
  155. dst->fh_size = src->fh_size;
  156. memcpy(&dst->fh_base, &src->fh_base, src->fh_size);
  157. }
  158. static __inline__ struct svc_fh *
  159. fh_init(struct svc_fh *fhp, int maxsize)
  160. {
  161. memset(fhp, 0, sizeof(*fhp));
  162. fhp->fh_maxsize = maxsize;
  163. return fhp;
  164. }
  165. static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
  166. {
  167. if (fh1->fh_size != fh2->fh_size)
  168. return false;
  169. if (memcmp(fh1->fh_base.fh_pad, fh2->fh_base.fh_pad, fh1->fh_size) != 0)
  170. return false;
  171. return true;
  172. }
  173. static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
  174. {
  175. if (fh1->fh_fsid_type != fh2->fh_fsid_type)
  176. return false;
  177. if (memcmp(fh1->fh_fsid, fh2->fh_fsid, key_len(fh1->fh_fsid_type)) != 0)
  178. return false;
  179. return true;
  180. }
  181. #ifdef CONFIG_CRC32
  182. /**
  183. * knfsd_fh_hash - calculate the crc32 hash for the filehandle
  184. * @fh - pointer to filehandle
  185. *
  186. * returns a crc32 hash for the filehandle that is compatible with
  187. * the one displayed by "wireshark".
  188. */
  189. static inline u32
  190. knfsd_fh_hash(struct knfsd_fh *fh)
  191. {
  192. return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size);
  193. }
  194. #else
  195. static inline u32
  196. knfsd_fh_hash(struct knfsd_fh *fh)
  197. {
  198. return 0;
  199. }
  200. #endif
  201. #ifdef CONFIG_NFSD_V3
  202. /*
  203. * The wcc data stored in current_fh should be cleared
  204. * between compound ops.
  205. */
  206. static inline void
  207. fh_clear_wcc(struct svc_fh *fhp)
  208. {
  209. fhp->fh_post_saved = false;
  210. fhp->fh_pre_saved = false;
  211. }
  212. /*
  213. * Fill in the pre_op attr for the wcc data
  214. */
  215. static inline void
  216. fill_pre_wcc(struct svc_fh *fhp)
  217. {
  218. struct inode *inode;
  219. inode = d_inode(fhp->fh_dentry);
  220. if (!fhp->fh_pre_saved) {
  221. fhp->fh_pre_mtime = inode->i_mtime;
  222. fhp->fh_pre_ctime = inode->i_ctime;
  223. fhp->fh_pre_size = inode->i_size;
  224. fhp->fh_pre_change = inode->i_version;
  225. fhp->fh_pre_saved = true;
  226. }
  227. }
  228. extern void fill_post_wcc(struct svc_fh *);
  229. #else
  230. #define fh_clear_wcc(ignored)
  231. #define fill_pre_wcc(ignored)
  232. #define fill_post_wcc(notused)
  233. #endif /* CONFIG_NFSD_V3 */
  234. /*
  235. * Lock a file handle/inode
  236. * NOTE: both fh_lock and fh_unlock are done "by hand" in
  237. * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
  238. * so, any changes here should be reflected there.
  239. */
  240. static inline void
  241. fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
  242. {
  243. struct dentry *dentry = fhp->fh_dentry;
  244. struct inode *inode;
  245. BUG_ON(!dentry);
  246. if (fhp->fh_locked) {
  247. printk(KERN_WARNING "fh_lock: %pd2 already locked!\n",
  248. dentry);
  249. return;
  250. }
  251. inode = d_inode(dentry);
  252. inode_lock_nested(inode, subclass);
  253. fill_pre_wcc(fhp);
  254. fhp->fh_locked = true;
  255. }
  256. static inline void
  257. fh_lock(struct svc_fh *fhp)
  258. {
  259. fh_lock_nested(fhp, I_MUTEX_NORMAL);
  260. }
  261. /*
  262. * Unlock a file handle/inode
  263. */
  264. static inline void
  265. fh_unlock(struct svc_fh *fhp)
  266. {
  267. if (fhp->fh_locked) {
  268. fill_post_wcc(fhp);
  269. inode_unlock(d_inode(fhp->fh_dentry));
  270. fhp->fh_locked = false;
  271. }
  272. }
  273. #endif /* _LINUX_NFSD_NFSFH_H */