[PATCH] - 2.5.67 - sysfs (modifiable size) interface for ramdisk driver

Krishnakumar. R (krishnakumar@naturesoft.net)
Thu, 10 Apr 2003 21:05:53 +0530


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

--- drivers/block/genhd.orig.c Thu Apr 10 20:03:04 2003
+++ drivers/block/genhd.c Thu Apr 10 20:41:24 2003
@@ -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 },
--- drivers/block/rd.orig.c Thu Apr 10 20:03:17 2003
+++ drivers/block/rd.c Thu Apr 10 20:14:58 2003
@@ -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


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/