diff options
| author | James Morris <jmorris@redhat.com> | 2004-08-23 21:31:13 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-23 21:31:13 -0700 |
| commit | f22f9adedabc7989fb81f24dc64de3b0715b8fa6 (patch) | |
| tree | a2db13fbcec1f20f4317acfd0e15613e891f6f65 /include | |
| parent | ef53b198e5a457487b148c5f6e84ae85e7c8df83 (diff) | |
[PATCH] libfs: move transaction file ops into libfs
Below is an updated version of the patch which moves duplicated
transaction-based file operation code into libfs. Since the last post, the
patch has been through a couple of iterations with Al, who suggested a
number of cleanups including locking and interface simplification.
For filesystem writers, the interface is now much simpler. The
simple_transaction_get() helper should be part of the file op write method.
This safely obtains the transaction request data during write(), allocates
a page for it and stores it there. The data is returned to the caller for
potential further processing, which then makes it available for the next
read() call via simple_transaction_set(). See the selinuxfs and nfsctl
code for examples of use.
Signed-off-by: James Morris <jmorris@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/fs.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index a7631bd33db1..aecce55e4f88 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1571,6 +1571,39 @@ static inline ino_t parent_ino(struct dentry *dentry) /* kernel/fork.c */ extern int unshare_files(void); +/* Transaction based IO helpers */ + +/* + * An argresp is stored in an allocated page and holds the + * size of the argument or response, along with its content + */ +struct simple_transaction_argresp { + ssize_t size; + char data[0]; +}; + +#define SIMPLE_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct simple_transaction_argresp)) + +char *simple_transaction_get(struct file *file, const char __user *buf, + size_t size); +ssize_t simple_transaction_read(struct file *file, char __user *buf, + size_t size, loff_t *pos); +int simple_transaction_release(struct inode *inode, struct file *file); + +static inline void simple_transaction_set(struct file *file, size_t n) +{ + struct simple_transaction_argresp *ar = file->private_data; + + BUG_ON(n > SIMPLE_TRANSACTION_LIMIT); + + /* + * The barrier ensures that ar->size will really remain zero until + * ar->data is ready for reading. + */ + smp_mb(); + ar->size = n; +} + #ifdef CONFIG_SECURITY static inline char *alloc_secdata(void) { |
