pohmelfs: Use current logging styles.
[pohmelfs.git] / fs / pohmelfs / pohmelfs.h
blob3b30a5916685ef90e18657d0b2f67e832e4970e9
1 /*
2 * Copyright (C) 2011+ Evgeniy Polyakov <zbr@ioremap.net>
3 */
5 #ifndef __POHMELFS_H
6 #define __POHMELFS_H
8 #include <linux/backing-dev.h>
9 #include <linux/crypto.h>
10 #include <linux/fs.h>
11 #include <linux/kref.h>
12 #include <linux/list.h>
13 #include <linux/mutex.h>
14 #include <linux/net.h>
15 #include <linux/pagemap.h>
16 #include <linux/pagevec.h>
17 #include <linux/printk.h>
18 #include <linux/slab.h>
19 #include <linux/time.h>
20 #include <linux/wait.h>
21 #include <linux/workqueue.h>
23 #include <crypto/sha.h>
25 #define dnet_bswap16(x) cpu_to_le16(x)
26 #define dnet_bswap32(x) cpu_to_le32(x)
27 #define dnet_bswap64(x) cpu_to_le64(x)
29 /* theese are needed for packet.h below to compile */
30 #define DNET_ID_SIZE SHA512_DIGEST_SIZE
31 #define DNET_CSUM_SIZE SHA512_DIGEST_SIZE
33 #define POHMELFS_INODE_COLUMN 3
36 * is not used in kernel, but we want to share the same header
37 * with userspace, so I put it here for compiler to shut up
39 int gettimeofday(struct timeval *, struct timezone *);
41 #include "packet.h"
43 static inline struct timespec pohmelfs_date(struct dnet_time *tm)
45 struct timespec ts;
47 ts.tv_sec = tm->tsec;
48 ts.tv_nsec = tm->tnsec;
50 return ts;
53 struct pohmelfs_cmd {
54 struct dnet_cmd cmd;
55 struct dnet_attr attr;
56 union {
57 struct dnet_io_attr io;
58 } p;
62 * Compare two IDs.
63 * Returns 1 when id1 > id2
64 * -1 when id1 < id2
65 * 0 when id1 = id2
67 static inline int dnet_id_cmp_str(const unsigned char *id1, const unsigned char *id2)
69 unsigned int i = 0;
71 for (i*=sizeof(unsigned long); i<DNET_ID_SIZE; ++i) {
72 if (id1[i] < id2[i])
73 return -1;
74 if (id1[i] > id2[i])
75 return 1;
78 return 0;
81 struct pohmelfs_state;
82 struct pohmelfs_sb;
83 struct pohmelfs_trans;
85 struct pohmelfs_trans_cb {
86 int (* init)(struct pohmelfs_trans *t);
87 int (* complete)(struct pohmelfs_trans *t, struct pohmelfs_state *recv);
88 int (* recv_reply)(struct pohmelfs_trans *t, struct pohmelfs_state *recv);
89 void (* destroy)(struct pohmelfs_trans *t);
92 struct pohmelfs_trans {
93 struct list_head trans_entry;
94 struct rb_node trans_node;
96 struct kref refcnt;
98 unsigned long trans;
100 struct inode *inode;
102 struct pohmelfs_state *st;
104 struct pohmelfs_cmd cmd;
106 u64 header_size, data_size;
108 unsigned long long io_offset;
110 void *data;
111 void *recv_data;
113 struct pohmelfs_write_ctl *wctl;
114 void *priv;
116 struct pohmelfs_trans_cb cb;
119 struct pohmelfs_trans *pohmelfs_trans_alloc(struct inode *inode);
120 struct pohmelfs_trans *pohmelfs_trans_alloc_io_buf(struct inode *inode, int group, int command,
121 void *data, u64 offset, u64 size, int aflags, int ioflags, int type);
122 void pohmelfs_trans_put(struct pohmelfs_trans *t);
124 int pohmelfs_trans_insert(struct pohmelfs_trans *t);
125 int pohmelfs_trans_insert_tree(struct pohmelfs_state *st, struct pohmelfs_trans *t);
126 void pohmelfs_trans_remove(struct pohmelfs_trans *t);
127 struct pohmelfs_trans *pohmelfs_trans_lookup(struct pohmelfs_state *st, struct dnet_cmd *cmd);
129 struct pohmelfs_state {
130 struct pohmelfs_connection *conn;
131 struct list_head state_entry;
133 struct sockaddr_storage sa;
134 int addrlen;
135 struct socket *sock;
137 int group_id;
139 struct mutex trans_lock;
140 struct list_head trans_list;
141 struct rb_root trans_root;
143 struct kref refcnt;
145 int routes;
147 /* Waiting/polling machinery */
148 wait_queue_t wait;
149 wait_queue_head_t *whead;
151 struct work_struct io_work;
153 /* is set when dnet_cmd is being read, otherwise attached data */
154 int cmd_read;
155 /* currently read command reply */
156 struct dnet_cmd cmd;
158 uint64_t bsize; /* Block size */
159 uint64_t frsize; /* Fragment size */
160 uint64_t blocks; /* Filesystem size in frsize units */
161 uint64_t bfree; /* # free blocks */
162 uint64_t bavail; /* # free blocks for non-root */
165 struct pohmelfs_state *pohmelfs_state_create(struct pohmelfs_connection *conn, struct sockaddr_storage *sa, int addrlen,
166 int ask_route, int group_id);
167 struct pohmelfs_state *pohmelfs_state_lookup(struct pohmelfs_sb *psb, struct dnet_raw_id *id, int group, ssize_t size);
168 int pohmelfs_grab_states(struct pohmelfs_sb *psb, struct pohmelfs_state ***stp);
170 static inline void pohmelfs_state_get(struct pohmelfs_state *st)
172 kref_get(&st->refcnt);
175 void pohmelfs_state_put(struct pohmelfs_state *st);
176 void pohmelfs_state_kill(struct pohmelfs_state *st);
178 struct pohmelfs_state *pohmelfs_addr_exist(struct pohmelfs_connection *conn, struct sockaddr_storage *sa, int addrlen);
180 void pohmelfs_state_schedule(struct pohmelfs_state *st);
182 __attribute__ ((format (printf, 2, 3))) void pohmelfs_print_addr(struct sockaddr_storage *addr, const char *fmt, ...);
184 #define POHMELFS_INODE_INFO_REMOVED (1<<0)
186 struct pohmelfs_inode_info {
187 struct dnet_raw_id id;
189 unsigned int mode;
190 unsigned int nlink;
191 unsigned int uid;
192 unsigned int gid;
193 unsigned int blocksize;
194 unsigned int namelen;
195 __u64 ino;
196 __u64 blocks;
197 __u64 rdev;
198 __u64 size;
199 __u64 version;
201 __u64 flags;
203 struct dnet_time ctime;
204 struct dnet_time mtime;
205 struct dnet_time atime;
206 } __attribute__ ((packed));
208 void pohmelfs_fill_inode_info(struct inode *inode, struct pohmelfs_inode_info *info);
209 void pohmelfs_fill_inode(struct inode *inode, struct pohmelfs_inode_info *info);
210 void pohmelfs_convert_inode_info(struct pohmelfs_inode_info *info);
212 struct pohmelfs_inode {
213 struct inode vfs_inode;
214 struct dnet_raw_id id;
216 struct rb_node node;
218 struct mutex lock;
220 int *groups;
221 int group_num;
223 time_t update;
224 int local;
227 int pohmelfs_send_dentry(struct pohmelfs_inode *pi, struct dnet_raw_id *id, const char *sname, int len, int sync);
228 struct pohmelfs_inode *pohmelfs_sb_inode_lookup(struct pohmelfs_sb *psb, struct dnet_raw_id *id);
230 struct pohmelfs_reconnect {
231 struct list_head reconnect_entry;
232 struct sockaddr_storage sa;
233 int addrlen;
234 int group_id;
237 int pohmelfs_state_add_reconnect(struct pohmelfs_state *st);
239 struct pohmelfs_path {
240 struct mutex lock;
241 char *data;
244 int pohmelfs_http_compat_id(struct pohmelfs_inode *pi);
246 struct pohmelfs_addr {
247 struct list_head addr_entry;
248 struct sockaddr_storage sa;
249 int addrlen;
252 struct pohmelfs_connection {
253 struct pohmelfs_sb *psb;
255 int idx;
257 struct rb_root route_root;
258 struct list_head state_list;
259 spinlock_t state_lock;
261 struct mutex reconnect_lock;
262 struct list_head reconnect_list;
263 struct list_head kill_state_list;
265 struct workqueue_struct *wq;
267 int need_exit;
268 struct delayed_work reconnect_work;
271 void pohmelfs_pool_clean(struct pohmelfs_connection *conn, int conn_num);
272 int pohmelfs_pool_resize(struct pohmelfs_sb *psb, int num);
274 struct pohmelfs_sb {
275 struct super_block *sb;
276 struct backing_dev_info bdi;
278 struct pohmelfs_inode *root;
280 spinlock_t inode_lock;
281 struct rb_root inode_root;
283 int http_compat;
284 struct pohmelfs_path *path;
286 int bdi_num;
288 struct pohmelfs_connection *conn;
289 int conn_num;
290 int bulk_idx, bulk_num;
291 int meta_idx, meta_num;
292 struct mutex conn_lock;
294 /* protected by conn_lock */
295 struct list_head addr_list;
297 long read_wait_timeout;
298 long write_wait_timeout;
299 long sync_timeout;
300 long reconnect_timeout;
302 int need_exit;
303 struct delayed_work sync_work;
304 struct workqueue_struct *wq;
306 char *fsid;
307 int fsid_len;
309 atomic_long_t ino;
310 atomic_long_t trans;
312 struct crypto_hash *hash;
314 int *groups;
315 int group_num;
318 * number of copies to be successfully written to mark write as successful
319 * if not set, half of groups plus one must be successfully written, i.e. plain write quorum
321 int successful_write_count;
322 int keepalive_cnt, keepalive_interval, keepalive_idle;
323 int readdir_allocation;
324 int sync_on_close;
325 int no_read_csum;
328 static inline struct pohmelfs_sb *pohmelfs_sb(struct super_block *sb)
330 return (struct pohmelfs_sb *)sb->s_fs_info;
333 static inline struct pohmelfs_inode *pohmelfs_inode(struct inode *inode)
335 return container_of(inode, struct pohmelfs_inode, vfs_inode);
338 struct pohmelfs_wait {
339 wait_queue_head_t wq;
340 struct pohmelfs_inode *pi;
341 void *ret;
342 atomic_long_t count;
343 int condition;
344 struct kref refcnt;
347 int pohmelfs_wait_init(struct pohmelfs_wait *wait, struct pohmelfs_inode *pi);
348 struct pohmelfs_wait *pohmelfs_wait_alloc(struct pohmelfs_inode *pi);
349 void pohmelfs_wait_put(struct pohmelfs_wait *wait);
350 static inline void pohmelfs_wait_get(struct pohmelfs_wait *wait)
352 kref_get(&wait->refcnt);
355 struct pohmelfs_inode_info_binary_package {
356 struct pohmelfs_inode_info info;
358 struct pohmelfs_wait wait;
361 struct pohmelfs_write_ctl {
362 struct pagevec pvec;
363 struct pohmelfs_inode_info *info;
365 struct kref refcnt;
366 atomic_t good_writes;
369 struct pohmelfs_dentry_disk {
370 struct dnet_raw_id id;
371 uint64_t ino;
372 int type;
373 int len;
374 char name[0];
375 } __attribute__((packed));
377 struct pohmelfs_dentry {
378 struct dnet_raw_id parent_id;
379 struct pohmelfs_dentry_disk disk;
382 extern struct kmem_cache *pohmelfs_inode_cache;
383 extern struct kmem_cache *pohmelfs_trans_cache;
384 extern struct kmem_cache *pohmelfs_inode_info_cache;
385 extern struct kmem_cache *pohmelfs_route_cache;
386 extern struct kmem_cache *pohmelfs_wait_cache;
387 extern struct kmem_cache *pohmelfs_io_cache;
388 extern struct kmem_cache *pohmelfs_inode_info_binary_package_cache;
389 extern struct kmem_cache *pohmelfs_write_cache;
390 extern struct kmem_cache *pohmelfs_dentry_cache;
392 struct inode *pohmelfs_alloc_inode(struct super_block *sb);
393 void pohmelfs_destroy_inode(struct inode *);
395 struct pohmelfs_inode *pohmelfs_existing_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode_info *info);
396 struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb, int mode);
397 int pohmelfs_hash(struct pohmelfs_sb *psb, const void *data, const size_t size, struct dnet_raw_id *id);
399 char *pohmelfs_dump_id(const unsigned char *id);
400 char *pohmelfs_dump_id_len_raw(const unsigned char *id, unsigned int len, char *dst);
402 int pohmelfs_write_command(struct pohmelfs_inode *pi, struct pohmelfs_write_ctl *ctl, loff_t offset, size_t len);
403 void pohmelfs_write_ctl_release(struct kref *kref);
404 int pohmelfs_metadata_inode(struct pohmelfs_inode *pi, int sync);
406 extern const struct file_operations pohmelfs_dir_fops;
407 extern const struct inode_operations pohmelfs_dir_inode_operations;
409 extern const struct file_operations pohmelfs_file_ops;
410 extern const struct inode_operations pohmelfs_file_inode_operations;
412 extern const struct inode_operations pohmelfs_symlink_inode_operations;
413 extern const struct inode_operations pohmelfs_special_inode_operations;
415 extern void *pohmelfs_scratch_buf;
416 extern int pohmelfs_scratch_buf_size;
419 * if this flag is set, pohmelfs_inode_info->data is owned by the caller,
420 * so sending path may use it on its own and free (using kfree) when it's done
422 * This logic does not work for shared buffers or
423 * when multiple transactions will be sent for single pohmelfs_inode_info
425 #define POHMELFS_IO_OWN (1<<0)
427 struct pohmelfs_io {
428 struct pohmelfs_inode *pi;
430 struct dnet_raw_id *id;
432 int cmd;
433 int type;
435 u64 offset, size;
436 u64 start, num;
438 u32 cflags;
439 u32 aflags;
440 u32 ioflags;
442 int group_id;
444 u32 alloc_flags;
445 void *data;
447 struct pohmelfs_write_ctl *wctl;
448 void *priv;
450 struct pohmelfs_trans_cb cb;
453 int pohmelfs_send_io_group(struct pohmelfs_io *pio, int group_id);
454 int pohmelfs_send_io(struct pohmelfs_io *pio);
455 int pohmelfs_send_buf_single(struct pohmelfs_io *pio, struct pohmelfs_state *st);
456 int pohmelfs_send_buf(struct pohmelfs_io *pio);
458 int pohmelfs_data_recv(struct pohmelfs_state *st, void *buf, u64 size, unsigned int flags);
459 int pohmelfs_recv(struct pohmelfs_trans *t, struct pohmelfs_state *recv, void *data, int size);
461 struct pohmelfs_route {
462 struct rb_node node;
463 int group_id;
464 struct dnet_raw_id id;
465 struct pohmelfs_state *st;
468 int pohmelfs_route_request(struct pohmelfs_state *st);
469 void pohmelfs_route_remove_all(struct pohmelfs_state *st);
471 struct pohmelfs_script_req {
472 char *obj_name;
473 int obj_len;
475 char *script_name;
476 int script_namelen;
478 void *binary;
479 int binary_size;
481 int group_id;
483 unsigned int cflags;
484 int sync;
486 struct dnet_raw_id *id;
488 int (* complete)(struct pohmelfs_trans *t, struct pohmelfs_state *recv);
489 void *ret;
490 int ret_cond;
493 int pohmelfs_send_script_request(struct pohmelfs_inode *parent, struct pohmelfs_script_req *req);
495 int pohmelfs_stat(struct pohmelfs_sb *psb, int sync);
497 static inline int pohmelfs_need_resync(struct pohmelfs_inode *pi)
499 struct pohmelfs_sb *psb = pohmelfs_sb(pi->vfs_inode.i_sb);
500 return get_seconds() > pi->update + psb->sync_timeout;
503 #endif /* __POHMELFS_H */