aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2010-01-27 01:14:20 -0500
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:14 -0500
commit65b6f3403431cd43ef7b0dab679a50f770124a65 (patch)
tree3f9e8c88926fa3c3fe40bc8fab20dabd8496e307 /fs
parent14a437c2b67aeee2a989a5d9c7e19094355d2fed (diff)
ocfs2_dlmfs: Use poll() to signify BASTs.
o2dlm's userspace filesystem is an easy way to use the DLM from userspace. It is intentionally simple. For example, it does not allow for asynchronous behavior or lock conversion. This is intentional to keep the interface simple. Because there is no asynchronous notification, there is no way for a process holding a lock to know another node needs the lock. This is the number one complaint of ocfs2_dlmfs users. Turns out, we can solve this very easily. We add poll() support to ocfs2_dlmfs. When a BAST is received, the lock's file descriptor will receive POLLIN. This is trivial to implement. Userdlm already has an appropriate waitqueue, and the lock knows when it is blocked. We add the "bast" capability to tell userspace this is available. Signed-off-by: Joel Becker <joel.becker@oracle.com> Acked-by: Mark Fasheh <mfasheh@suse.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/dlm/dlmfs.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index 77d0df42fe02..ddf55dafba2d 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -43,6 +43,7 @@
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/string.h> 44#include <linux/string.h>
45#include <linux/backing-dev.h> 45#include <linux/backing-dev.h>
46#include <linux/poll.h>
46 47
47#include <asm/uaccess.h> 48#include <asm/uaccess.h>
48 49
@@ -98,8 +99,12 @@ static const struct dlm_protocol_version user_locking_protocol = {
98 * The ABI features are local to this machine's dlmfs mount. This is 99 * The ABI features are local to this machine's dlmfs mount. This is
99 * distinct from the locking protocol, which is concerned with inter-node 100 * distinct from the locking protocol, which is concerned with inter-node
100 * interaction. 101 * interaction.
102 *
103 * Capabilities:
104 * - bast : POLLIN against the file descriptor of a held lock
105 * signifies a bast fired on the lock.
101 */ 106 */
102#define DLMFS_CAPABILITIES "" 107#define DLMFS_CAPABILITIES "bast"
103extern int param_set_dlmfs_capabilities(const char *val, 108extern int param_set_dlmfs_capabilities(const char *val,
104 struct kernel_param *kp) 109 struct kernel_param *kp)
105{ 110{
@@ -215,6 +220,22 @@ static int dlmfs_file_release(struct inode *inode,
215 return 0; 220 return 0;
216} 221}
217 222
223static unsigned int dlmfs_file_poll(struct file *file, poll_table *wait)
224{
225 int event = 0;
226 struct inode *inode = file->f_path.dentry->d_inode;
227 struct dlmfs_inode_private *ip = DLMFS_I(inode);
228
229 poll_wait(file, &ip->ip_lockres.l_event, wait);
230
231 spin_lock(&ip->ip_lockres.l_lock);
232 if (ip->ip_lockres.l_flags & USER_LOCK_BLOCKED)
233 event = POLLIN | POLLRDNORM;
234 spin_unlock(&ip->ip_lockres.l_lock);
235
236 return event;
237}
238
218static ssize_t dlmfs_file_read(struct file *filp, 239static ssize_t dlmfs_file_read(struct file *filp,
219 char __user *buf, 240 char __user *buf,
220 size_t count, 241 size_t count,
@@ -585,6 +606,7 @@ static int dlmfs_fill_super(struct super_block * sb,
585static const struct file_operations dlmfs_file_operations = { 606static const struct file_operations dlmfs_file_operations = {
586 .open = dlmfs_file_open, 607 .open = dlmfs_file_open,
587 .release = dlmfs_file_release, 608 .release = dlmfs_file_release,
609 .poll = dlmfs_file_poll,
588 .read = dlmfs_file_read, 610 .read = dlmfs_file_read,
589 .write = dlmfs_file_write, 611 .write = dlmfs_file_write,
590}; 612};