Always set prepare bit in write command. Use async writes only.
[pohmelfs.git] / fs / pohmelfs / pohmelfs.h
blob6b62716780a4cf75a68028644840394f26cdbfac
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/wait.h>
20 #include <linux/workqueue.h>
22 #include <crypto/sha.h>
24 #define dnet_bswap16(x) cpu_to_le16(x)
25 #define dnet_bswap32(x) cpu_to_le32(x)
26 #define dnet_bswap64(x) cpu_to_le64(x)
28 /* theese are needed for packet.h below to compile */
29 #define DNET_ID_SIZE SHA512_DIGEST_SIZE
30 #define DNET_CSUM_SIZE SHA512_DIGEST_SIZE
33 * is not used in kernel, but we want to share the same header
34 * with userspace, so I put it here for compiler to shut up
36 int gettimeofday(struct timeval *, struct timezone *);
38 #include "packet.h"
40 static inline struct timespec pohmelfs_date(struct dnet_time *tm)
42 struct timespec ts;
44 ts.tv_sec = tm->tsec;
45 ts.tv_nsec = tm->tnsec;
47 return ts;
50 struct pohmelfs_cmd {
51 struct dnet_cmd cmd;
52 struct dnet_attr attr;
53 union {
54 struct dnet_io_attr io;
55 } p;
59 * Compare two IDs.
60 * Returns 1 when id1 > id2
61 * -1 when id1 < id2
62 * 0 when id1 = id2
64 static inline int dnet_id_cmp_str(const unsigned char *id1, const unsigned char *id2)
66 unsigned int i = 0;
68 for (i*=sizeof(unsigned long); i<DNET_ID_SIZE; ++i) {
69 if (id1[i] < id2[i])
70 return -1;
71 if (id1[i] > id2[i])
72 return 1;
75 return 0;
78 struct pohmelfs_state;
79 struct pohmelfs_sb;
80 struct pohmelfs_trans;
82 struct pohmelfs_trans_cb {
83 int (* init)(struct pohmelfs_trans *t);
84 int (* complete)(struct pohmelfs_trans *t, struct pohmelfs_state *recv);
85 int (* recv_reply)(struct pohmelfs_trans *t, struct pohmelfs_state *recv);
86 void (* destroy)(struct pohmelfs_trans *t);
89 struct pohmelfs_trans {
90 struct list_head trans_entry;
92 struct kref refcnt;
94 unsigned long trans;
96 struct inode *inode;
98 struct pohmelfs_state *st;
100 struct pohmelfs_cmd cmd;
102 u64 header_size, data_size;
104 void *data;
106 unsigned long long recv_offset;
107 void *recv_data;
109 struct pohmelfs_write_ctl *wctl;
110 void *priv;
112 struct pohmelfs_trans_cb cb;
115 struct pohmelfs_trans *pohmelfs_trans_alloc(struct inode *inode);
116 struct pohmelfs_trans *pohmelfs_trans_alloc_io_buf(struct inode *inode, int group, int command,
117 void *data, u64 offset, u64 size, int aflags, int ioflags, int type);
118 void pohmelfs_trans_put(struct pohmelfs_trans *t);
120 int pohmelfs_trans_insert(struct pohmelfs_trans *t);
121 struct pohmelfs_trans *pohmelfs_trans_lookup(struct pohmelfs_state *st, struct dnet_cmd *cmd);
123 struct pohmelfs_state {
124 struct pohmelfs_sb *psb;
125 struct list_head state_entry;
127 struct sockaddr_storage sa;
128 int addrlen;
129 struct socket *sock;
131 int group_id;
133 struct mutex trans_lock;
134 struct list_head trans_list;
135 struct list_head sent_trans_list;
137 struct kref refcnt;
139 int routes;
141 /* Waiting/polling machinery */
142 wait_queue_t wait;
143 wait_queue_head_t *whead;
145 struct work_struct send_work;
146 struct work_struct recv_work;
148 /* is set when dnet_cmd is being read, otherwise attached data */
149 int cmd_read;
150 /* currently read command reply */
151 struct dnet_cmd cmd;
154 struct pohmelfs_state *pohmelfs_state_create(struct pohmelfs_sb *psb, struct sockaddr_storage *sa, int addrlen,
155 int ask_route, int group_id);
156 struct pohmelfs_state *pohmelfs_state_lookup(struct pohmelfs_sb *psb, struct dnet_raw_id *id, int group);
158 static inline void pohmelfs_state_get(struct pohmelfs_state *st)
160 kref_get(&st->refcnt);
163 void pohmelfs_state_put(struct pohmelfs_state *st);
164 void pohmelfs_state_kill(struct pohmelfs_state *st);
166 struct pohmelfs_state *pohmelfs_addr_exist(struct pohmelfs_sb *psb, struct sockaddr_storage *sa, int addrlen);
168 void pohmelfs_state_schedule(struct pohmelfs_state *st);
170 __attribute__ ((format (printf, 2, 3))) void pohmelfs_print_addr(struct sockaddr_storage *addr, const char *fmt, ...);
172 #define POHMELFS_INODE_INFO_REMOVED (1<<0)
174 struct pohmelfs_inode_info {
175 struct dnet_raw_id id;
177 unsigned int mode;
178 unsigned int nlink;
179 unsigned int uid;
180 unsigned int gid;
181 unsigned int blocksize;
182 unsigned int namelen;
183 __u64 ino;
184 __u64 blocks;
185 __u64 rdev;
186 __u64 size;
187 __u64 version;
189 __u64 flags;
191 struct dnet_time ctime;
192 struct dnet_time mtime;
193 struct dnet_time atime;
194 } __attribute__ ((packed));
196 void pohmelfs_fill_inode_info(struct inode *inode, struct pohmelfs_inode_info *info);
197 void pohmelfs_fill_inode(struct inode *inode, struct pohmelfs_inode_info *info);
198 void pohmelfs_convert_inode_info(struct pohmelfs_inode_info *info);
200 struct pohmelfs_inode {
201 struct inode vfs_inode;
202 struct dnet_raw_id id;
203 struct dnet_raw_id parent_id;
205 size_t prepared_size;
206 int received;
208 struct rb_node node;
211 int pohmelfs_send_inode_info(struct pohmelfs_inode *pi, struct dnet_raw_id *id, const char *sname, int len, int sync);
212 struct pohmelfs_inode *pohmelfs_sb_inode_lookup(struct pohmelfs_sb *psb, struct dnet_raw_id *id);
215 struct pohmelfs_reconnect {
216 struct list_head reconnect_entry;
217 struct sockaddr_storage sa;
218 int addrlen;
219 int group_id;
222 int pohmelfs_state_add_reconnect(struct pohmelfs_state *st);
225 struct pohmelfs_sb {
226 struct super_block *sb;
227 struct backing_dev_info bdi;
229 struct pohmelfs_inode *root;
231 spinlock_t inode_lock;
232 struct rb_root inode_root;
234 int sync;
235 int use_http_compat;
237 int bdi_num;
239 struct rb_root route_root;
240 struct list_head state_list;
241 spinlock_t state_lock;
243 long read_wait_timeout;
244 long write_wait_timeout;
245 long sync_timeout;
247 char *fsid;
248 int fsid_len;
250 int no_read_csum;
252 atomic_long_t ino;
253 atomic_long_t trans;
255 struct crypto_hash *hash;
257 struct workqueue_struct *wq;
259 int *groups;
260 int group_num;
262 struct mutex reconnect_lock;
263 struct list_head reconnect_list;
264 struct list_head kill_state_list;
265 struct delayed_work reconnect_work;
266 long reconnect_timeout;
269 static inline struct pohmelfs_sb *pohmelfs_sb(struct super_block *sb)
271 return (struct pohmelfs_sb *)sb->s_fs_info;
274 static inline struct pohmelfs_inode *pohmelfs_inode(struct inode *inode)
276 return container_of(inode, struct pohmelfs_inode, vfs_inode);
279 struct pohmelfs_inode_info_binary_package {
280 struct dnet_raw_id parent;
281 struct pohmelfs_inode_info info;
284 struct pohmelfs_write_ctl {
285 struct pagevec pvec;
287 struct pohmelfs_sb *psb;
289 struct kref refcnt;
291 atomic_t good_writes;
294 extern struct kmem_cache *pohmelfs_inode_cache;
295 extern struct kmem_cache *pohmelfs_trans_cache;
296 extern struct kmem_cache *pohmelfs_inode_info_cache;
297 extern struct kmem_cache *pohmelfs_route_cache;
298 extern struct kmem_cache *pohmelfs_wait_cache;
299 extern struct kmem_cache *pohmelfs_io_cache;
300 extern struct kmem_cache *pohmelfs_inode_info_binary_package_cache;
301 extern struct kmem_cache *pohmelfs_write_cache;
303 struct inode *pohmelfs_alloc_inode(struct super_block *sb);
304 void pohmelfs_destroy_inode(struct inode *);
306 struct pohmelfs_inode *pohmelfs_existing_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode_info *info);
307 struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb, int mode);
308 int pohmelfs_hash(struct pohmelfs_sb *psb, const void *data, const size_t size, struct dnet_raw_id *id);
310 char *pohmelfs_dump_id(const unsigned char *id);
311 char *pohmelfs_dump_id_len_raw(const unsigned char *id, unsigned int len, char *dst);
313 int pohmelfs_write_command(struct pohmelfs_inode *pi, struct pohmelfs_write_ctl *ctl, loff_t offset, size_t len);
314 void pohmelfs_write_ctl_release(struct kref *kref);
315 int pohmelfs_metadata_inode(struct pohmelfs_inode *pi, int sync);
317 extern const struct file_operations pohmelfs_dir_fops;
318 extern const struct inode_operations pohmelfs_dir_inode_operations;
320 extern const struct file_operations pohmelfs_file_ops;
321 extern const struct inode_operations pohmelfs_file_inode_operations;
323 extern const struct inode_operations pohmelfs_symlink_inode_operations;
325 extern void *pohmelfs_scratch_buf;
326 extern int pohmelfs_scratch_buf_size;
329 * if this flag is set, pohmelfs_inode_info->data is owned by the caller,
330 * so sending path may use it on its own and free (using kfree) when it's done
332 * This logic does not work for shared buffers or
333 * when multiple transactions will be sent for single pohmelfs_inode_info
335 #define POHMELFS_IO_OWN (1<<0)
337 struct pohmelfs_io {
338 struct pohmelfs_inode *pi;
340 struct dnet_raw_id *id;
342 int cmd;
343 int type;
345 u64 offset, size;
346 u64 start, num;
348 u32 cflags;
349 u32 aflags;
350 u32 ioflags;
352 int group_id;
354 u32 alloc_flags;
355 void *data;
357 struct pohmelfs_write_ctl *wctl;
358 void *priv;
360 struct pohmelfs_trans_cb cb;
363 int pohmelfs_send_io_group(struct pohmelfs_io *pio, int group_id);
364 int pohmelfs_send_io(struct pohmelfs_io *pio);
365 int pohmelfs_send_buf_single(struct pohmelfs_io *pio, struct pohmelfs_state *st);
366 int pohmelfs_send_buf(struct pohmelfs_io *pio);
368 int pohmelfs_data_recv(struct pohmelfs_state *st, void *buf, u64 size, unsigned int flags);
369 int pohmelfs_recv(struct pohmelfs_trans *t, struct pohmelfs_state *recv, void *data, int size);
371 struct pohmelfs_route {
372 struct rb_node node;
373 int group_id;
374 struct dnet_raw_id id;
375 struct pohmelfs_state *st;
378 int pohmelfs_route_request(struct pohmelfs_state *st);
379 void pohmelfs_route_remove_all(struct pohmelfs_state *st);
381 struct pohmelfs_wait {
382 wait_queue_head_t wq;
383 struct pohmelfs_inode *pi;
384 void *ret;
385 atomic_long_t count;
386 int condition;
387 struct kref refcnt;
390 struct pohmelfs_wait *pohmelfs_wait_alloc(struct pohmelfs_inode *pi);
391 void pohmelfs_wait_put(struct pohmelfs_wait *wait);
392 static inline void pohmelfs_wait_get(struct pohmelfs_wait *wait)
394 kref_get(&wait->refcnt);
397 #endif /* __POHMELFS_H */