mm/huge_memory.c: use head to emphasize the purpose of page
[linux-2.6-microblaze.git] / fs / nfs / nfs42xdr.c
index aed865a..c03f324 100644 (file)
 #define encode_copy_maxsz              (op_encode_hdr_maxsz +          \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE) + \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE) + \
-                                        2 + 2 + 2 + 1 + 1 + 1)
+                                        2 + 2 + 2 + 1 + 1 + 1 +\
+                                        1 + /* One cnr_source_server */\
+                                        1 + /* nl4_type */ \
+                                        1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
 #define decode_copy_maxsz              (op_decode_hdr_maxsz + \
                                         NFS42_WRITE_RES_SIZE + \
                                         1 /* cr_consecutive */ + \
 #define encode_offload_cancel_maxsz    (op_encode_hdr_maxsz + \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE))
 #define decode_offload_cancel_maxsz    (op_decode_hdr_maxsz)
+#define encode_copy_notify_maxsz       (op_encode_hdr_maxsz + \
+                                        XDR_QUADLEN(NFS4_STATEID_SIZE) + \
+                                        1 + /* nl4_type */ \
+                                        1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
+#define decode_copy_notify_maxsz       (op_decode_hdr_maxsz + \
+                                        3 + /* cnr_lease_time */\
+                                        XDR_QUADLEN(NFS4_STATEID_SIZE) + \
+                                        1 + /* Support 1 cnr_source_server */\
+                                        1 + /* nl4_type */ \
+                                        1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
 #define encode_deallocate_maxsz                (op_encode_hdr_maxsz + \
                                         encode_fallocate_maxsz)
 #define decode_deallocate_maxsz                (op_decode_hdr_maxsz)
                                         decode_sequence_maxsz + \
                                         decode_putfh_maxsz + \
                                         decode_offload_cancel_maxsz)
+#define NFS4_enc_copy_notify_sz                (compound_encode_hdr_maxsz + \
+                                        encode_putfh_maxsz + \
+                                        encode_copy_notify_maxsz)
+#define NFS4_dec_copy_notify_sz                (compound_decode_hdr_maxsz + \
+                                        decode_putfh_maxsz + \
+                                        decode_copy_notify_maxsz)
 #define NFS4_enc_deallocate_sz         (compound_encode_hdr_maxsz + \
                                         encode_sequence_maxsz + \
                                         encode_putfh_maxsz + \
@@ -166,6 +185,26 @@ static void encode_allocate(struct xdr_stream *xdr,
        encode_fallocate(xdr, args);
 }
 
+static void encode_nl4_server(struct xdr_stream *xdr,
+                             const struct nl4_server *ns)
+{
+       encode_uint32(xdr, ns->nl4_type);
+       switch (ns->nl4_type) {
+       case NL4_NAME:
+       case NL4_URL:
+               encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
+               break;
+       case NL4_NETADDR:
+               encode_string(xdr, ns->u.nl4_addr.netid_len,
+                             ns->u.nl4_addr.netid);
+               encode_string(xdr, ns->u.nl4_addr.addr_len,
+                             ns->u.nl4_addr.addr);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+       }
+}
+
 static void encode_copy(struct xdr_stream *xdr,
                        const struct nfs42_copy_args *args,
                        struct compound_hdr *hdr)
@@ -180,7 +219,12 @@ static void encode_copy(struct xdr_stream *xdr,
 
        encode_uint32(xdr, 1); /* consecutive = true */
        encode_uint32(xdr, args->sync);
-       encode_uint32(xdr, 0); /* src server list */
+       if (args->cp_src == NULL) { /* intra-ssc */
+               encode_uint32(xdr, 0); /* no src server list */
+               return;
+       }
+       encode_uint32(xdr, 1); /* supporting 1 server */
+       encode_nl4_server(xdr, args->cp_src);
 }
 
 static void encode_offload_cancel(struct xdr_stream *xdr,
@@ -191,6 +235,15 @@ static void encode_offload_cancel(struct xdr_stream *xdr,
        encode_nfs4_stateid(xdr, &args->osa_stateid);
 }
 
+static void encode_copy_notify(struct xdr_stream *xdr,
+                              const struct nfs42_copy_notify_args *args,
+                              struct compound_hdr *hdr)
+{
+       encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
+       encode_nfs4_stateid(xdr, &args->cna_src_stateid);
+       encode_nl4_server(xdr, &args->cna_dst);
+}
+
 static void encode_deallocate(struct xdr_stream *xdr,
                              const struct nfs42_falloc_args *args,
                              struct compound_hdr *hdr)
@@ -354,6 +407,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
        encode_nops(&hdr);
 }
 
