nfsfh.h 6.6 KB

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