- 2.5.67 - sysfs (modifiable size) interface for ramdisk driver
PATCH 1/1 - 2.5.67 - sysfs (modifiable size) interface for ramdisk driver
Hi,
This patch will make the size entry in the sysfs of the ramdisk as writable.
Using this we can modify the size of the ramdisk at run time.
Usage:
echo "4000" > /sys/block/ram0/size
will change the size of the ramdisk 0. Similarly for all the ramdisks.
It would discard all the writes to size if the major number is different from that of ramdisk. So all other size present in other block devices remain safe.
Regards and Thanks
KK
PS: The following patch was generated by using diff -urN and modifies two files - genhd.c and rd.c
block/genhd.c renamed from block/genhd.orig.c +21 -0
@@ -423,6 +423,7 @@struct disk_attribute {struct attribute attr;ssize_t (*show)(struct gendisk *,char *); +ssize_t (*store)(struct gendisk *,const char *,size_t ); }; static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
@@ -438,8 +439,23 @@return ret; } + +static ssize_t disk_attr_store (struct kobject *kobj,struct attribute *attr, +const char *buf,size_t len) +{ +struct gendisk *disk =to_disk (kobj); +struct disk_attribute *disk_attr = + container_of(attr,struct disk_attribute,attr); +ssize_t ret =0 ; + +if (disk_attr->store) + ret = disk_attr->store (disk, buf, len); +return ret; +} +static struct sysfs_ops disk_sysfs_ops = { .show = &disk_attr_show, + .store = &disk_attr_store };static ssize_t disk_dev_read (struct gendisk * disk,char *page)
@@ -456,6 +472,47 @@return sprintf (page,"%llu\n" , (unsigned long long )get_capacity (disk)); } +#define NUM_RAMDISKS 16 +#define MAX_RDSTR_LEN 7 +extern struct block_device *rd_bdev[NUM_RAMDISKS ]; + +static ssize_t disk_size_store(struct gendisk * disk, const char *buf, size_t
len)
+{
+ struct block_device *bdev = rd_bdev[disk->first_minor];
+ char rd_buf[MAX_RDSTR_LEN+1];
+ int temp = get_capacity(disk);
+
+ /* Only for ramdisks */
+ if (disk->major != RAMDISK_MAJOR ) return -EPERM;
+
+ /* If mounted or being used return busy */
+ if (bdev != NULL ) {
+ down (&bdev->bd_sem);
+ if ( bdev->bd_openers > 1 ){
+ up (&bdev->bd_sem);
+ return -EBUSY;
+ }
+ up (&bdev->bd_sem);
+ }
+
+ if (len>MAX_RDSTR_LEN) len = MAX_RDSTR_LEN;
+ strncpy(rd_buf, buf, len-1);
+ rd_buf[len-1] = '\0';
+ temp = simple_strtol(rd_buf,NULL,0);
+
+ if ( (temp < 0) || (temp % 2) ) {
+ printk("RAMDISK: wrong size %d\n", temp);
+ return len; /* Neglect -ve and odd values */
+ }
+ set_capacity(disk, temp );
+ if (bdev != NULL ) {
+ down (&bdev->bd_sem); + bdev->bd_inode->i_size = get_capacity(disk)<<9; + up (&bdev->bd_sem);
+ }
+ return len;
+}
+
static inline unsigned jiffies_to_msec(unsigned jif) {
#if 1000 % HZ == 0
@@ -494,8 +551,9 @@
.show = disk_range_read
};
static struct disk_attribute disk_attr_size = {
- .attr = {.name = "size", .mode = S_IRUGO },
- .show = disk_size_read
+ .attr = {.name = "size", .mode = S_IRUGO|S_IWUSR },
+ .show = disk_size_read,
+ .store = disk_size_store
};
static struct disk_attribute disk_attr_stat = {
.attr = {.name = "stat", .mode = S_IRUGO },
block/rd.c renamed from block/rd.orig.c +1 -1
@@ -70,7 +70,7 @@*/ static struct gendisk *rd_disks[NUM_RAMDISKS ]; -static struct block_device *rd_bdev[NUM_RAMDISKS ];/* Protected device data */ +struct block_device *rd_bdev[NUM_RAMDISKS ];/* Protected device data */ /* * Parameters for the boot-loading of the RAM disk. These are set by