1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5  *  Copyright (C) 2001 Tacitus Systems, Inc.
6  *  Copyright (C) 2000 Stelias Computing, Inc.
7  *  Copyright (C) 2000 Red Hat, Inc.
8  *  Copyright (C) 2000 TurboLinux, Inc.
9  *  Copyright (C) 2000 Los Alamos National Laboratory.
10  *
11  *   This file is part of InterMezzo, http://www.inter-mezzo.org.
12  *
13  *   InterMezzo is free software; you can redistribute it and/or
14  *   modify it under the terms of version 2 of the GNU General Public
15  *   License as published by the Free Software Foundation.
16  *
17  *   InterMezzo is distributed in the hope that it will be useful,
18  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *   GNU General Public License for more details.
21  *
22  *   You should have received a copy of the GNU General Public License
23  *   along with InterMezzo; if not, write to the Free Software
24  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26 
27 #ifndef __INTERMEZZO_FS_H_
28 #define __INTERMEZZO_FS_H_ 1
29 
30 #include <linux/intermezzo_lib.h>
31 #include <linux/intermezzo_idl.h>
32 
33 
34 #ifdef __KERNEL__
35 typedef __u8 uuid_t[16];
36 #else
37 # include <uuid/uuid.h>
38 #endif
39 
40 struct lento_vfs_context {
41         __u64 kml_offset;
42         __u64 updated_time;
43         __u64 remote_ino;
44         __u64 remote_generation;
45         __u32 slot_offset;
46         __u32 recno;
47         __u32 flags;
48         uuid_t uuid;
49         struct presto_version remote_version;
50 };
51 
52 #ifdef __KERNEL__
53 # include <linux/smp.h>
54 # include <linux/fsfilter.h>
55 # include <linux/slab.h>
56 # include <linux/vmalloc.h>
57 # include <linux/smp_lock.h>
58 
59 /* fixups for fs.h */
60 # ifndef fs_down
61 #  define fs_down(sem) down(sem)
62 # endif
63 
64 # ifndef fs_up
65 #  define fs_up(sem) up(sem)
66 # endif
67 
68 # define KML_IDLE                        0
69 # define KML_DECODE                      1
70 # define KML_OPTIMIZE                    2
71 # define KML_REINT                       3
72 
73 # define KML_OPEN_REINT                  0x0100
74 # define KML_REINT_BEGIN                 0x0200
75 # define KML_BACKFETCH                   0x0400
76 # define KML_REINT_END                   0x0800
77 # define KML_CLOSE_REINT                 0x1000
78 # define KML_REINT_MAXBUF                (64 * 1024)
79 
80 # define CACHE_CLIENT_RO       0x4
81 # define CACHE_LENTO_RO        0x8
82 
83 /* global variables */
84 extern int presto_debug;
85 extern int presto_print_entry;
86 extern long presto_kmemory;
87 extern long presto_vmemory;
88 
89 # define PRESTO_DEBUG
90 # ifdef PRESTO_DEBUG
91 /* debugging masks */
92 #  define D_SUPER       1
93 #  define D_INODE       2
94 #  define D_FILE        4
95 #  define D_CACHE       8  /* cache debugging */
96 #  define D_MALLOC     16  /* print malloc, de-alloc information */
97 #  define D_JOURNAL    32
98 #  define D_UPCALL     64  /* up and downcall debugging */
99 #  define D_PSDEV     128
100 #  define D_PIOCTL    256
101 #  define D_SPECIAL   512
102 #  define D_TIMING   1024
103 #  define D_DOWNCALL 2048
104 #  define D_KML      4096
105 #  define D_FSDATA   8192
106 
107 #  define CDEBUG(mask, format, a...)                                    \
108         do {                                                            \
109                 if (presto_debug & mask) {                              \
110                         printk("(%s:%s,l. %d %d): " format, __FILE__,   \
111                                __FUNCTION__, __LINE__, current->pid     \
112                                , ## a);                                 \
113                 }                                                       \
114         } while (0)
115 
116 #define CERROR(format, a...)                                            \
117 do {                                                                    \
118         printk("(%s:%s,l. %d %d): " format, __FILE__, __FUNCTION__,     \
119                __LINE__, current->pid , ## a);                          \
120 } while (0)
121 
122 #  define ENTRY                                                         \
123         if (presto_print_entry)                                         \
124                 printk("Process %d entered %s\n", current->pid, __FUNCTION__)
125 
126 #  define EXIT                                                          \
127         if (presto_print_entry)                                         \
128                 printk("Process %d leaving %s at %d\n", current->pid,   \
129                        __FUNCTION__, __LINE__)
130 
131 #  define presto_kmem_inc(ptr, size) presto_kmemory += (size)
132 #  define presto_kmem_dec(ptr, size) presto_kmemory -= (size)
133 #  define presto_vmem_inc(ptr, size) presto_vmemory += (size)
134 #  define presto_vmem_dec(ptr, size) presto_vmemory -= (size)
135 # else /* !PRESTO_DEBUG */
136 #  define CDEBUG(mask, format, a...) do {} while (0)
137 #  define ENTRY do {} while (0)
138 #  define EXIT do {} while (0)
139 #  define presto_kmem_inc(ptr, size) do {} while (0)
140 #  define presto_kmem_dec(ptr, size) do {} while (0)
141 #  define presto_vmem_inc(ptr, size) do {} while (0)
142 #  define presto_vmem_dec(ptr, size) do {} while (0)
143 # endif /* PRESTO_DEBUG */
144 
145 
146 struct run_ctxt {
147         struct vfsmount *pwdmnt;
148         struct dentry   *pwd;
149         struct vfsmount *rootmnt;
150         struct dentry   *root;
151         uid_t            fsuid;
152         gid_t            fsgid;
153         mm_segment_t     fs;
154 	int              ngroups;
155 	gid_t	         groups[NGROUPS];
156 
157 };
158 
push_ctxt(struct run_ctxt * save,struct run_ctxt * new)159 static inline void push_ctxt(struct run_ctxt *save, struct run_ctxt *new)
160 {
161         int i;
162         save->fs = get_fs();
163         save->pwd = dget(current->fs->pwd);
164         save->pwdmnt = mntget(current->fs->pwdmnt);
165         save->fsgid = current->fsgid;
166         save->fsuid = current->fsuid;
167         save->root = current->fs->root;
168         save->rootmnt = current->fs->rootmnt;
169         save->ngroups = current->ngroups;
170         for (i = 0; i< current->ngroups; i++)
171                 save->groups[i] = current->groups[i];
172 
173         set_fs(new->fs);
174         lock_kernel();
175         set_fs_pwd(current->fs, new->pwdmnt, new->pwd);
176         if (new->root)
177                 set_fs_root(current->fs, new->rootmnt, new->root);
178         unlock_kernel();
179         current->fsuid = new->fsuid;
180         current->fsgid = new->fsgid;
181         if (new->ngroups > 0) {
182                 current->ngroups = new->ngroups;
183                 for (i = 0; i< new->ngroups; i++)
184                         current->groups[i] = new->groups[i];
185         }
186 
187 }
188 
pop_ctxt(struct run_ctxt * saved)189 static inline void pop_ctxt(struct run_ctxt *saved)
190 {
191         int i;
192 
193         set_fs(saved->fs);
194         lock_kernel();
195         set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd);
196         if (saved->root)
197                 set_fs_root(current->fs, saved->rootmnt, saved->root);
198         unlock_kernel();
199         current->fsuid = saved->fsuid;
200         current->fsgid = saved->fsgid;
201         current->ngroups = saved->ngroups;
202         for (i = 0; i< saved->ngroups; i++)
203                 current->groups[i] = saved->groups[i];
204 
205         mntput(saved->pwdmnt);
206         dput(saved->pwd);
207 }
208 
presto_d2d(struct dentry * dentry)209 static inline struct presto_dentry_data *presto_d2d(struct dentry *dentry)
210 {
211         return (struct presto_dentry_data *)(dentry->d_fsdata);
212 }
213 
214 struct presto_cache {
215         spinlock_t          cache_lock;
216         loff_t              cache_reserved;
217         struct  vfsmount   *cache_vfsmount;
218         struct super_block *cache_sb;
219         struct  dentry     *cache_root;
220         struct list_head    cache_chain; /* for the dev/cache hash */
221 
222         int   cache_flags;
223 
224         kdev_t cache_dev;            /* underlying block device */
225 
226         char *cache_type;            /* filesystem type of cache */
227         struct filter_fs *cache_filter;
228 
229         struct upc_channel *cache_psdev;  /* points to channel used */
230         struct list_head cache_channel_list;
231         struct list_head cache_fset_list; /* filesets mounted in cache */
232 };
233 
234 struct presto_log_fd {
235         rwlock_t         fd_lock;
236         loff_t           fd_offset;  /* offset where next record should go */
237         struct file    *fd_file;
238         int             fd_truncating;
239         unsigned int   fd_recno;   /* last recno written */
240         struct list_head  fd_reservations;
241 };
242 
243 /* file sets */
244 # define CHUNK_BITS  16
245 
246 struct presto_file_set {
247         struct list_head fset_list;
248         struct presto_log_fd fset_kml;
249         struct presto_log_fd fset_lml;
250         struct presto_log_fd fset_rcvd;
251         struct list_head *fset_clients;  /* cache of clients */
252         struct dentry *fset_dentry;
253         struct vfsmount *fset_mnt;
254         struct presto_cache *fset_cache;
255 
256         unsigned int fset_lento_recno;  /* last recno mentioned to lento */
257         loff_t fset_lento_off;    /* last offset mentioned to lento */
258         loff_t fset_kml_logical_off; /* logical offset of kml file byte 0 */
259         char * fset_name;
260 
261         int fset_flags;
262         int fset_chunkbits;
263         char *fset_reint_buf; /* temporary buffer holds kml during reint */
264 
265         spinlock_t fset_permit_lock;
266         int fset_permit_count;
267         int fset_permit_upcall_count;
268         /* This queue is used both for processes waiting for the kernel to give
269          * up the permit as well as processes waiting for the kernel to be given
270          * the permit, depending on the state of FSET_HASPERMIT. */
271         wait_queue_head_t fset_permit_queue;
272 
273         loff_t  fset_file_maxio;  /* writing more than this causes a close */
274         unsigned long int kml_truncate_size;
275 };
276 
277 /* This is the default number of bytes written before a close is recorded*/
278 #define FSET_DEFAULT_MAX_FILEIO (1024<<10)
279 
280 struct dentry *presto_tmpfs_ilookup(struct inode *dir, struct dentry *dentry,
281                                     ino_t ino, unsigned int generation);
282 struct dentry *presto_iget_ilookup(struct inode *dir, struct dentry *dentry,
283                                     ino_t ino, unsigned int generation);
284 struct dentry *presto_add_ilookup_dentry(struct dentry *parent,
285                                          struct dentry *real);
286 
287 struct journal_ops {
288         int (*tr_all_data)(struct inode *);
289         loff_t (*tr_avail)(struct presto_cache *fset, struct super_block *);
290         void *(*tr_start)(struct presto_file_set *, struct inode *, int op);
291         void (*tr_commit)(struct presto_file_set *, void *handle);
292         void (*tr_journal_data)(struct inode *);
293         struct dentry *(*tr_ilookup)(struct inode *dir, struct dentry *dentry, ino_t ino, unsigned int generation);
294         struct dentry *(*tr_add_ilookup)(struct dentry *parent, struct dentry *real);
295 };
296 
297 extern struct journal_ops presto_ext2_journal_ops;
298 extern struct journal_ops presto_ext3_journal_ops;
299 extern struct journal_ops presto_tmpfs_journal_ops;
300 extern struct journal_ops presto_xfs_journal_ops;
301 extern struct journal_ops presto_reiserfs_journal_ops;
302 extern struct journal_ops presto_obdfs_journal_ops;
303 
304 # define LENTO_FL_KML            0x0001
305 # define LENTO_FL_EXPECT         0x0002
306 # define LENTO_FL_VFSCHECK       0x0004
307 # define LENTO_FL_JUSTLOG        0x0008
308 # define LENTO_FL_WRITE_KML      0x0010
309 # define LENTO_FL_CANCEL_LML     0x0020
310 # define LENTO_FL_WRITE_EXPECT   0x0040
311 # define LENTO_FL_IGNORE_TIME    0x0080
312 # define LENTO_FL_TOUCH_PARENT   0x0100
313 # define LENTO_FL_TOUCH_NEWOBJ   0x0200
314 # define LENTO_FL_SET_DDFILEID   0x0400
315 
316 struct presto_cache *presto_get_cache(struct inode *inode);
317 int presto_sprint_mounts(char *buf, int buflen, int minor);
318 struct presto_file_set *presto_fset(struct dentry *de);
319 int presto_journal(struct dentry *dentry, char *buf, size_t size);
320 int presto_fwrite(struct file *file, const char *str, int len, loff_t *off);
321 int presto_ispresto(struct inode *);
322 
323 /* super.c */
324 extern int init_intermezzo_fs(void);
325 
326 /* fileset.c */
327 extern int izo_prepare_fileset(struct dentry *root, char *fsetname);
328 char * izo_make_path(struct presto_file_set *fset, char *name);
329 struct file *izo_fset_open(struct presto_file_set *fset, char *name, int flags, int mode);
330 
331 /* psdev.c */
332 int izo_psdev_get_free_channel(void);
333 int presto_psdev_init(void);
334 int izo_psdev_setpid(int minor);
335 extern void presto_psdev_cleanup(void);
336 int presto_lento_up(int minor);
337 int izo_psdev_setchannel(struct file *file, int fd);
338 
339 /* inode.c */
340 extern struct super_operations presto_super_ops;
341 void presto_set_ops(struct inode *inode, struct  filter_fs *filter);
342 
343 /* dcache.c */
344 void presto_frob_dop(struct dentry *de);
345 char *presto_path(struct dentry *dentry, struct dentry *root,
346                   char *buffer, int buflen);
347 struct presto_dentry_data *izo_alloc_ddata(void);
348 int presto_set_dd(struct dentry *);
349 int presto_init_ddata_cache(void);
350 void presto_cleanup_ddata_cache(void);
351 extern struct dentry_operations presto_dentry_ops;
352 
353 /* dir.c */
354 extern struct inode_operations presto_dir_iops;
355 extern struct inode_operations presto_file_iops;
356 extern struct inode_operations presto_sym_iops;
357 extern struct file_operations presto_dir_fops;
358 extern struct file_operations presto_file_fops;
359 extern struct file_operations presto_sym_fops;
360 int presto_setattr(struct dentry *de, struct iattr *iattr);
361 int presto_settime(struct presto_file_set *fset, struct dentry *newobj,
362                    struct dentry *parent, struct dentry *target,
363                    struct lento_vfs_context *ctx, int valid);
364 int presto_ioctl(struct inode *inode, struct file *file,
365                  unsigned int cmd, unsigned long arg);
366 
367 extern int presto_ilookup_uid;
368 # define PRESTO_ILOOKUP_MAGIC "...ino:"
369 # define PRESTO_ILOOKUP_SEP ':'
370 int izo_dentry_is_ilookup(struct dentry *, ino_t *id, unsigned int *generation);
371 struct dentry *presto_lookup(struct inode * dir, struct dentry *dentry);
372 
373 struct presto_dentry_data {
374         int dd_count; /* how mnay dentries are using this dentry */
375         struct presto_file_set *dd_fset;
376         struct dentry *dd_inodentry;
377         loff_t dd_kml_offset;
378         int dd_flags;
379         __u64 remote_ino;
380         __u64 remote_generation;
381 };
382 
383 struct presto_file_data {
384         int fd_do_lml;
385         loff_t fd_lml_offset;
386         size_t fd_bytes_written;
387         /* authorization related data of file at open time */
388         uid_t fd_uid;
389         gid_t fd_gid;
390         mode_t fd_mode;
391         /* identification data of calling process */
392         uid_t fd_fsuid;
393         gid_t fd_fsgid;
394         int fd_ngroups;
395         gid_t fd_groups[NGROUPS_MAX];
396         /* information how to complete the close operation */
397         struct lento_vfs_context fd_info;
398         struct presto_version fd_version;
399 };
400 
401 /* presto.c and Lento::Downcall */
402 
403 int presto_walk(const char *name, struct nameidata *nd);
404 int izo_clear_fsetroot(struct dentry *dentry);
405 int izo_clear_all_fsetroots(struct presto_cache *cache);
406 int presto_get_kmlsize(char *path, __u64 *size);
407 int presto_get_lastrecno(char *path, off_t *size);
408 int presto_set_fsetroot(struct dentry *dentry, char *fsetname,
409                        unsigned int flags);
410 int presto_set_fsetroot_from_ioc(struct dentry *dentry, char *fsetname,
411                                  unsigned int flags);
412 int presto_is_read_only(struct presto_file_set *);
413 int presto_truncate_lml(struct presto_file_set *fset);
414 int lento_write_lml(char *path,
415                      __u64 remote_ino,
416                      __u32 remote_generation,
417                      __u32 remote_version,
418                     struct presto_version *remote_file_version);
419 int lento_complete_closes(char *path);
420 int presto_f2m(struct presto_file_set *fset);
421 int presto_prep(struct dentry *, struct presto_cache **,
422                        struct presto_file_set **);
423 /* cache.c */
424 extern struct presto_cache *presto_cache_init(void);
425 extern void presto_cache_add(struct presto_cache *cache, kdev_t dev);
426 extern void presto_cache_init_hash(void);
427 
428 struct presto_cache *presto_cache_find(kdev_t dev);
429 
430 #define PRESTO_REQLOW  (3 * 4096)
431 #define PRESTO_REQHIGH (6 * 4096)
432 void presto_release_space(struct presto_cache *cache, loff_t req);
433 int presto_reserve_space(struct presto_cache *cache, loff_t req);
434 
435 #define PRESTO_DATA             0x00000002 /* cached data is valid */
436 #define PRESTO_ATTR             0x00000004 /* attributes cached */
437 #define PRESTO_DONT_JOURNAL     0x00000008 /* things like .intermezzo/ */
438 
439 struct presto_file_set *presto_path2fileset(const char *name);
440 int izo_revoke_permit(struct dentry *, uuid_t uuid);
441 int presto_chk(struct dentry *dentry, int flag);
442 void presto_set(struct dentry *dentry, int flag);
443 int presto_get_permit(struct inode *inode);
444 int presto_put_permit(struct inode *inode);
445 int presto_set_max_kml_size(const char *path, unsigned long max_size);
446 int izo_mark_dentry(struct dentry *dentry, int and, int or, int *res);
447 int izo_mark_cache(struct dentry *dentry, int and_bits, int or_bits, int *);
448 int izo_mark_fset(struct dentry *dentry, int and_bits, int or_bits, int *);
449 void presto_getversion(struct presto_version *pv, struct inode *inode);
450 int presto_i2m(struct inode *inode);
451 int presto_c2m(struct presto_cache *cache);
452 
453 
454 /* file.c */
455 int izo_purge_file(struct presto_file_set *fset, char *file);
456 int presto_adjust_lml(struct file *file, struct lento_vfs_context *info);
457 
458 /* journal.c */
459 struct rec_info {
460         loff_t offset;
461         int size;
462         int recno;
463         int is_kml;
464 };
465 
466 void presto_trans_commit(struct presto_file_set *fset, void *handle);
467 void *presto_trans_start(struct presto_file_set *fset, struct inode *inode,
468                          int op);
469 int presto_fread(struct file *file, char *str, int len, loff_t *off);
470 int presto_clear_lml_close(struct presto_file_set *fset,
471                            loff_t  lml_offset);
472 int presto_complete_lml(struct presto_file_set *fset);
473 int presto_read_kml_logical_offset(struct rec_info *recinfo,
474                                    struct presto_file_set *fset);
475 int presto_write_kml_logical_offset(struct presto_file_set *fset);
476 struct file *presto_copy_kml_tail(struct presto_file_set *fset,
477                                   unsigned long int start);
478 int presto_finish_kml_truncate(struct presto_file_set *fset,
479                                unsigned long int offset);
480 int izo_lookup_file(struct presto_file_set *fset, char *path,
481                     struct nameidata *nd);
482 int izo_do_truncate(struct presto_file_set *fset, struct dentry *dentry,
483                     loff_t length,  loff_t size_check);
484 int izo_log_close(struct presto_log_fd *logfd);
485 struct file *izo_log_open(struct presto_file_set *fset, char *name, int flags);
486 int izo_init_kml_file(struct presto_file_set *, struct presto_log_fd *);
487 int izo_init_lml_file(struct presto_file_set *, struct presto_log_fd *);
488 int izo_init_last_rcvd_file(struct presto_file_set *, struct presto_log_fd *);
489 
490 /* vfs.c */
491 
492 /* Extra data needed in the KML for rollback operations; this structure is
493  * passed around during the KML-writing process. */
494 struct izo_rollback_data {
495         __u32 rb_mode;
496         __u32 rb_rdev;
497         __u64 rb_uid;
498         __u64 rb_gid;
499 };
500 
501 int presto_write_last_rcvd(struct rec_info *recinfo,
502                            struct presto_file_set *fset,
503                            struct lento_vfs_context *info);
504 void izo_get_rollback_data(struct inode *inode, struct izo_rollback_data *rb);
505 int presto_do_close(struct presto_file_set *fset, struct file *file);
506 int presto_do_setattr(struct presto_file_set *fset, struct dentry *dentry,
507                       struct iattr *iattr, struct lento_vfs_context *info);
508 int presto_do_create(struct presto_file_set *fset, struct dentry *dir,
509                      struct dentry *dentry, int mode,
510                      struct lento_vfs_context *info);
511 int presto_do_link(struct presto_file_set *fset, struct dentry *dir,
512                    struct dentry *old_dentry, struct dentry *new_dentry,
513                    struct lento_vfs_context *info);
514 int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,
515                      struct dentry *dentry, struct lento_vfs_context *info);
516 int presto_do_symlink(struct presto_file_set *fset, struct dentry *dir,
517                       struct dentry *dentry, const char *name,
518                       struct lento_vfs_context *info);
519 int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir,
520                     struct dentry *dentry, int mode,
521                     struct lento_vfs_context *info);
522 int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir,
523                     struct dentry *dentry, struct lento_vfs_context *info);
524 int presto_do_mknod(struct presto_file_set *fset, struct dentry *dir,
525                     struct dentry *dentry, int mode, dev_t dev,
526                     struct lento_vfs_context *info);
527 int do_rename(struct presto_file_set *fset, struct dentry *old_dir,
528               struct dentry *old_dentry, struct dentry *new_dir,
529               struct dentry *new_dentry, struct lento_vfs_context *info);
530 int presto_do_statfs (struct presto_file_set *fset,
531                       struct statfs * buf);
532 
533 int lento_setattr(const char *name, struct iattr *iattr,
534                   struct lento_vfs_context *info);
535 int lento_create(const char *name, int mode, struct lento_vfs_context *info);
536 int lento_link(const char *oldname, const char *newname,
537                struct lento_vfs_context *info);
538 int lento_unlink(const char *name, struct lento_vfs_context *info);
539 int lento_symlink(const char *oldname,const char *newname,
540                   struct lento_vfs_context *info);
541 int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info);
542 int lento_rmdir(const char *name, struct lento_vfs_context *info);
543 int lento_mknod(const char *name, int mode, dev_t dev,
544                 struct lento_vfs_context *info);
545 int lento_rename(const char *oldname, const char *newname,
546                  struct lento_vfs_context *info);
547 int lento_iopen(const char *name, ino_t ino, unsigned int generation,int flags);
548 
549 /* journal.c */
550 
551 #define JOURNAL_PAGE_SZ  PAGE_SIZE
552 
553 int presto_no_journal(struct presto_file_set *fset);
554 int journal_fetch(int minor);
555 int presto_log(struct presto_file_set *fset, struct rec_info *rec,
556                const char *buf, size_t size,
557                const char *string1, int len1,
558                const char *string2, int len2,
559                const char *string3, int len3);
560 int presto_get_fileid(int minor, struct presto_file_set *fset,
561                       struct dentry *dentry);
562 int presto_journal_setattr(struct rec_info *rec, struct presto_file_set *fset,
563                            struct dentry *dentry, struct presto_version *old_ver,
564                            struct izo_rollback_data *, struct iattr *iattr);
565 int presto_journal_create(struct rec_info *rec, struct presto_file_set *fset,
566                           struct dentry *dentry,
567                           struct presto_version *tgt_dir_ver,
568                           struct presto_version *new_file_ver, int mode);
569 int presto_journal_link(struct rec_info *rec, struct presto_file_set *fset,
570                         struct dentry *src, struct dentry *tgt,
571                         struct presto_version *tgt_dir_ver,
572                         struct presto_version *new_link_ver);
573 int presto_journal_unlink(struct rec_info *rec, struct presto_file_set *fset,
574                           struct dentry *dir,
575                           struct presto_version *tgt_dir_ver,
576                           struct presto_version *old_file_ver,
577                           struct izo_rollback_data *, struct dentry *dentry,
578                           char *old_target, int old_targetlen);
579 int presto_journal_symlink(struct rec_info *rec, struct presto_file_set *fset,
580                            struct dentry *dentry, const char *target,
581                            struct presto_version *tgt_dir_ver,
582                            struct presto_version *new_link_ver);
583 int presto_journal_mkdir(struct rec_info *rec, struct presto_file_set *fset,
584                          struct dentry *dentry,
585                          struct presto_version *tgt_dir_ver,
586                          struct presto_version *new_dir_ver, int mode);
587 int presto_journal_rmdir(struct rec_info *rec, struct presto_file_set *fset,
588                          struct dentry *dentry,
589                          struct presto_version *tgt_dir_ver,
590                          struct presto_version *old_dir_ver,
591                          struct izo_rollback_data *, int len, const char *name);
592 int presto_journal_mknod(struct rec_info *rec, struct presto_file_set *fset,
593                          struct dentry *dentry,
594                          struct presto_version *tgt_dir_ver,
595                          struct presto_version *new_node_ver, int mode,
596                          int dmajor, int dminor);
597 int presto_journal_rename(struct rec_info *rec, struct presto_file_set *fset,
598                           struct dentry *src, struct dentry *tgt,
599                           struct presto_version *src_dir_ver,
600                           struct presto_version *tgt_dir_ver);
601 int presto_journal_open(struct rec_info *, struct presto_file_set *,
602                         struct dentry *, struct presto_version *old_ver);
603 int presto_journal_close(struct rec_info *rec, struct presto_file_set *,
604                          struct file *, struct dentry *,
605                          struct presto_version *old_file_ver,
606                          struct presto_version *new_file_ver);
607 int presto_write_lml_close(struct rec_info *rec,
608                            struct presto_file_set *fset,
609                            struct file *file,
610                            __u64 remote_ino,
611                            __u64 remote_generation,
612                            struct presto_version *remote_version,
613                            struct presto_version *new_file_ver);
614 void presto_log_op(void *data, int len);
615 loff_t presto_kml_offset(struct presto_file_set *fset);
616 
617 /* upcall.c */
618 #define SYNCHRONOUS 0
619 #define ASYNCHRONOUS 1
620 /* asynchronous calls */
621 int izo_upc_kml(int minor, __u64 offset, __u32 first_recno, __u64 length,
622                 __u32 last_recno, char *fsetname);
623 int izo_upc_kml_truncate(int minor, __u64 length, __u32 last_recno,
624                          char *fsetname);
625 int izo_upc_go_fetch_kml(int minor, char *fsetname, uuid_t uuid, __u64 kmlsize);
626 int izo_upc_backfetch(int minor, char *path, char *fileset,
627                       struct lento_vfs_context *);
628 
629 /* synchronous calls */
630 int izo_upc_get_fileid(int minor, __u32 reclen, char *rec,
631                        __u32 pathlen, char *path, char *fsetname);
632 int izo_upc_permit(int minor, struct dentry *, __u32 pathlen, char *path,
633                    char *fset);
634 int izo_upc_open(int minor, __u32 pathlen, char *path, char *fsetname,
635                  struct lento_vfs_context *info);
636 int izo_upc_connect(int minor, __u64 ip_address, __u64 port, __u8 uuid[16],
637                     int client_flag);
638 int izo_upc_revoke_permit(int minor, char *fsetname, uuid_t uuid);
639 int izo_upc_set_kmlsize(int minor, char *fsetname, uuid_t uuid, __u64 kmlsize);
640 int izo_upc_client_make_branch(int minor, char *fsetname);
641 int izo_upc_server_make_branch(int minor, char *fsetname);
642 int izo_upc_branch_undo(int minor, char *fsetname, char *branchname);
643 int izo_upc_branch_redo(int minor, char *fsetname, char *branchname);
644 int izo_upc_repstatus(int minor,  char * fsetname, struct izo_rcvd_rec *lr_server);
645 
646 /* general mechanism */
647 int izo_upc_upcall(int minor, int *size, struct izo_upcall_hdr *, int async);
648 
649 /* replicator.c */
650 int izo_repstatus(struct presto_file_set *fset, __u64 client_kmlsize,
651                   struct izo_rcvd_rec *lr_client, struct izo_rcvd_rec *lr_server);
652 int izo_rep_cache_init(struct presto_file_set *);
653 void izo_rep_cache_clean(struct presto_file_set *fset);
654 loff_t izo_rcvd_get(struct izo_rcvd_rec *, struct presto_file_set *, char *uuid);
655 loff_t izo_rcvd_write(struct presto_file_set *, struct izo_rcvd_rec *);
656 loff_t izo_rcvd_upd_remote(struct presto_file_set *fset, char * uuid,  __u64 remote_recno,
657                            __u64 remote_offset);
658 
659 int izo_ioctl_packlen(struct izo_ioctl_data *data);
660 
661 /* sysctl.c */
662 int init_intermezzo_sysctl(void);
663 void cleanup_intermezzo_sysctl(void);
664 
665 /* ext_attr.c */
666 /* We will be more tolerant than the default ea patch with attr name sizes and
667  * the size of value. If these come via VFS from the default ea patches, the
668  * corresponding character strings will be truncated anyway. During journalling- * we journal length for both name and value. See journal_set_ext_attr.
669  */
670 #define PRESTO_EXT_ATTR_NAME_MAX 128
671 #define PRESTO_EXT_ATTR_VALUE_MAX 8192
672 
673 #define PRESTO_ALLOC(ptr, size)                                         \
674 do {                                                                    \
675         long s = (size);                                                \
676         (ptr) = kmalloc(s, GFP_KERNEL);                                 \
677         if ((ptr) == NULL)                                              \
678                 CERROR("IZO: out of memory at %s:%d (trying to "        \
679                        "allocate %ld)\n", __FILE__, __LINE__, s);       \
680         else {                                                          \
681                 presto_kmem_inc((ptr), s);                              \
682                 memset((ptr), 0, s);                                    \
683         }                                                               \
684         CDEBUG(D_MALLOC, "kmalloced: %ld at %p (tot %ld).\n",           \
685                s, (ptr), presto_kmemory);                               \
686 } while (0)
687 
688 #define PRESTO_FREE(ptr, size)                                          \
689 do {                                                                    \
690         long s = (size);                                                \
691         if ((ptr) == NULL) {                                            \
692                 CERROR("IZO: free NULL pointer (%ld bytes) at "         \
693                        "%s:%d\n", s, __FILE__, __LINE__);               \
694                 break;                                                  \
695         }                                                               \
696         kfree(ptr);                                                     \
697         CDEBUG(D_MALLOC, "kfreed: %ld at %p (tot %ld).\n",              \
698                s, (ptr), presto_kmemory);                               \
699         presto_kmem_dec((ptr), s);                                      \
700 } while (0)
701 
dentry_name_cmp(struct dentry * dentry,char * name)702 static inline int dentry_name_cmp(struct dentry *dentry, char *name)
703 {
704         return (strlen(name) == dentry->d_name.len &&
705                 memcmp(name, dentry->d_name.name, dentry->d_name.len) == 0);
706 }
707 
strdup(char * str)708 static inline char *strdup(char *str)
709 {
710         char *tmp;
711 		long int s;
712 
713 		s=strlen(str) + 1;
714         tmp = kmalloc(s, GFP_KERNEL);
715         if (tmp){
716 				  memcpy(tmp, str, s);
717 				  presto_kmem_inc(tmp, s);
718 		}
719         CDEBUG(D_MALLOC, "kmalloced: %ld at %p (tot %ld).\n",
720                s, tmp, presto_kmemory);
721 
722         return tmp;
723 }
724 
izo_ioctl_is_invalid(struct izo_ioctl_data * data)725 static inline int izo_ioctl_is_invalid(struct izo_ioctl_data *data)
726 {
727         if (data->ioc_len > (1<<30)) {
728                 CERROR("IZO ioctl: ioc_len larger than 1<<30\n");
729                 return 1;
730         }
731         if (data->ioc_inllen1 > (1<<30)) {
732                 CERROR("IZO ioctl: ioc_inllen1 larger than 1<<30\n");
733                 return 1;
734         }
735         if (data->ioc_inllen2 > (1<<30)) {
736                 CERROR("IZO ioctl: ioc_inllen2 larger than 1<<30\n");
737                 return 1;
738         }
739         if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
740                 CERROR("IZO ioctl: inlbuf1 pointer but 0 length\n");
741                 return 1;
742         }
743         if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
744                 CERROR("IZO ioctl: inlbuf2 pointer but 0 length\n");
745                 return 1;
746         }
747         if (data->ioc_pbuf1 && !data->ioc_plen1) {
748                 CERROR("IZO ioctl: pbuf1 pointer but 0 length\n");
749                 return 1;
750         }
751         if (data->ioc_pbuf2 && !data->ioc_plen2) {
752                 CERROR("IZO ioctl: pbuf2 pointer but 0 length\n");
753                 return 1;
754         }
755         if (izo_ioctl_packlen(data) != data->ioc_len ) {
756                 CERROR("IZO ioctl: packlen exceeds ioc_len\n");
757                 return 1;
758         }
759         if (data->ioc_inllen1 &&
760             data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
761                 CERROR("IZO ioctl: inlbuf1 not 0 terminated\n");
762                 return 1;
763         }
764         if (data->ioc_inllen2 &&
765             data->ioc_bulk[size_round(data->ioc_inllen1) + data->ioc_inllen2
766                            - 1] != '\0') {
767                 CERROR("IZO ioctl: inlbuf2 not 0 terminated\n");
768                 return 1;
769         }
770         return 0;
771 }
772 
773 /* buffer MUST be at least the size of izo_ioctl_hdr */
izo_ioctl_getdata(char * buf,char * end,void * arg)774 static inline int izo_ioctl_getdata(char *buf, char *end, void *arg)
775 {
776         struct izo_ioctl_hdr *hdr;
777         struct izo_ioctl_data *data;
778         int err;
779         ENTRY;
780 
781         hdr = (struct izo_ioctl_hdr *)buf;
782         data = (struct izo_ioctl_data *)buf;
783 
784         err = copy_from_user(buf, (void *)arg, sizeof(*hdr));
785         if ( err ) {
786                 EXIT;
787                 return err;
788         }
789 
790         if (hdr->ioc_version != IZO_IOCTL_VERSION) {
791                 CERROR("IZO: version mismatch kernel vs application\n");
792                 return -EINVAL;
793         }
794 
795         if (hdr->ioc_len + buf >= end) {
796                 CERROR("IZO: user buffer exceeds kernel buffer\n");
797                 return -EINVAL;
798         }
799 
800         if (hdr->ioc_len < sizeof(struct izo_ioctl_data)) {
801                 CERROR("IZO: user buffer too small for ioctl\n");
802                 return -EINVAL;
803         }
804 
805         err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
806         if ( err ) {
807                 EXIT;
808                 return err;
809         }
810 
811         if (izo_ioctl_is_invalid(data)) {
812                 CERROR("IZO: ioctl not correctly formatted\n");
813                 return -EINVAL;
814         }
815 
816         if (data->ioc_inllen1) {
817                 data->ioc_inlbuf1 = &data->ioc_bulk[0];
818         }
819 
820         if (data->ioc_inllen2) {
821                 data->ioc_inlbuf2 = &data->ioc_bulk[0] +
822                         size_round(data->ioc_inllen1);
823         }
824 
825         EXIT;
826         return 0;
827 }
828 
829 # define MYPATHLEN(buffer, path) ((buffer) + PAGE_SIZE - (path))
830 
831 # define free kfree
832 # define malloc(a) kmalloc(a, GFP_KERNEL)
833 # define printf printk
834 int kml_reint_rec(struct file *dir, struct izo_ioctl_data *data);
835 int izo_get_fileid(struct file *dir, struct izo_ioctl_data *data);
836 int izo_set_fileid(struct file *dir, struct izo_ioctl_data *data);
837 
838 #else /* __KERNEL__ */
839 # include <stdlib.h>
840 # include <stdio.h>
841 # include <sys/types.h>
842 # include <sys/ioctl.h>
843 # include <string.h>
844 
845 # define printk printf
846 # ifndef CERROR
847 #   define CERROR printf
848 # endif
849 # define kmalloc(a,b) malloc(a)
850 
851 void init_fsreintdata (void);
852 int kml_fsreint(struct kml_rec *rec, char *basedir);
853 int kml_iocreint(__u32 size, char *ptr, __u32 offset, int dird,
854                  uuid_t uuid, __u32 generate_kml);
855 
izo_ioctl_init(struct izo_ioctl_data * data)856 static inline void izo_ioctl_init(struct izo_ioctl_data *data)
857 {
858         memset(data, 0, sizeof(*data));
859         data->ioc_len = sizeof(*data);
860         data->ioc_version = IZO_IOCTL_VERSION;
861 }
862 
863 static inline int
izo_ioctl_pack(struct izo_ioctl_data * data,char ** pbuf,int max)864 izo_ioctl_pack(struct izo_ioctl_data *data, char **pbuf, int max)
865 {
866         char *ptr;
867         struct izo_ioctl_data *overlay;
868         data->ioc_len = izo_ioctl_packlen(data);
869         data->ioc_version = IZO_IOCTL_VERSION;
870 
871         if (*pbuf && izo_ioctl_packlen(data) > max)
872                 return 1;
873         if (*pbuf == NULL)
874                 *pbuf = malloc(data->ioc_len);
875         if (*pbuf == NULL)
876                 return 1;
877         overlay = (struct izo_ioctl_data *)*pbuf;
878         memcpy(*pbuf, data, sizeof(*data));
879 
880         ptr = overlay->ioc_bulk;
881         if (data->ioc_inlbuf1)
882                 LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
883         if (data->ioc_inlbuf2)
884                 LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
885         if (izo_ioctl_is_invalid(overlay))
886                 return 1;
887 
888         return 0;
889 }
890 
891 #endif /* __KERNEL__*/
892 
893 #define IZO_ERROR_NAME 1
894 #define IZO_ERROR_UPDATE 2
895 #define IZO_ERROR_DELETE 3
896 #define IZO_ERROR_RENAME 4
897 
izo_error(int err)898 static inline char *izo_error(int err)
899 {
900 #ifndef __KERNEL__
901         if (err <= 0)
902                 return strerror(-err);
903 #endif
904         switch (err) {
905         case IZO_ERROR_NAME:
906                 return "InterMezzo name/name conflict";
907         case IZO_ERROR_UPDATE:
908                 return "InterMezzo update/update conflict";
909         case IZO_ERROR_DELETE:
910                 return "InterMezzo update/delete conflict";
911         case IZO_ERROR_RENAME:
912                 return "InterMezzo rename/rename conflict";
913         }
914         return "Unknown InterMezzo error";
915 }
916 
917 /* kml_unpack.c */
918 char *kml_print_rec(struct kml_rec *rec, int brief);
919 int kml_unpack(struct kml_rec *rec, char **buf, char *end);
920 
921 #endif
922