home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.linux
- Path: sparky!uunet!darwin.sura.net!Sirius.dfn.de!chx400!bernina!almesber
- From: almesber@nessie.cs.id.ethz.ch (Werner Almesberger)
- Subject: Re: mrphmpmmmph shoelace and partitions
- Message-ID: <1992Jul25.210010.4405@bernina.ethz.ch>
- Sender: news@bernina.ethz.ch (USENET News System)
- Organization: Swiss Federal Institute of Technology (ETH), Zurich, CH
- References: <1992Jul24.021543.24526@sol.UVic.CA> <1992Jul24.143547.23391@crd.ge.com>
- Date: Sat, 25 Jul 1992 21:00:10 GMT
- Lines: 342
-
- In article <1992Jul24.143547.23391@crd.ge.com> davidsen@crd.ge.com (bill davidsen) writes:
- >In article <1992Jul24.021543.24526@sol.UVic.CA>, pmacdona@sanjuan (Peter MacDonald) writes:
- >
- >| One solution is to implement quotas, but I think Linus may
- >| have said nay to that already. Another would be to
- >| allow mounting of files as file systems? Comments? Catcalls?
-
- I've had this sitting around for a long time. A patch I've originally
- made for 0.96c-pl1 and that seems to work unmodified for 0.96c-pl2 is
- at the end of this posting.
-
- Usage example:
-
- # a floppy with a Minix FS (e.g. the rootimage) is in drive A:
- dd if=/dev/fd0 of=/file bs=256k
- mount /file /mnt
-
- A few remarks:
- - files that reside on an MS-DOS FS can only be mounted if that FS
- supports bmap. Hard disk and 3.5" floppy file systems usually
- don't.
- - newer umounts may refuse to unmount a mounted file. Hacking umount
- to accept files is left as an exercise to the reader ;-)
- - recursion (mounting a file from an FS that is a mounted file,
- etc.) is possible.
-
- > Well, I like the basic idea, because it solves a bunch of problems.
- > But it needs a bit of support before it really works; namely support in
- > fsck and mkfs to support it.
-
- Last time I've checked (early June, 0.96a-pl2), fsck and mkfs were able
- to operate on files.
-
- Enjoy,
- - Werner
-
- ---------------------------------- cut here -----------------------------------
-
- diff -cr +new-files linux.orig/fs/Makefile linux/fs/Makefile
- *** linux.orig/fs/Makefile Fri Jul 17 08:56:13 1992
- --- linux/fs/Makefile Fri Jul 17 09:55:19 1992
- ***************
- *** 18,24 ****
-
- OBJS= open.o read_write.o inode.o file_table.o buffer.o super.o \
- block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
- ! select.o fifo.o
-
- all: fs.o subdirs
-
- --- 18,24 ----
-
- OBJS= open.o read_write.o inode.o file_table.o buffer.o super.o \
- block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
- ! select.o fifo.o loop.o
-
- all: fs.o subdirs
-
- diff -cr +new-files linux.orig/fs/buffer.c linux/fs/buffer.c
- *** linux.orig/fs/buffer.c Fri Jul 17 08:56:13 1992
- --- linux/fs/buffer.c Fri Jul 17 09:35:30 1992
- ***************
- *** 23,28 ****
- --- 23,29 ----
- #include <linux/config.h>
- #include <linux/sched.h>
- #include <linux/kernel.h>
- + #include <linux/loop.h>
- #include <asm/system.h>
- #include <asm/io.h>
-
- ***************
- *** 261,266 ****
- --- 262,269 ----
- struct buffer_head * bh, * tmp;
- int buffers;
-
- + while (MAJOR(dev) == LOOP_MAJOR)
- + if (loop_trans(&dev,&block)) break;
- repeat:
- if (bh = get_hash_table(dev,block))
- return bh;
- diff -cr +new-files linux.orig/fs/loop.c linux/fs/loop.c
- *** linux.orig/fs/loop.c
- --- linux/fs/loop.c Fri Jul 17 09:35:31 1992
- ***************
- *** 0 ****
- --- 1,73 ----
- + /* Loop devices. They're used to mount files as FS'. */
- + /* Written 1992 by Werner Almesberger */
- +
- + #include <asm/segment.h>
- + #include <linux/kernel.h>
- + #include <linux/fs.h>
- + #include <linux/loop.h>
- + #include <errno.h>
- +
- +
- + static int first_use = 1;
- + static struct inode *loops[MAX_LOOPS];
- +
- +
- + int loop_getdev(struct inode *inode)
- + {
- + int count;
- +
- + if (first_use) {
- + for (count = 0; count < MAX_LOOPS; count++) loops[count] = NULL;
- + first_use = 0;
- + }
- + if (inode->i_op == NULL || inode->i_op->bmap == NULL) return -EINVAL;
- + for (count = 0; count < MAX_LOOPS; count++)
- + if (loops[count] == inode) return -EBUSY;
- + for (count = 0; count < MAX_LOOPS; count++)
- + if (loops[count] == NULL) {
- + loops[count] = inode;
- + return (LOOP_MAJOR << 8) | count;
- + }
- + return -ENODEV;
- + }
- +
- +
- + int loop_finddev(struct inode *inode)
- + {
- + int count;
- +
- + for (count = 0; count < MAX_LOOPS; count++)
- + if (loops[count] == inode) return (LOOP_MAJOR << 8) | count;
- + return -ENODEV;
- + }
- +
- +
- + void loop_dropdev(int dev)
- + {
- + int loop;
- +
- + if (MAJOR(dev) != LOOP_MAJOR) panic("loop_dropdev: bad major number");
- + loop = MINOR(dev);
- + if (loop < 0 || loop >= MAX_LOOPS || loops[loop] == NULL)
- + panic("loop_dropdev: bad minor number");
- + iput(loops[loop]);
- + loops[loop] = NULL;
- + }
- +
- +
- + int loop_trans(int *dev,int *block)
- + {
- + int loop,this;
- +
- + if (MAJOR(*dev) != LOOP_MAJOR) panic("loop_trans: bad major number");
- + loop = MINOR(*dev);
- + if (loop < 0 || loop >= MAX_LOOPS || loops[loop] == NULL)
- + panic("loop_trans: bad minor number");
- + if (*block < 0 || *block >= ((loops[loop]->i_size+BLOCK_SIZE-1) >>
- + BLOCK_SIZE_BITS)) return -1;
- + /* makes a lot of noise when failing, but it's better than a panic. */
- + if (!(this = bmap(loops[loop],*block))) return -1;
- + *block = this;
- + *dev = loops[loop]->i_dev;
- + return 0;
- + }
- diff -cr +new-files linux.orig/fs/super.c linux/fs/super.c
- *** linux.orig/fs/super.c Fri Jul 17 08:56:14 1992
- --- linux/fs/super.c Fri Jul 17 10:05:33 1992
- ***************
- *** 13,18 ****
- --- 13,19 ----
- #include <linux/ext_fs.h>
- #include <linux/msdos_fs.h>
- #include <linux/kernel.h>
- + #include <linux/loop.h>
- #include <linux/stat.h>
- #include <asm/system.h>
- #include <asm/segment.h>
- ***************
- *** 158,167 ****
- return -EPERM;
- if (!(inode = namei(dev_name)))
- return -ENOENT;
- ! dev = inode->i_rdev;
- ! if (!S_ISBLK(inode->i_mode)) {
- ! iput(inode);
- ! return -ENOTBLK;
- }
- iput(inode);
- if (dev==ROOT_DEV)
- --- 159,176 ----
- return -EPERM;
- if (!(inode = namei(dev_name)))
- return -ENOENT;
- ! if (S_ISBLK(inode->i_mode)) dev = inode->i_rdev;
- ! else {
- ! if (S_ISREG(inode->i_mode)) {
- ! if ((dev = loop_finddev(inode)) < 0) {
- ! iput(inode);
- ! return dev;
- ! }
- ! }
- ! else {
- ! iput(inode);
- ! return -ENOTBLK;
- ! }
- }
- iput(inode);
- if (dev==ROOT_DEV)
- ***************
- *** 185,190 ****
- --- 194,200 ----
- sb->s_op->write_super (sb);
- put_super(dev);
- sync_dev(dev);
- + if (MAJOR(dev) == LOOP_MAJOR) loop_dropdev(dev);
- return 0;
- }
-
- ***************
- *** 248,254 ****
- unsigned long new_flags, void *data)
- {
- struct inode * inode;
- ! int dev;
- int retval = 0;
- char tmp[100],*t;
- int i;
- --- 258,264 ----
- unsigned long new_flags, void *data)
- {
- struct inode * inode;
- ! int dev = 0; /* to make GCC happy ... */
- int retval = 0;
- char tmp[100],*t;
- int i;
- ***************
- *** 259,269 ****
- return -EPERM;
- if (!(inode = namei(dev_name)))
- return -ENOENT;
- ! dev = inode->i_rdev;
- ! if (!S_ISBLK(inode->i_mode))
- ! retval = -EPERM;
- ! else if (IS_NODEV(inode))
- ! retval = -EACCES;
- iput(inode);
- if (retval)
- return retval;
- --- 269,282 ----
- return -EPERM;
- if (!(inode = namei(dev_name)))
- return -ENOENT;
- ! if (S_ISBLK(inode->i_mode)) {
- ! if (IS_NODEV(inode)) retval = -EACCES;
- ! else dev = inode->i_rdev;
- ! }
- ! else {
- ! if (!S_ISREG(inode->i_mode)) retval = -EPERM;
- ! else if ((dev = loop_getdev(inode)) < 0) retval = dev;
- ! }
- iput(inode);
- if (retval)
- return retval;
- ***************
- *** 285,291 ****
- t = tmp;
- } else
- t = "minix";
- ! retval = do_mount(dev,dir_name,t,flags,(void *) page);
- free_page(page);
- return retval;
- }
- --- 298,305 ----
- t = tmp;
- } else
- t = "minix";
- ! if ((retval = do_mount(dev,dir_name,t,flags,(void *) page)) < 0 &&
- ! MAJOR(dev) == LOOP_MAJOR) loop_dropdev(dev);
- free_page(page);
- return retval;
- }
- diff -cr +new-files linux.orig/include/linux/loop.h linux/include/linux/loop.h
- *** linux.orig/include/linux/loop.h
- --- linux/include/linux/loop.h Fri Jul 17 09:35:32 1992
- ***************
- *** 0 ****
- --- 1,12 ----
- + #ifndef _LOOP_H
- + #define _LOOP_H
- +
- + #define LOOP_MAJOR 10 /* loop device major number */
- + #define MAX_LOOPS 8 /* max. number of loop devices */
- +
- + int loop_getdev(struct inode *inode); /* create loop device */
- + int loop_finddev(struct inode *inode); /* find loop device */
- + void loop_dropdev(int dev); /* remove loop device */
- + int loop_trans(int *dev,int *block); /* translate to real params */
- +
- + #endif
- diff -cr +new-files linux.orig/kernel/blk_drv/blk.h linux/kernel/blk_drv/blk.h
- *** linux.orig/kernel/blk_drv/blk.h Fri Jul 17 08:56:46 1992
- --- linux/kernel/blk_drv/blk.h Fri Jul 17 09:35:32 1992
- ***************
- *** 1,7 ****
- #ifndef _BLK_H
- #define _BLK_H
-
- ! #define NR_BLK_DEV 10
- /*
- * NR_REQUEST is the number of entries in the request-queue.
- * NOTE that writes may use only the low 2/3 of these: reads
- --- 1,7 ----
- #ifndef _BLK_H
- #define _BLK_H
-
- ! #define NR_BLK_DEV 11
- /*
- * NR_REQUEST is the number of entries in the request-queue.
- * NOTE that writes may use only the low 2/3 of these: reads
- diff -cr +new-files linux.orig/kernel/blk_drv/ll_rw_blk.c linux/kernel/blk_drv/ll_rw_blk.c
- *** linux.orig/kernel/blk_drv/ll_rw_blk.c Fri Jul 17 08:56:45 1992
- --- linux/kernel/blk_drv/ll_rw_blk.c Fri Jul 17 09:35:32 1992
- ***************
- *** 42,48 ****
- { NULL, NULL }, /* dev lp */
- { NULL, NULL }, /* dev pipes */
- { NULL, NULL }, /* dev sd */
- ! { NULL, NULL } /* dev st */
- };
-
- /*
- --- 42,49 ----
- { NULL, NULL }, /* dev lp */
- { NULL, NULL }, /* dev pipes */
- { NULL, NULL }, /* dev sd */
- ! { NULL, NULL }, /* dev st */
- ! { NULL, NULL } /* dev loop */
- };
-
- /*
- --
- _________________________________________________________________________
- / Werner Almesberger, ETH Zuerich, CH almesber@nessie.cs.id.ethz.ch /
- / IFW A44 Tel. +41 1 254 7213 almesberger@rzvax.ethz.ch /
- /_BITNET:_ALMESBER@CZHETH5A__HEPNET/CHADNET:_[20579::]57414::ALMESBERGER_/
-