[PATCH/RFC] allow mapping from block-device-file to sysfs entry.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Suppose that in a program I have an open file descriptor for a device,
and I want to find the /sys/block information for this device.
There is currently no direct way to do this.  I need to read
   /sys/block/*/dev, /sys/block/*/*/dev
and match major/minor numbers with the result from fstat.

I would like a more direct mechanism.

The following patch is a proposal for such a mechanism.

It provides an 'ioctl' which returns then 'name' of the device, as
generated by bdevname.  This is the same name that is used to create
entries in sysfs.
For a partition of a device, it returns 'device/partition'.

There is also a patch to 'blockdev' so you can test it.

dell:~# ./blockdev --name /dev/sda1
sda/sda1
dell:~# ./blockdev --name /dev/disk/by-uuid/f1394e26-6e0d-48bf-9fb7-1321e06efba3 
sde

My particular need for this is: given a device, find out what md/dm
array it is a member of.  Given this ioctl, I can then look up
 /sys/block/$DEVNAME/holders
and see what is in there.

Any objection to this becoming a new ioctl?  Is 'BLKGETNAME' and
adequate name?

Thanks,
NeilBrown

----------------
Subject: Allow mapping from block-device-file to sysfs entry.

New ioctl returns name provided by bdevname for non-partitions,
or "parentname/bdevname" for partitions.

Signed-off-by: Neil Brown <[email protected]>

### Diffstat output
 ./block/ioctl.c      |   13 +++++++++++++
 ./include/linux/fs.h |    6 +++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff .prev/block/ioctl.c ./block/ioctl.c
--- .prev/block/ioctl.c	2007-08-07 14:53:07.000000000 +1000
+++ ./block/ioctl.c	2007-08-07 15:38:46.000000000 +1000
@@ -223,8 +223,21 @@ int blkdev_ioctl(struct inode *inode, st
 	struct block_device *bdev = inode->i_bdev;
 	struct gendisk *disk = bdev->bd_disk;
 	int ret, n;
+	char b[BDEVNAME_SIZE*2];
 
 	switch(cmd) {
+	case BLKGETNAME:
+		memset(b, 0, sizeof(b));
+		bdevname(bdev->bd_contains, b);
+		if (bdev->bd_contains != bdev) {
+			char *e = b + strlen(b);
+			*e++ = '/';
+			bdevname(bdev, e);
+		}
+		if (copy_to_user((char __user *)arg, b, BDEVNAME_SIZE*2))
+			return -EFAULT;
+		return 0;
+
 	case BLKFLSBUF:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;

diff .prev/include/linux/fs.h ./include/linux/fs.h
--- .prev/include/linux/fs.h	2007-08-07 14:51:08.000000000 +1000
+++ ./include/linux/fs.h	2007-08-07 15:38:49.000000000 +1000
@@ -223,6 +223,9 @@ extern int dir_notify_enable;
 #define BLKTRACESTOP _IO(0x12,117)
 #define BLKTRACETEARDOWN _IO(0x12,118)
 
+#define BDEVNAME_SIZE	32	/* Largest string for a blockdev identifier */
+#define BLKGETNAME _IOR(0x12, 119, char [BDEVNAME_SIZE*2])
+
 #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
 #define FIBMAP	   _IO(0x00,1)	/* bmap access */
 #define FIGETBSZ   _IO(0x00,2)	/* get the block size used for bmap */
@@ -1590,9 +1593,6 @@ extern void unregister_chrdev_region(dev
 extern int chrdev_open(struct inode *, struct file *);
 extern void chrdev_show(struct seq_file *,off_t);
 
-/* fs/block_dev.c */
-#define BDEVNAME_SIZE	32	/* Largest string for a blockdev identifier */
-
 #ifdef CONFIG_BLOCK
 #define BLKDEV_MAJOR_HASH_SIZE	255
 extern const char *__bdevname(dev_t, char *buffer);

--------------
--- blockdev.c.orig	2007-08-07 15:06:00.000000000 +1000
+++ blockdev.c	2007-08-07 15:39:04.000000000 +1000
@@ -29,6 +29,7 @@
 #define BLKBSZGET  _IOR(0x12,112,size_t)
 #define BLKBSZSET  _IOW(0x12,113,size_t)
 #define BLKGETSIZE64 _IOR(0x12,114,size_t)
+#define BLKGETNAME _IOR(0x12,119,char [64])
 #endif
 
 /* Maybe <linux/hdreg.h> could be included */
@@ -56,6 +57,7 @@
 #define ARGINTG	4
 #define ARGLINTG 5
 #define ARGLLINTG 6
+#define ARGSTR64 7
 	long argval;
 	char *argname;
 	char *help;
@@ -101,6 +103,10 @@
 	{ "--rereadpt", "BLKRRPART", BLKRRPART, ARGNONE, 0, NULL,
 	  N_("reread partition table") },
 #endif
+#ifdef BLKGETNAME
+	{ "--name", "BLKGETNAME", BLKGETNAME, ARGSTR64, 0, NULL,
+	  N_("get device name") },
+#endif
 };
 
 #define SIZE(a)	(sizeof(a)/sizeof((a)[0]))
@@ -242,6 +248,7 @@
 	int iarg;
 	long larg;
 	long long llarg;
+	char str64arg[64];
 	int verbose = 0;
 
 	for (i = 1; i < d; i++) {
@@ -306,6 +313,9 @@
 			llarg = bdcms[j].argval;
 			res = ioctl(fd, bdcms[j].ioc, &llarg);
 			break;
+		case ARGSTR64:
+			res = ioctl(fd, bdcms[j].ioc, &str64arg);
+			break;
 		}
 		if (res == -1) {
 			perror(bdcms[j].iocname);
@@ -332,6 +342,13 @@
 			else
 				printf("%lld\n", llarg);
 			break;
+		case ARGSTR64:
+			if (verbose)
+				printf("%s: %.64s\n", _(bdcms[j].help),
+				       str64arg);
+			else
+				printf("%.64s\n", str64arg);
+			break;
 		default:
 			if (verbose)
 				printf(_("%s succeeded.\n"), _(bdcms[j].help));
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux