]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/nfs/nfsm_subs.h
xnu-2422.90.20.tar.gz
[apple/xnu.git] / bsd / nfs / nfsm_subs.h
index 2daeebc9cd80ab68afb7d413b94273db61da23b1..434d4f57a54b5a8ab4d4a19a88754a4b0f42cf89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
 
 #ifdef __APPLE_API_PRIVATE
 
-int nfsm_rpchead(struct nfsreq *, int, mbuf_t, u_int64_t *, mbuf_t *);
-int nfsm_rpchead2(int, int, int, int, int, int, kauth_cred_t, struct nfsreq *, mbuf_t, u_int64_t *, mbuf_t *);
+int nfsm_rpchead(struct nfsreq *, mbuf_t, u_int64_t *, mbuf_t *);
+int nfsm_rpchead2(struct nfsmount *, int, int, int, int, int, kauth_cred_t, struct nfsreq *, mbuf_t, u_int64_t *, mbuf_t *);
 
 int nfsm_chain_new_mbuf(struct nfsm_chain *, size_t);
 int nfsm_chain_add_opaque_f(struct nfsm_chain *, const u_char *, uint32_t);
 int nfsm_chain_add_opaque_nopad_f(struct nfsm_chain *, const u_char *, uint32_t);
-int nfsm_chain_add_uio(struct nfsm_chain *, struct uio *, uint32_t);
+int nfsm_chain_add_uio(struct nfsm_chain *, uio_t, uint32_t);
 int nfsm_chain_add_fattr4_f(struct nfsm_chain *, struct vnode_attr *, struct nfsmount *);
 int nfsm_chain_add_v2sattr_f(struct nfsm_chain *, struct vnode_attr *, uint32_t);
 int nfsm_chain_add_v3sattr_f(struct nfsm_chain *, struct vnode_attr *);
+int nfsm_chain_add_string_nfc(struct nfsm_chain *, const uint8_t *, uint32_t);
 
 int nfsm_chain_advance(struct nfsm_chain *, uint32_t);
 int nfsm_chain_offset(struct nfsm_chain *);
 int nfsm_chain_reverse(struct nfsm_chain *, uint32_t);
 int nfsm_chain_get_opaque_pointer_f(struct nfsm_chain *, uint32_t, u_char **);
 int nfsm_chain_get_opaque_f(struct nfsm_chain *, uint32_t, u_char *);
-int nfsm_chain_get_uio(struct nfsm_chain *, uint32_t, struct uio *);
+int nfsm_chain_get_uio(struct nfsm_chain *, uint32_t, uio_t);
 int nfsm_chain_get_fh_attr(struct nfsm_chain *, nfsnode_t,
        vfs_context_t, int, uint64_t *, fhandle_t *, struct nfs_vattr *);
 int nfsm_chain_get_wcc_data_f(struct nfsm_chain *, nfsnode_t, struct timespec *, int *, u_int64_t *);
+int nfsm_chain_get_secinfo(struct nfsm_chain *, uint32_t *, int *);
 
 #if NFSSERVER
 void nfsm_adj(mbuf_t, int, int);
@@ -339,6 +341,16 @@ int nfsm_chain_trim_data(struct nfsm_chain *, int, int *);
                nfsm_chain_add_opaque((E), (NMC), (STR), (LEN)); \
        } while (0)
 
+/* add a name to an mbuf chain */
+#define nfsm_chain_add_name(E, NMC, STR, LEN, NMP) \
+       do { \
+               if (E) break; \
+               if (NMFLAG((NMP), NFC)) \
+                       (E) = nfsm_chain_add_string_nfc((NMC), (const uint8_t*)(STR), (LEN)); \
+               else \
+                       nfsm_chain_add_string((E), (NMC), (STR), (LEN)); \
+       } while (0)
+
 /* add an NFSv2 time to an mbuf chain */
 #define nfsm_chain_add_v2time(E, NMC, TVP) \
        do { \
@@ -420,12 +432,18 @@ int nfsm_chain_trim_data(struct nfsm_chain *, int, int *);
        } while (0)
 
 /* add NFSv4 COMPOUND header */
+#define NFS4_TAG_LENGTH        12
 #define nfsm_chain_add_compound_header(E, NMC, TAG, NUMOPS) \
        do { \
-               if ((TAG) && strlen(TAG)) \
-                       nfsm_chain_add_string((E), (NMC), (TAG), strlen(TAG)); \
-               else \
+               if ((TAG) && strlen(TAG)) { \
+                       /* put tags into a fixed-length space-padded field */ \
+                       char __nfstag[NFS4_TAG_LENGTH+1]; \
+                       snprintf(__nfstag, sizeof(__nfstag), "%-*s", NFS4_TAG_LENGTH, (TAG)); \
+                       nfsm_chain_add_32((E), (NMC), NFS4_TAG_LENGTH); \
+                       nfsm_chain_add_opaque((E), (NMC), __nfstag, NFS4_TAG_LENGTH); \
+               } else { \
                        nfsm_chain_add_32((E), (NMC), 0); \
+               } \
                nfsm_chain_add_32((E), (NMC), 0); /*minorversion*/ \
                nfsm_chain_add_32((E), (NMC), (NUMOPS)); \
        } while (0)
@@ -448,6 +466,56 @@ int nfsm_chain_trim_data(struct nfsm_chain *, int, int *);
                        nfsm_chain_add_32((E), (NMC), ((B)[__i] & (MASK)[__i])); \
        } while (0)
 
+/* add NFSv4 attr bitmap masked with the supported attributes for this mount/node */
+#define nfsm_chain_add_bitmap_supported(E, NMC, B, NMP, NP) \
+       do { \
+               uint32_t __bitmap[NFS_ATTR_BITMAP_LEN], *__bmp = (B); \
+               int __nonamedattr = 0, __noacl = 0, __nomode = 0; \
+               if (!((NMP)->nm_fsattr.nfsa_flags & NFS_FSFLAG_NAMED_ATTR) || \
+                   ((NP) && (((nfsnode_t)(NP))->n_flag & (NISDOTZFS|NISDOTZFSCHILD)))) \
+                       __nonamedattr = 1; \
+               if (!((NMP)->nm_fsattr.nfsa_flags & NFS_FSFLAG_ACL)) \
+                       __noacl = 1; \
+               if (NMFLAG((NMP), ACLONLY)) \
+                       __nomode = 1; \
+               if (__nonamedattr || __noacl || __nomode) { \
+                       /* don't ask for attrs we're not supporting */ \
+                       /* some ".zfs" directories can't handle being asked for some attributes */ \
+                       int __ii; \
+                       NFS_CLEAR_ATTRIBUTES(__bitmap); \
+                       for (__ii=0; __ii < NFS_ATTR_BITMAP_LEN; __ii++) \
+                               __bitmap[__ii] = (B)[__ii]; \
+                       if (__nonamedattr) \
+                               NFS_BITMAP_CLR(__bitmap, NFS_FATTR_NAMED_ATTR); \
+                       if (__noacl) \
+                               NFS_BITMAP_CLR(__bitmap, NFS_FATTR_ACL); \
+                       if (__nomode) \
+                               NFS_BITMAP_CLR(__bitmap, NFS_FATTR_MODE); \
+                       __bmp = __bitmap; \
+               } \
+               nfsm_chain_add_bitmap_masked((E), (NMC), __bmp, NFS_ATTR_BITMAP_LEN, (NMP)->nm_fsattr.nfsa_supp_attr); \
+       } while (0)
+
+/* Add an NFSv4 "stateid" structure to an mbuf chain */
+#define nfsm_chain_add_stateid(E, NMC, SID) \
+       do { \
+               nfsm_chain_add_32((E), (NMC), (SID)->seqid); \
+               nfsm_chain_add_32((E), (NMC), (SID)->other[0]); \
+               nfsm_chain_add_32((E), (NMC), (SID)->other[1]); \
+               nfsm_chain_add_32((E), (NMC), (SID)->other[2]); \
+       } while (0)
+
+/* add an NFSv4 lock owner structure to an mbuf chain */
+#define nfsm_chain_add_lock_owner4(E, NMC, NMP, NLOP) \
+       do { \
+               nfsm_chain_add_64((E), (NMC), (NMP)->nm_clientid); \
+               nfsm_chain_add_32((E), (NMC), 5*NFSX_UNSIGNED); \
+               nfsm_chain_add_32((E), (NMC), (NLOP)->nlo_name); \
+               nfsm_chain_add_32((E), (NMC), (NLOP)->nlo_pid); \
+               nfsm_chain_add_64((E), (NMC), (NLOP)->nlo_pid_start.tv_sec); \
+               nfsm_chain_add_32((E), (NMC), (NLOP)->nlo_pid_start.tv_usec); \
+       } while (0)
+
 /*
  * macros for dissecting NFS mbuf chains
  */
