summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorJames Morris <jmorris@redhat.com>2004-08-23 21:31:13 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-23 21:31:13 -0700
commitf22f9adedabc7989fb81f24dc64de3b0715b8fa6 (patch)
treea2db13fbcec1f20f4317acfd0e15613e891f6f65 /include/linux
parentef53b198e5a457487b148c5f6e84ae85e7c8df83 (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/linux')
-rw-r--r--include/linux/fs.h33
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)
{