GIT: unionfs2-2.6.27.y: md: set mddev readonly flag on blkdev BLKROSET ioctl

Erez Zadok ezk at fsl.cs.sunysb.edu
Thu Aug 12 23:15:29 EDT 2010


commit 789242303b22bddc1cd03a0c013bfdc091556d83
Author: Dan Williams <dan.j.williams at intel.com>
Date:   Wed May 12 08:25:37 2010 +1000

    md: set mddev readonly flag on blkdev BLKROSET ioctl
    
    commit e2218350465e7e0931676b4849b594c978437bce upstream.
    
    When the user sets the block device to readwrite then the mddev should
    follow suit.  Otherwise, the BUG_ON in md_write_start() will be set to
    trigger.
    
    The reverse direction, setting mddev->ro to match a set readonly
    request, can be ignored because the blkdev level readonly flag precludes
    the need to have mddev->ro set correctly.  Nevermind the fact that
    setting mddev->ro to 1 may fail if the array is in use.
    
    Signed-off-by: Dan Williams <dan.j.williams at intel.com>
    Signed-off-by: NeilBrown <neilb at suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>

diff --git a/drivers/md/md.c b/drivers/md/md.c
index b60d328..4d96950 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4816,6 +4816,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
 	int err = 0;
 	void __user *argp = (void __user *)arg;
 	mddev_t *mddev = NULL;
+	int ro;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -4951,6 +4952,34 @@ static int md_ioctl(struct inode *inode, struct file *file,
 			err = do_md_stop (mddev, 1, 1);
 			goto done_unlock;
 
+		case BLKROSET:
+			if (get_user(ro, (int __user *)(arg))) {
+				err = -EFAULT;
+				goto done_unlock;
+			}
+			err = -EINVAL;
+
+			/* if the bdev is going readonly the value of mddev->ro
+			 * does not matter, no writes are coming
+			 */
+			if (ro)
+				goto done_unlock;
+
+			/* are we are already prepared for writes? */
+			if (mddev->ro != 1)
+				goto done_unlock;
+
+			/* transitioning to readauto need only happen for
+			 * arrays that call md_write_start
+			 */
+			if (mddev->pers) {
+				err = restart_array(mddev);
+				if (err == 0) {
+					mddev->ro = 2;
+					set_disk_ro(mddev->gendisk, 0);
+				}
+			}
+			goto done_unlock;
 	}
 
 	/*


More information about the unionfs-cvs mailing list