Go to the documentation of this file.00001
00024 #ifndef _XENO_NUCLEUS_VFILE_H
00025 #define _XENO_NUCLEUS_VFILE_H
00026
00027 #if defined(CONFIG_XENO_OPT_VFILE) || defined(DOXYGEN_CPP)
00028
00032 #include <linux/proc_fs.h>
00033 #include <linux/seq_file.h>
00034 #include <nucleus/types.h>
00035
00036 struct xnvfile_directory;
00037 struct xnvfile_regular_iterator;
00038 struct xnvfile_snapshot_iterator;
00039 struct xnvfile_lock_ops;
00040
00041 struct xnvfile {
00042 struct proc_dir_entry *pde;
00043 struct file *file;
00044 struct xnvfile_directory *parent;
00045 struct xnvfile_lock_ops *lockops;
00046 int refcnt;
00047 void *private;
00048 };
00049
00058 struct xnvfile_lock_ops {
00071 int (*get)(struct xnvfile *vfile);
00079 void (*put)(struct xnvfile *vfile);
00080 };
00081
00082
00083
00084
00085
00086
00087 struct xnvfile_hostlock_class {
00088 struct xnvfile_lock_ops ops;
00089 struct semaphore sem;
00090 };
00091
00092 struct xnvfile_nklock_class {
00093 struct xnvfile_lock_ops ops;
00094 spl_t s;
00095 };
00096
00097 struct xnvfile_input {
00098 const char __user *u_buf;
00099 size_t size;
00100 struct xnvfile *vfile;
00101 };
00102
00112 struct xnvfile_regular_ops {
00130 int (*rewind)(struct xnvfile_regular_iterator *it);
00163 void *(*begin)(struct xnvfile_regular_iterator *it);
00190 void *(*next)(struct xnvfile_regular_iterator *it);
00199 void (*end)(struct xnvfile_regular_iterator *it);
00228 int (*show)(struct xnvfile_regular_iterator *it, void *data);
00257 ssize_t (*store)(struct xnvfile_input *input);
00258 };
00259
00260 struct xnvfile_regular {
00261 struct xnvfile entry;
00262 size_t privsz;
00263 struct xnvfile_regular_ops *ops;
00264 };
00265
00266 struct xnvfile_regular_template {
00267 size_t privsz;
00268 struct xnvfile_regular_ops *ops;
00269 struct xnvfile_lock_ops *lockops;
00270 };
00271
00278 struct xnvfile_regular_iterator {
00280 loff_t pos;
00282 struct seq_file *seq;
00284 struct xnvfile_regular *vfile;
00289 char private[0];
00290 };
00291
00302 struct xnvfile_snapshot_ops {
00343 int (*rewind)(struct xnvfile_snapshot_iterator *it);
00371 void *(*begin)(struct xnvfile_snapshot_iterator *it);
00389 void (*end)(struct xnvfile_snapshot_iterator *it, void *buf);
00422 int (*next)(struct xnvfile_snapshot_iterator *it, void *data);
00451 int (*show)(struct xnvfile_snapshot_iterator *it, void *data);
00481 ssize_t (*store)(struct xnvfile_input *input);
00482 };
00483
00491 struct xnvfile_rev_tag {
00493 int rev;
00494 };
00495
00496 struct xnvfile_snapshot_template {
00497 size_t privsz;
00498 size_t datasz;
00499 struct xnvfile_rev_tag *tag;
00500 struct xnvfile_snapshot_ops *ops;
00501 struct xnvfile_lock_ops *lockops;
00502 };
00503
00515 struct xnvfile_snapshot {
00516 struct xnvfile entry;
00517 size_t privsz;
00518 size_t datasz;
00519 struct xnvfile_rev_tag *tag;
00520 struct xnvfile_snapshot_ops *ops;
00521 };
00522
00529 struct xnvfile_snapshot_iterator {
00531 int nrdata;
00533 caddr_t databuf;
00535 struct seq_file *seq;
00537 struct xnvfile_snapshot *vfile;
00539 void (*endfn)(struct xnvfile_snapshot_iterator *it, void *buf);
00544 char private[0];
00545 };
00546
00547 struct xnvfile_directory {
00548 struct xnvfile entry;
00549 };
00550
00551 struct xnvfile_link {
00552 struct xnvfile entry;
00553 };
00554
00555
00556 #define VFILE_SEQ_EMPTY ((void *)-1)
00557
00558 #define VFILE_SEQ_START SEQ_START_TOKEN
00559
00560 #define VFILE_SEQ_SKIP 2
00561
00562 #define xnvfile_printf(it, args...) seq_printf((it)->seq, ##args)
00563 #define xnvfile_write(it, data, len) seq_write((it)->seq, (data),(len))
00564 #define xnvfile_puts(it, s) seq_puts((it)->seq, (s))
00565 #define xnvfile_putc(it, c) seq_putc((it)->seq, (c))
00566
00567 static inline void xnvfile_touch_tag(struct xnvfile_rev_tag *tag)
00568 {
00569 tag->rev++;
00570 }
00571
00572 static inline void xnvfile_touch(struct xnvfile_snapshot *vfile)
00573 {
00574 xnvfile_touch_tag(vfile->tag);
00575 }
00576
00577 static inline int xnvfile_reg_p(struct xnvfile *entry)
00578 {
00579 return S_ISREG(entry->pde->mode);
00580 }
00581
00582 static inline int xnvfile_dir_p(struct xnvfile *entry)
00583 {
00584 return S_ISDIR(entry->pde->mode);
00585 }
00586
00587 static inline int xnvfile_link_p(struct xnvfile *entry)
00588 {
00589 return S_ISLNK(entry->pde->mode);
00590 }
00591
00592 #define xnvfile_noentry \
00593 { \
00594 .pde = NULL, \
00595 .parent = NULL, \
00596 .private = NULL, \
00597 .file = NULL, \
00598 .refcnt = 0, \
00599 }
00600
00601 #define xnvfile_nodir { .entry = xnvfile_noentry }
00602 #define xnvfile_nolink { .entry = xnvfile_noentry }
00603 #define xnvfile_nofile { .entry = xnvfile_noentry }
00604
00605 #define xnvfile_parent(e) ((e)->entry.parent)
00606 #define xnvfile_priv(e) ((e)->entry.private)
00607 #define xnvfile_nref(e) ((e)->entry.refcnt)
00608 #define xnvfile_file(e) ((e)->entry.file)
00609 #define xnvfile_iterator_priv(it) ((void *)(&(it)->private))
00610
00611 extern struct xnvfile_nklock_class xnvfile_nucleus_lock;
00612
00613 extern struct xnvfile_directory nkvfroot;
00614
00615 int xnvfile_init_root(void);
00616
00617 void xnvfile_destroy_root(void);
00618
00619 #ifdef __cplusplus
00620 extern "C" {
00621 #endif
00622
00623 int xnvfile_init_snapshot(const char *name,
00624 struct xnvfile_snapshot *vfile,
00625 struct xnvfile_directory *parent);
00626
00627 int xnvfile_init_regular(const char *name,
00628 struct xnvfile_regular *vfile,
00629 struct xnvfile_directory *parent);
00630
00631 int xnvfile_init_dir(const char *name,
00632 struct xnvfile_directory *vdir,
00633 struct xnvfile_directory *parent);
00634
00635 int xnvfile_init_link(const char *from,
00636 const char *to,
00637 struct xnvfile_link *vlink,
00638 struct xnvfile_directory *parent);
00639
00640 void xnvfile_destroy(struct xnvfile *vfile);
00641
00642 ssize_t xnvfile_get_blob(struct xnvfile_input *input,
00643 void *data, size_t size);
00644
00645 ssize_t xnvfile_get_string(struct xnvfile_input *input,
00646 char *s, size_t maxlen);
00647
00648 ssize_t xnvfile_get_integer(struct xnvfile_input *input, long *valp);
00649
00650 int __vfile_hostlock_get(struct xnvfile *vfile);
00651
00652 void __vfile_hostlock_put(struct xnvfile *vfile);
00653
00654 #ifdef __cplusplus
00655 }
00656 #endif
00657
00658 static inline
00659 void xnvfile_destroy_snapshot(struct xnvfile_snapshot *vfile)
00660 {
00661 xnvfile_destroy(&vfile->entry);
00662 }
00663
00664 static inline
00665 void xnvfile_destroy_regular(struct xnvfile_regular *vfile)
00666 {
00667 xnvfile_destroy(&vfile->entry);
00668 }
00669
00670 static inline
00671 void xnvfile_destroy_dir(struct xnvfile_directory *vdir)
00672 {
00673 xnvfile_destroy(&vdir->entry);
00674 }
00675
00676 static inline
00677 void xnvfile_destroy_link(struct xnvfile_link *vlink)
00678 {
00679 xnvfile_destroy(&vlink->entry);
00680 }
00681
00682 #define DEFINE_VFILE_HOSTLOCK(name) \
00683 struct xnvfile_hostlock_class name = { \
00684 .ops = { \
00685 .get = __vfile_hostlock_get, \
00686 .put = __vfile_hostlock_put, \
00687 }, \
00688 .sem = __SEMAPHORE_INITIALIZER(name.sem, 1), \
00689 }
00690
00691 #else
00692
00693 #define xnvfile_touch_tag(tag) do { } while (0)
00694
00695 #define xnvfile_touch(vfile) do { } while (0)
00696
00697 #endif
00698
00701 #endif