One to many mapping and IOCTL.
Posted On Wednesday, February 18, 2009 at at 2:56 PM by rajgopalvThis project is going really great. After the one to one mapping, the next plan was to make one to many mapping.
The pool disk will be the one in which the file system will reside on. This pool device internally maps to the block devices of the original harddisks.
Krishna and I worked hard like never before.
The one to many consists of these steps.
- Get the bio
- Find in which disk the bio starts.
- If bio starts and ends in the same device,
- then change the block_dev and sector and send_bio;
- else if the bio spans many devices,
- then split_bio and call this same function recursively
This module, while developing, by default spans only /dev/ram0,1. But we need the user to select the devices.
Here comes ioctl.
The only way user programs can communicate with driver is through IOCTL calls. Me and Krishna, now started concentrating on writing ioctls. We wrote the ioctl handling inside drivers. Santhosh started working on user commands. He creates c-programs, that get commands. Commands look something like,
$ pool add /dev/pool0 /dev/ram10 /dev/ram12
This means, Add /dev/ram10 and ram12 to /dev/pool0. This guy, gets the devices in command line arguement and put it in a datastructure. Finally, according to wat to be done (add, remove etc..), he passes the corresponding ioctl_command_number with the datastructure.
We get this datasructure inside the driver and we add the corresponding block_device objects of the devices to out list of devices handled by pool. Same applies for remove..
Some ioctl operations are left.. We are doing that.
Our next step will be, putting metadata on harddisks. We know nothing in this. Lots Lots of problem. As soon as we are done, I'll post the same here!
We've not yet touched the file system part. Problem lies there too....
GOD HELP US! :)
Thinking of Pool data structures..
Posted On Saturday, February 7, 2009 at at 4:11 PM by rajgopalv- one for physical on_disk pool. (when the pool info is saved in disks, we should take care of : 'this' data is from 'this' sector to 'this' sector. )
- one for memory (take information from physical disks and put it in the pool object in memory which is handy for programming.)
- How can a disk (partition or physical disk or whatever) be uniquely identified ? The device address (like /dev/sda) might change if you reboot.
- When the computer is rebooted, our pool should know what all disks it was handling before. For this we need to store the pool-device relationship somewhere permanently (you cant store it in disk which is participating in pool because it can be removed). Where can I save that ?
- (!) Lot of things become easy if we keep a maximum limit on the disk that can participate in the pool ( say 256 ).. May be there are ways to handle infinite number of disks, but to begin with, the first version will have 256 as limit.
ONE - to - ONE mapping... SUCCESS
Posted On Friday, February 6, 2009 at at 12:08 PM by rajgopalvPool is the device over which the file system is going to operate on. So, The pool has to redirect the requests that it gets to the original devices below it. I was bit stuck with "how can this communication be achieved ?"................
I was thinking of EXPORTING the transfer functions globally, so that, the pool's job as simple as to call the transfer functions. But is this generic ?
* I've EXPORT them.,
* Recompile the driver
* Also, you cant do this for all the drivers
COMPLETELY NOT GENERIC!
Then, Hari Helped!!!!!
He told me there are several ways by which u can achieve this without EXPORTING. one of the way is submit_bio(). I read in LDD3, "If you want to redirect, you change the bio->bi_bdev, and resubmit the bio".... [ GREAT!!! ]
But how to get the block_device object of a device....??
Hari Helped!!!!!
* Path_lookup the device
* Get the inode of the device from nameidata
* Get the dev_t object fom the inode
* open_by_devnum and get the block_device [GREAT!!!!]
ok... Got the block_device....
I changed the block_device and submited the bio
KERNEL PANICS!!!!!!!
tried tried tried tried tried....... 3 days of trying,
Hari pointed out the bug was there in bio_endio, but i din know what exactly the bug is.
05-01-2008, about 4.30 pm, evrery thing got so clear....
what i thought was,
* submit_bio() returns only after performing the whole I/O operation.
* so after the submit_bio, the bio is a waste
* i killed it after submit_bio
But the thing is,
* submit_bio retuns after "JUST PUTTING THE BIO IN THE REQUEST QUEUE OF THE OTHER DEVICE"
* not knowing this, i was killing the bio (which was still in the request queue)
FINE!
i wrote my bi_end_io function and did all ending operations there.........
TADAAAAAA.....
The code worked. Whatever operations tat i did in the pool, got reflected in ram0... Thankyou hari for all your help.! This project is going awesome..... Lots of learning........
NEXT_STEP : one-to-many mappping...
CREATING POOLS.......
Posted On Friday, January 30, 2009 at at 7:01 PM by rajgopalvThis is how i'm gonna implement pools......
* Every disk that is present in the system is controlled by a driver.
* every driver has a request queue.
I will create a virtual device - POOL. Pool's size = sum of sizes all the devices tat forms the pool.
any request that comes to my Pool's request queue will be forwarded to a corresponding physical device
-------------------------
| DEV-A | DEV-B | DEV-C | > dev_name
| 0-100 | 0-100 | 0-100 | > size in sectors
-------------------------
........................||...........................
........................||...........................
.......................\_/........................
........................\/.........................
---------------------------
| .........POOL ..........|
| ......... 300 ..........|
---------------------------
so, this pool is only visible to the user.
Any I/O request to the POOL should be converted to I/O request of the device.
Example : any request to read the 125'th sector of the pool, should be a request to read the DEV-B's 25th sector.
please see,
http://lwn.net/Articles/58720/
In this device driver,
static void sbd_transfer(); does the copying job from buffer to disk....
I need to modify this sbd_transfer(), such that,
{
if(sector>= 0 && sector <100) class="Apple-tab-span" style="white-space:pre"> i/o request should be sent to DEV-A's driver...
if(sector>= 100 && sector <200) class="Apple-tab-span" style="white-space:pre"> i/o request should be sent to DEV-B's driver...
if(sector>= 200 && sector <300) class="Apple-tab-span" style="white-space:pre"> i/o request should be sent to DEV-C's driver...
}
This is the algorithm
Questions.
* Is this possible ?
* If this is possible, how can we enable communication between Drivers?
[pool's driver need to pass a read/write request to DEV-B.. HOW?]
Modules of the Project...
Posted On Wednesday, January 28, 2009 at at 6:59 PM by rajgopalvPFS will have 2 main modules.....
1. Pool manager
2. File system.
* Pool manager is the one tat should replace the volume manager.
The Pool Manager should handle multiple disks as a single logical pool. the size of that logical pool should not be limited. the size should grow when another disk is added to the pool, it should decreased when a disk is removed.! It should provide various functions to the file system tat will be sitting above this.
* the File System - PFS is the one tat interacts with the Pool Manager to get the data written into the hard disk. For this, the FS makes use of the methods provided by the pool manager. This interacts with the upper level layers like system calls etc.
WHY PFS ?
Posted On Sunday, January 25, 2009 at at 12:26 PM by rajgopalvHere is a detailed Description of the PFS...
Current filesystems have this problem : LIMITED SIZE...
u allocate certain size for a file system, format a file system, done.!
say,
in a 50 hard disk, u have 3 logical partitions
MOVIES | PROJECTS | DOCUMENTS..
20GB........20GB...........10GB
* now consider MOVIES partion is full
* there is 15GB free space in PROJECTS
* still u cant add even a single file in MOVIES !!!
Why not make a file system tat can dynamically expand and shrink...
We'll eliminate the term "VOLUMES, PARTITIONS"... We'll make POOLS!!!
Now, how about,
* MOVIES , PROJECTS, DOCUMENTS share the same 50GB.
* there is no seperate size for each of these.
* data can be added into any of these, till the whole 50GB gets full...
* still MOVIES , PROJECTS, DOCUMENTS can be accesed as different file systems
* they can be mounted, and un mounted seperately..
Now,
* u buy a new harddisk (120 GB)
* u plug-in the harddisk...
* boot ur system...
* "a single command" (pool -add /dev/my_new_harddisk already_existing_pool)
* NO-RE-FORMATTING ur harddisk
* [new space 50 + 120 GB]
* data can be added into any of MOVIES , PROJECTS, DOCUMENTS , till the whole 50GB + 120GB gets full...
it is already implemented in,
ZFS......... Open solaris
ZFS-on-FUSE. LINUX
LVM2 can do this (but not as a readymade file system)
Going thro ZFS
Posted On Sunday, November 30, 2008 at at 3:35 PM by rajgopalvZFS is seriously a great work of open solaris. After a long time, I'm understanding the arch of ZFS. ZFS is a file system that is built upon ZPOOLS. By going through the zfs-on-fuse.blogspot.com, i got to know that porting zpool is not tat difficult job. still as a beginner, i would find it difficult. I would keep things posted... bye.. :)