Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (c) 2020, Oracle and/or its affiliates
0004  */
0005 
0006 #ifndef SVC_RDMA_PCL_H
0007 #define SVC_RDMA_PCL_H
0008 
0009 #include <linux/list.h>
0010 
0011 struct svc_rdma_segment {
0012     u32         rs_handle;
0013     u32         rs_length;
0014     u64         rs_offset;
0015 };
0016 
0017 struct svc_rdma_chunk {
0018     struct list_head    ch_list;
0019 
0020     u32         ch_position;
0021     u32         ch_length;
0022     u32         ch_payload_length;
0023 
0024     u32         ch_segcount;
0025     struct svc_rdma_segment ch_segments[];
0026 };
0027 
0028 struct svc_rdma_pcl {
0029     unsigned int        cl_count;
0030     struct list_head    cl_chunks;
0031 };
0032 
0033 /**
0034  * pcl_init - Initialize a parsed chunk list
0035  * @pcl: parsed chunk list to initialize
0036  *
0037  */
0038 static inline void pcl_init(struct svc_rdma_pcl *pcl)
0039 {
0040     INIT_LIST_HEAD(&pcl->cl_chunks);
0041 }
0042 
0043 /**
0044  * pcl_is_empty - Return true if parsed chunk list is empty
0045  * @pcl: parsed chunk list
0046  *
0047  */
0048 static inline bool pcl_is_empty(const struct svc_rdma_pcl *pcl)
0049 {
0050     return list_empty(&pcl->cl_chunks);
0051 }
0052 
0053 /**
0054  * pcl_first_chunk - Return first chunk in a parsed chunk list
0055  * @pcl: parsed chunk list
0056  *
0057  * Returns the first chunk in the list, or NULL if the list is empty.
0058  */
0059 static inline struct svc_rdma_chunk *
0060 pcl_first_chunk(const struct svc_rdma_pcl *pcl)
0061 {
0062     if (pcl_is_empty(pcl))
0063         return NULL;
0064     return list_first_entry(&pcl->cl_chunks, struct svc_rdma_chunk,
0065                 ch_list);
0066 }
0067 
0068 /**
0069  * pcl_next_chunk - Return next chunk in a parsed chunk list
0070  * @pcl: a parsed chunk list
0071  * @chunk: chunk in @pcl
0072  *
0073  * Returns the next chunk in the list, or NULL if @chunk is already last.
0074  */
0075 static inline struct svc_rdma_chunk *
0076 pcl_next_chunk(const struct svc_rdma_pcl *pcl, struct svc_rdma_chunk *chunk)
0077 {
0078     if (list_is_last(&chunk->ch_list, &pcl->cl_chunks))
0079         return NULL;
0080     return list_next_entry(chunk, ch_list);
0081 }
0082 
0083 /**
0084  * pcl_for_each_chunk - Iterate over chunks in a parsed chunk list
0085  * @pos: the loop cursor
0086  * @pcl: a parsed chunk list
0087  */
0088 #define pcl_for_each_chunk(pos, pcl) \
0089     for (pos = list_first_entry(&(pcl)->cl_chunks, struct svc_rdma_chunk, ch_list); \
0090          &pos->ch_list != &(pcl)->cl_chunks; \
0091          pos = list_next_entry(pos, ch_list))
0092 
0093 /**
0094  * pcl_for_each_segment - Iterate over segments in a parsed chunk
0095  * @pos: the loop cursor
0096  * @chunk: a parsed chunk
0097  */
0098 #define pcl_for_each_segment(pos, chunk) \
0099     for (pos = &(chunk)->ch_segments[0]; \
0100          pos <= &(chunk)->ch_segments[(chunk)->ch_segcount - 1]; \
0101          pos++)
0102 
0103 /**
0104  * pcl_chunk_end_offset - Return offset of byte range following @chunk
0105  * @chunk: chunk in @pcl
0106  *
0107  * Returns starting offset of the region just after @chunk
0108  */
0109 static inline unsigned int
0110 pcl_chunk_end_offset(const struct svc_rdma_chunk *chunk)
0111 {
0112     return xdr_align_size(chunk->ch_position + chunk->ch_payload_length);
0113 }
0114 
0115 struct svc_rdma_recv_ctxt;
0116 
0117 extern void pcl_free(struct svc_rdma_pcl *pcl);
0118 extern bool pcl_alloc_call(struct svc_rdma_recv_ctxt *rctxt, __be32 *p);
0119 extern bool pcl_alloc_read(struct svc_rdma_recv_ctxt *rctxt, __be32 *p);
0120 extern bool pcl_alloc_write(struct svc_rdma_recv_ctxt *rctxt,
0121                 struct svc_rdma_pcl *pcl, __be32 *p);
0122 extern int pcl_process_nonpayloads(const struct svc_rdma_pcl *pcl,
0123                    const struct xdr_buf *xdr,
0124                    int (*actor)(const struct xdr_buf *,
0125                         void *),
0126                    void *data);
0127 
0128 #endif  /* SVC_RDMA_PCL_H */