1 #ifndef _FS_CEPH_OSD_CLIENT_H 2 #define _FS_CEPH_OSD_CLIENT_H 3 4 #include <linux/completion.h> 5 #include <linux/kref.h> 6 #include <linux/mempool.h> 7 #include <linux/rbtree.h> 8 9 #include "types.h" 10 #include "osdmap.h" 11 #include "messenger.h" 12 13 struct ceph_msg; 14 struct ceph_snap_context; 15 struct ceph_osd_request; 16 struct ceph_osd_client; 17 struct ceph_authorizer; 18 struct ceph_pagelist; 19 20 /* 21 * completion callback for async writepages 22 */ 23 typedef void (*ceph_osdc_callback_t)(struct ceph_osd_request *, 24 struct ceph_msg *); 25 26 /* a given osd we're communicating with */ 27 struct ceph_osd { 28 atomic_t o_ref; 29 struct ceph_osd_client *o_osdc; 30 int o_osd; 31 int o_incarnation; 32 struct rb_node o_node; 33 struct ceph_connection o_con; 34 struct list_head o_requests; 35 struct list_head o_osd_lru; 36 struct ceph_authorizer *o_authorizer; 37 void *o_authorizer_buf, *o_authorizer_reply_buf; 38 size_t o_authorizer_buf_len, o_authorizer_reply_buf_len; 39 unsigned long lru_ttl; 40 int o_marked_for_keepalive; 41 struct list_head o_keepalive_item; 42 }; 43 44 /* an in-flight request */ 45 struct ceph_osd_request { 46 u64 r_tid; /* unique for this client */ 47 struct rb_node r_node; 48 struct list_head r_req_lru_item; 49 struct list_head r_osd_item; 50 struct ceph_osd *r_osd; 51 struct ceph_pg r_pgid; 52 int r_pg_osds[CEPH_PG_MAX_SIZE]; 53 int r_num_pg_osds; 54 55 struct ceph_connection *r_con_filling_msg; 56 57 struct ceph_msg *r_request, *r_reply; 58 int r_result; 59 int r_flags; /* any additional flags for the osd */ 60 u32 r_sent; /* >0 if r_request is sending/sent */ 61 int r_got_reply; 62 63 struct ceph_osd_client *r_osdc; 64 struct kref r_kref; 65 bool r_mempool; 66 struct completion r_completion, r_safe_completion; 67 ceph_osdc_callback_t r_callback, r_safe_callback; 68 struct ceph_eversion r_reassert_version; 69 struct list_head r_unsafe_item; 70 71 struct inode *r_inode; /* for use by callbacks */ 72 void *r_priv; /* ditto */ 73 74 char r_oid[40]; /* object name */ 75 int r_oid_len; 76 unsigned long r_stamp; /* send OR check time */ 77 bool r_resend; /* msg send failed, needs retry */ 78 79 struct ceph_file_layout r_file_layout; 80 struct ceph_snap_context *r_snapc; /* snap context for writes */ 81 unsigned r_num_pages; /* size of page array (follows) */ 82 struct page **r_pages; /* pages for data payload */ 83 int r_pages_from_pool; 84 int r_own_pages; /* if true, i own page list */ 85 #ifdef CONFIG_BLOCK 86 struct bio *r_bio; /* instead of pages */ 87 #endif 88 89 struct ceph_pagelist *r_trail; /* trailing part of the data */ 90 }; 91 92 struct ceph_osd_client { 93 struct ceph_client *client; 94 95 struct ceph_osdmap *osdmap; /* current map */ 96 struct rw_semaphore map_sem; 97 struct completion map_waiters; 98 u64 last_requested_map; 99 100 struct mutex request_mutex; 101 struct rb_root osds; /* osds */ 102 struct list_head osd_lru; /* idle osds */ 103 u64 timeout_tid; /* tid of timeout triggering rq */ 104 u64 last_tid; /* tid of last request */ 105 struct rb_root requests; /* pending requests */ 106 struct list_head req_lru; /* pending requests lru */ 107 int num_requests; 108 struct delayed_work timeout_work; 109 struct delayed_work osds_timeout_work; 110 #ifdef CONFIG_DEBUG_FS 111 struct dentry *debugfs_file; 112 #endif 113 114 mempool_t *req_mempool; 115 116 struct ceph_msgpool msgpool_op; 117 struct ceph_msgpool msgpool_op_reply; 118 }; 119 120 struct ceph_osd_req_op { 121 u16 op; /* CEPH_OSD_OP_* */ 122 u32 flags; /* CEPH_OSD_FLAG_* */ 123 union { 124 struct { 125 u64 offset, length; 126 u64 truncate_size; 127 u32 truncate_seq; 128 } extent; 129 struct { 130 const char *name; 131 u32 name_len; 132 const char *val; 133 u32 value_len; 134 __u8 cmp_op; /* CEPH_OSD_CMPXATTR_OP_* */ 135 __u8 cmp_mode; /* CEPH_OSD_CMPXATTR_MODE_* */ 136 } xattr; 137 struct { 138 const char *class_name; 139 __u8 class_len; 140 const char *method_name; 141 __u8 method_len; 142 __u8 argc; 143 const char *indata; 144 u32 indata_len; 145 } cls; 146 struct { 147 u64 cookie, count; 148 } pgls; 149 struct { 150 u64 snapid; 151 } snap; 152 }; 153 u32 payload_len; 154 }; 155 156 extern int ceph_osdc_init(struct ceph_osd_client *osdc, 157 struct ceph_client *client); 158 extern void ceph_osdc_stop(struct ceph_osd_client *osdc); 159 160 extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc, 161 struct ceph_msg *msg); 162 extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, 163 struct ceph_msg *msg); 164 165 extern void ceph_calc_raw_layout(struct ceph_osd_client *osdc, 166 struct ceph_file_layout *layout, 167 u64 snapid, 168 u64 off, u64 *plen, u64 *bno, 169 struct ceph_osd_request *req, 170 struct ceph_osd_req_op *op); 171 172 extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, 173 int flags, 174 struct ceph_snap_context *snapc, 175 struct ceph_osd_req_op *ops, 176 bool use_mempool, 177 gfp_t gfp_flags, 178 struct page **pages, 179 struct bio *bio); 180 181 extern void ceph_osdc_build_request(struct ceph_osd_request *req, 182 u64 off, u64 *plen, 183 struct ceph_osd_req_op *src_ops, 184 struct ceph_snap_context *snapc, 185 struct timespec *mtime, 186 const char *oid, 187 int oid_len); 188 189 extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *, 190 struct ceph_file_layout *layout, 191 struct ceph_vino vino, 192 u64 offset, u64 *len, int op, int flags, 193 struct ceph_snap_context *snapc, 194 int do_sync, u32 truncate_seq, 195 u64 truncate_size, 196 struct timespec *mtime, 197 bool use_mempool, int num_reply); 198 199 static inline void ceph_osdc_get_request(struct ceph_osd_request *req) 200 { 201 kref_get(&req->r_kref); 202 } 203 extern void ceph_osdc_release_request(struct kref *kref); 204 static inline void ceph_osdc_put_request(struct ceph_osd_request *req) 205 { 206 kref_put(&req->r_kref, ceph_osdc_release_request); 207 } 208 209 extern int ceph_osdc_start_request(struct ceph_osd_client *osdc, 210 struct ceph_osd_request *req, 211 bool nofail); 212 extern int ceph_osdc_wait_request(struct ceph_osd_client *osdc, 213 struct ceph_osd_request *req); 214 extern void ceph_osdc_sync(struct ceph_osd_client *osdc); 215 216 extern int ceph_osdc_readpages(struct ceph_osd_client *osdc, 217 struct ceph_vino vino, 218 struct ceph_file_layout *layout, 219 u64 off, u64 *plen, 220 u32 truncate_seq, u64 truncate_size, 221 struct page **pages, int nr_pages); 222 223 extern int ceph_osdc_writepages(struct ceph_osd_client *osdc, 224 struct ceph_vino vino, 225 struct ceph_file_layout *layout, 226 struct ceph_snap_context *sc, 227 u64 off, u64 len, 228 u32 truncate_seq, u64 truncate_size, 229 struct timespec *mtime, 230 struct page **pages, int nr_pages, 231 int flags, int do_sync, bool nofail); 232 233 #endif 234 235