patch-1.3.78 linux/drivers/block/loop.c

Next file: linux/drivers/block/md.c
Previous file: linux/drivers/block/ll_rw_blk.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.77/linux/drivers/block/loop.c linux/drivers/block/loop.c
@@ -181,7 +181,10 @@
 		offset -= blksize;
 	}
 	len = CURRENT->current_nr_sectors << 9;
-	if ((CURRENT->cmd != WRITE) && (CURRENT->cmd != READ)) {
+	if (CURRENT->cmd == WRITE) {
+		if (lo->lo_flags & LO_FLAGS_READ_ONLY)
+			goto error_out;
+	} else if (CURRENT->cmd != READ) {
 		printk("unknown loop device command (%d)?!?", CURRENT->cmd);
 		goto error_out;
 	}
@@ -235,11 +238,11 @@
 	goto repeat;
 }
 
-static int loop_set_fd(struct loop_device *lo, unsigned int arg)
+static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
 {
 	struct file	*file;
 	struct inode	*inode;
-	
+
 	if (arg >= NR_OPEN || !(file = current->files->fd[arg]))
 		return -EBADF;
 	if (lo->lo_inode)
@@ -261,7 +264,14 @@
 	} else
 		return -EINVAL;
 
-	invalidate_inode_pages (inode);
+	if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) {
+		lo->lo_flags |= LO_FLAGS_READ_ONLY;
+		set_device_ro(dev, 1);
+	} else {
+		invalidate_inode_pages (inode);
+		set_device_ro(dev, 0);
+	}
+
 	lo->lo_inode = inode;
 	lo->lo_inode->i_count++;
 	lo->transfer = NULL;
@@ -274,7 +284,7 @@
 {
 	if (!lo->lo_inode)
 		return -ENXIO;
-	if (lo->lo_refcnt > 1)
+	if (lo->lo_refcnt > 1)	/* we needed one fd for the ioctl */
 		return -EBUSY;
 	if (S_ISBLK(lo->lo_inode->i_mode))
 		blkdev_release (lo->lo_inode);
@@ -378,7 +388,7 @@
 	lo = &loop_dev[dev];
 	switch (cmd) {
 	case LOOP_SET_FD:
-		return loop_set_fd(lo, arg);
+		return loop_set_fd(lo, inode->i_rdev, arg);
 	case LOOP_CLR_FD:
 		return loop_clr_fd(lo, inode->i_rdev);
 	case LOOP_SET_STATUS:
@@ -442,8 +452,6 @@
 		lo->lo_refcnt--;
 		MOD_DEC_USE_COUNT;
 	}
-
-	return;
 }
 
 static struct file_operations lo_fops = {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this