@@ -616,38 +684,48 @@ int nfsm_chain_trim_data(struct nfsm_chain *, int, int *);
        } while (0)
 
 /* update a node's attribute cache with attributes from an mbuf chain */
-#define nfsm_chain_loadattr(E, NMC, NP, VERS, A, X) \
+#define nfsm_chain_loadattr(E, NMC, NP, VERS, X) \
        do { \
-               struct nfs_vattr ttvattr, *ttnvap; \
+               struct nfs_vattr ttvattr; \
                if (E) break; \
-               ttnvap = (A) ? (A) : &ttvattr; \
                if ((VERS) == NFS_VER4) { \
-                       NFS_CLEAR_ATTRIBUTES(ttnvap->nva_bitmap); \
-                       (E) = nfs4_parsefattr((NMC), NULL, ttnvap, NULL, NULL); \
+                       (E) = nfs4_parsefattr((NMC), NULL, &ttvattr, NULL, NULL, NULL); \
                } else { \
-                       (E) = nfs_parsefattr((NMC), (VERS), ttnvap); \
+                       (E) = nfs_parsefattr((NMC), (VERS), &ttvattr); \
                } \
-               if (E) break; \
-               (E) = nfs_loadattrcache((NP), ttnvap, (X), 0); \
+               if (!(E) && (NP)) \
+                       (E) = nfs_loadattrcache((NP), &ttvattr, (X), 0); \
+               NVATTR_CLEANUP(&ttvattr); \
        } while (0)
 
 /* get NFSv4 attr bitmap */
 #define nfsm_chain_get_bitmap(E, NMC, B, LEN) \
        do { \
-               uint32_t __len, __i; \
+               uint32_t __len = 0, __i; \
                nfsm_chain_get_32((E), (NMC), __len); \
                if (E) break; \
                for (__i=0; __i < MIN(__len, (LEN)); __i++) \
                        nfsm_chain_get_32((E), (NMC), (B)[__i]); \
                if (E) break; \
+               for (; __i < __len; __i++) \
+                       nfsm_chain_adv((E), (NMC), NFSX_UNSIGNED); \
                for (; __i < (LEN); __i++) \
                        (B)[__i] = 0; \
                (LEN) = __len; \
        } while (0)
 
+/* get an NFSv4 "stateid" structure from an mbuf chain */
+#define nfsm_chain_get_stateid(E, NMC, SID) \
+       do { \
+               nfsm_chain_get_32((E), (NMC), (SID)->seqid); \
+               nfsm_chain_get_32((E), (NMC), (SID)->other[0]); \
+               nfsm_chain_get_32((E), (NMC), (SID)->other[1]); \
+               nfsm_chain_get_32((E), (NMC), (SID)->other[2]); \
+       } while (0)
+
 #define nfsm_chain_skip_tag(E, NMC) \
        do { \
-               uint32_t __val; \
+               uint32_t __val = 0; \
                nfsm_chain_get_32((E), (NMC), __val); \
                nfsm_chain_adv((E), (NMC), nfsm_rndup(__val)); \
        } while (0)
@@ -656,7 +734,8 @@ int nfsm_chain_trim_data(struct nfsm_chain *, int, int *);
        do { \
                uint32_t __val = 0; \
                nfsm_chain_get_32((E), (NMC), __val); \
-               nfsm_assert((E), (__val == (OP)), EBADRPC); \
+               /* [sigh] some implementations return the "illegal" op for unsupported ops */ \
+               nfsm_assert((E), ((__val == (OP)) || (__val == NFS_OP_ILLEGAL)), EBADRPC); \
                nfsm_chain_get_32((E), (NMC), __val); \
                nfsm_assert((E), (__val == NFS_OK), __val); \
        } while (0)
@@ -668,11 +747,13 @@ int nfsm_chain_trim_data(struct nfsm_chain *, int, int *);
                nfsm_chain_get_32((E), (NMC), __ci_atomic); \
                nfsm_chain_get_64((E), (NMC), __ci_before); \
                nfsm_chain_get_64((E), (NMC), __ci_after); \
-               if (E) break; \
-               if (__ci_atomic && (__ci_before == (DNP)->n_ncchange)) \
+               if ((E) || !(DNP)) break; \
+               if (__ci_atomic && (__ci_before == (DNP)->n_ncchange)) \
                        (DNP)->n_ncchange = __ci_after; \
-               else \
+               } else { \
                        cache_purge(NFSTOV(DNP)); \
+                       (DNP)->n_ncgen++; \
+               } \
        } while (0)
 
 #endif /* __APPLE_API_PRIVATE */