+/*
+ * Encode COPY_NOTIFY request
+ */
+static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
+                                    struct xdr_stream *xdr,
+                                    const void *data)
+{
+       const struct nfs42_copy_notify_args *args = data;
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
+       };
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->cna_seq_args, &hdr);
+       encode_putfh(xdr, args->cna_src_fh, &hdr);
+       encode_copy_notify(xdr, args, &hdr);
+       encode_nops(&hdr);
+}
+
 /*
  * Encode DEALLOCATE request
  */
@@ -490,6 +562,58 @@ static int decode_write_response(struct xdr_stream *xdr,
        return decode_verifier(xdr, &res->verifier.verifier);
 }
 
+static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
+{
+       struct nfs42_netaddr *naddr;
+       uint32_t dummy;
+       char *dummy_str;
+       __be32 *p;
+       int status;
+
+       /* nl_type */
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               return -EIO;
+       ns->nl4_type = be32_to_cpup(p);
+       switch (ns->nl4_type) {
+       case NL4_NAME:
+       case NL4_URL:
+               status = decode_opaque_inline(xdr, &dummy, &dummy_str);
+               if (unlikely(status))
+                       return status;
+               if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
+                       return -EIO;
+               memcpy(&ns->u.nl4_str, dummy_str, dummy);
+               ns->u.nl4_str_sz = dummy;
+               break;
+       case NL4_NETADDR:
+               naddr = &ns->u.nl4_addr;
+
+               /* netid string */
+               status = decode_opaque_inline(xdr, &dummy, &dummy_str);
+               if (unlikely(status))
+                       return status;
+               if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
+                       return -EIO;
+               naddr->netid_len = dummy;
+               memcpy(naddr->netid, dummy_str, naddr->netid_len);
+
+               /* uaddr string */
+               status = decode_opaque_inline(xdr, &dummy, &dummy_str);
+               if (unlikely(status))
+                       return status;
+               if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
+                       return -EIO;
+               naddr->addr_len = dummy;
+               memcpy(naddr->addr, dummy_str, naddr->addr_len);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               return -EIO;
+       }
+       return 0;
+}
+
 static int decode_copy_requirements(struct xdr_stream *xdr,
                                    struct nfs42_copy_res *res) {
        __be32 *p;
@@ -529,6 +653,42 @@ static int decode_offload_cancel(struct xdr_stream *xdr,
        return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
 }
 
+static int decode_copy_notify(struct xdr_stream *xdr,
+                             struct nfs42_copy_notify_res *res)
+{
+       __be32 *p;
+       int status, count;
+
+       status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
+       if (status)
+               return status;
+       /* cnr_lease_time */
+       p = xdr_inline_decode(xdr, 12);
+       if (unlikely(!p))
+               return -EIO;
+       p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
+       res->cnr_lease_time.nseconds = be32_to_cpup(p);
+
+       status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
+       if (unlikely(status))
+               return -EIO;
+
+       /* number of source addresses */
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               return -EIO;
+
+       count = be32_to_cpup(p);
+       if (count > 1)
+               pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
+                        __func__, count);
+
+       status = decode_nl4_server(xdr, &res->cnr_src);
+       if (unlikely(status))
+               return -EIO;
+       return 0;
+}
+
 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
 {
        return decode_op_hdr(xdr, OP_DEALLOCATE);
@@ -656,6 +816,32 @@ out:
        return status;
 }
 
+/*
+ * Decode COPY_NOTIFY response
+ */
+static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
+                                   struct xdr_stream *xdr,
+                                   void *data)
+{
+       struct nfs42_copy_notify_res *res = data;
+       struct compound_hdr hdr;
+       int status;
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+       status = decode_copy_notify(xdr, res);
+
+out:
+       return status;
+}
+
 /*
  * Decode DEALLOCATE request
  */