[Ocfs2-commits] mfasheh commits r1885 - trunk/fs/ocfs2/dlm

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Feb 2 16:59:04 CST 2005


Author: mfasheh
Date: 2005-02-02 16:59:02 -0600 (Wed, 02 Feb 2005)
New Revision: 1885

Modified:
   trunk/fs/ocfs2/dlm/dlmfs.c
   trunk/fs/ocfs2/dlm/dlmfs_compat.h
   trunk/fs/ocfs2/dlm/userdlm.c
   trunk/fs/ocfs2/dlm/userdlm.h
Log:
* Add LVB support to dlmfs. to set an lvb you just write to the lock file,  
  to get an lvb you read from it. Dlmfs users now have 64 bytes of
  atomically updated shared resource to play with!



Modified: trunk/fs/ocfs2/dlm/dlmfs.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmfs.c	2005-02-02 22:45:57 UTC (rev 1884)
+++ trunk/fs/ocfs2/dlm/dlmfs.c	2005-02-02 22:59:02 UTC (rev 1885)
@@ -74,10 +74,11 @@
 				   int *level,
 				   int *flags)
 {
-	if (open_flags & O_RDWR)
-		return -EACCES;
+	if (open_flags & (O_WRONLY|O_RDWR))
+		*level = LKM_EXMODE;
+	else
+		*level = LKM_PRMODE;
 
-	*level = (open_flags & O_WRONLY) ? LKM_EXMODE : LKM_PRMODE;
 	*flags = 0;
 	if (open_flags & O_NONBLOCK)
 		*flags |= LKM_NOQUEUE;
@@ -102,6 +103,10 @@
 	if (status < 0)
 		goto bail;
 
+	/* We don't want to honor O_APPEND at read/write time as it
+	 * doesn't make sense for LVB writes. */
+	file->f_flags &= ~O_APPEND;
+
 	fp = kmalloc(sizeof(*fp), GFP_KERNEL);
 	if (!fp) {
 		status = -ENOMEM;
@@ -154,6 +159,94 @@
 	return 0;
 }
 
+static ssize_t dlmfs_file_read(struct file *filp,
+			       char *buf,
+			       size_t count,
+			       loff_t *ppos)
+{
+	int bytes_left;
+	ssize_t readlen;
+	char *lvb_buf;
+	struct inode *inode = filp->f_dentry->d_inode;
+
+	dprintk("inode %lu, count = %u, *ppos = %llu\n",
+		inode->i_ino, count, *ppos);
+
+	if (*ppos >= i_size_read(inode))
+		return 0;
+
+	if (!count)
+		return 0;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	/* don't read past the lvb */
+	if ((count + *ppos) > i_size_read(inode))
+		readlen = i_size_read(inode) - *ppos;
+	else
+		readlen = count - *ppos;
+
+	lvb_buf = kmalloc(readlen, GFP_KERNEL);
+	if (!lvb_buf)
+		return -ENOMEM;
+
+	user_dlm_read_lvb(inode, lvb_buf, readlen);
+	bytes_left = __copy_to_user(buf, lvb_buf, readlen);
+	readlen -= bytes_left;
+
+	kfree(lvb_buf);
+
+	*ppos = *ppos + readlen;
+
+	dprintk("read %d bytes\n", readlen);
+	return readlen;
+}
+
+static ssize_t dlmfs_file_write(struct file *filp,
+				const char *buf,
+				size_t count,
+				loff_t *ppos)
+{
+	int bytes_left;
+	ssize_t writelen;
+	char *lvb_buf;
+	struct inode *inode = filp->f_dentry->d_inode;
+
+	dprintk("inode %lu, count = %u, *ppos = %llu\n",
+		inode->i_ino, count, *ppos);
+
+	if (*ppos >= i_size_read(inode))
+		return -ENOSPC;
+
+	if (!count)
+		return 0;
+
+	if (!access_ok(VERIFY_READ, buf, count))
+		return -EFAULT;
+
+	/* don't write past the lvb */
+	if ((count + *ppos) > i_size_read(inode))
+		writelen = i_size_read(inode) - *ppos;
+	else
+		writelen = count - *ppos;
+
+	lvb_buf = kmalloc(writelen, GFP_KERNEL);
+	if (!lvb_buf)
+		return -ENOMEM;
+
+	bytes_left = copy_from_user(lvb_buf, buf, writelen);
+	writelen -= bytes_left;
+	if (writelen)
+		user_dlm_write_lvb(inode, lvb_buf, writelen);
+
+	kfree(lvb_buf);
+
+	*ppos = *ppos + writelen;
+	dprintk("wrote %d bytes\n", writelen);
+	return writelen;
+}
+
 static void dlmfs_init_once(void *foo,
 			    kmem_cache_t *cachep,
 			    unsigned long flags)
@@ -295,6 +388,8 @@
 #endif
 		inode->i_fop = &dlmfs_file_operations;
 
+		i_size_write(inode,  DLM_LVB_LEN);
+
 		user_dlm_lock_res_init(&ip->ip_lockres, dentry);
 
 		/* released at clear_inode time, this insures that we
@@ -462,6 +557,8 @@
 static struct file_operations dlmfs_file_operations = {
 	.open		= dlmfs_file_open,
 	.release	= dlmfs_file_release,
+	.read		= dlmfs_file_read,
+	.write		= dlmfs_file_write,
 };
 
 static struct inode_operations dlmfs_dir_inode_operations = {

Modified: trunk/fs/ocfs2/dlm/dlmfs_compat.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmfs_compat.h	2005-02-02 22:45:57 UTC (rev 1884)
+++ trunk/fs/ocfs2/dlm/dlmfs_compat.h	2005-02-02 22:59:02 UTC (rev 1885)
@@ -24,6 +24,16 @@
 
 #define flush_workqueue(foobar) flush_scheduled_tasks()
 
+static inline loff_t i_size_read(struct inode *inode)
+{
+	return inode->i_size;
+}
+
+static inline void i_size_write(struct inode *inode, loff_t i_size)
+{
+	inode->i_size = i_size;
+}
+
 #else
 #include <linux/workqueue.h>
 #endif

Modified: trunk/fs/ocfs2/dlm/userdlm.c
===================================================================
--- trunk/fs/ocfs2/dlm/userdlm.c	2005-02-02 22:45:57 UTC (rev 1884)
+++ trunk/fs/ocfs2/dlm/userdlm.c	2005-02-02 22:59:02 UTC (rev 1885)
@@ -336,7 +336,7 @@
 	status = dlmlock(dlm,
 			 new_level,
 			 &lockres->l_lksb,
-			 LKM_CONVERT,
+			 LKM_CONVERT|LKM_VALBLK,
 			 lockres->l_name,
 			 user_ast,
 			 lockres,
@@ -428,7 +428,7 @@
 	}
 
 	if (level > lockres->l_level) {
-		local_flags = lkm_flags;
+		local_flags = lkm_flags | LKM_VALBLK;
 		if (lockres->l_level != LKM_IVMODE)
 			local_flags |= LKM_CONVERT;
 
@@ -516,6 +516,40 @@
 	spin_unlock(&lockres->l_lock);
 }
 
+void user_dlm_write_lvb(struct inode *inode,
+			const char *val,
+			unsigned int len)
+{
+	struct user_lock_res *lockres = &DLMFS_I(inode)->ip_lockres;
+	char *lvb = lockres->l_lksb.lvb;
+
+	BUG_ON(len > DLM_LVB_LEN);
+
+	spin_lock(&lockres->l_lock);
+
+	BUG_ON(lockres->l_level < LKM_EXMODE);
+	memcpy(lvb, val, len);
+
+	spin_unlock(&lockres->l_lock);
+}
+
+void user_dlm_read_lvb(struct inode *inode,
+		       char *val,
+		       unsigned int len)
+{
+	struct user_lock_res *lockres = &DLMFS_I(inode)->ip_lockres;
+	char *lvb = lockres->l_lksb.lvb;
+
+	BUG_ON(len > DLM_LVB_LEN);
+
+	spin_lock(&lockres->l_lock);
+
+	BUG_ON(lockres->l_level < LKM_PRMODE);
+	memcpy(val, lvb, len);
+
+	spin_unlock(&lockres->l_lock);
+}
+
 void user_dlm_lock_res_init(struct user_lock_res *lockres,
 			    struct dentry *dentry)
 {
@@ -571,7 +605,7 @@
 	dprintk("unlocking lockres %s\n", lockres->l_name);
 	status = dlmunlock(dlm,
 			   &lockres->l_lksb,
-			   0,
+			   LKM_VALBLK,
 			   user_unlock_ast,
 			   lockres);
 	if (status != DLM_NORMAL) {

Modified: trunk/fs/ocfs2/dlm/userdlm.h
===================================================================
--- trunk/fs/ocfs2/dlm/userdlm.h	2005-02-02 22:45:57 UTC (rev 1884)
+++ trunk/fs/ocfs2/dlm/userdlm.h	2005-02-02 22:59:02 UTC (rev 1885)
@@ -94,6 +94,12 @@
 			  int lkm_flags);
 void user_dlm_cluster_unlock(struct user_lock_res *lockres,
 			     int level);
+void user_dlm_write_lvb(struct inode *inode,
+			const char *val,
+			unsigned int len);
+void user_dlm_read_lvb(struct inode *inode,
+		       char *val,
+		       unsigned int len);
 dlm_ctxt *user_dlm_register_context(struct qstr *name);
 void user_dlm_unregister_context(dlm_ctxt *dlm);
 



More information about the Ocfs2-commits mailing list