7

hope you can help me: I'm trying to determine whether the device is removable or not, all i have is device name (/dev/sdc). Actually, I need to determine when the file on removable media or on local disk by full path of this file.

I've tryed to search in the current->fs->pwd and all I could find is a set of flags here: *current->fs->pwd.mnt->mnt_sb->s_bdev->bd_disk->flags* where GENHD_FL_REMOVABLE set for removable devices

But i always get the same flags set (as i understand, s_bdev always points to the same device (/dev/sda)).

So now i get the device name (/dev/sdc) that contains my file by parsing mtab, but still can't find out, removable it or not.

Is there possible way to get block_device structure by device name? (for example, "file" structure may be obtained by calling fd = open("name") fl = fged(fd) where fl points to "file" structure)

Makc
  • 297
  • 2
  • 16

2 Answers2

2

You can iterate over block devices using class_dev_iter_init and class_dev_iter_next. See the code in block/genhd.c blk_lookup_devt for usage.

Once you have the device, you can use dev_to_disk to get a struct gendisk *, in which you can check the removable flag.

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
  • So, using this way, how I can determine which one of block devices contains my opened file if i have only full path to this file. – Makc Oct 04 '11 at 12:36
  • 1
    @Makc: I think you can use `vfs_stat`, it will give you a `struct kstat` in which you will be able to compare the `dev_t` to the block device. – Hasturkun Oct 04 '11 at 12:51
  • I've meet some troubles using `class_dev_iter_init` and `class_dev_iter_next`. (system halts on `class_dev_iter_next` and `disk_type` is undefined, however his parameter is not necessary.) So, I have found `get_gendisk()` function that takes `dev_t` and returns `gendisk` [link](http://lxr.linux.no/linux+v2.6.32.33/block/genhd.c#L567), this is what i need, but how can I use this function ? It defined in **/include/linux/genhd.h**, but including this header makes module compile with warning and insmod fails with _Unknown symbol in module_. So, is it possible to use this function in kern module ? – Makc Oct 09 '11 at 12:41
  • @Makc: It appears that `get_gendisk()` should be exported in recent kernels, was not previously. If recompiling the kernel is an option, either update your kernel, or add a `EXPORT_SYMBOL` to genhd.c – Hasturkun Oct 09 '11 at 12:54
  • Kernel recompiling isn't option. I can't beleave that simple operation, like just obtaining list of block devices can be so complicated or even not possible 0_o. – Makc Oct 09 '11 at 17:14
  • 1
    @Makc: As I said, that was changed in a more recent kernel (though I'm having trouble pinpointing the exact version). I may have found an alternate path though, it's a bit ugly, as in `vfs_fstatat` get a path via `user_path_at`, then go through either `mnt.mnt_sb` or `dentry.d_sb` to get to your `block_device` and `gendisk` – Hasturkun Oct 09 '11 at 17:34
  • Finally, this code really works, in some cases I get EFAULT error when calling `user_path_at()`, but I'll fix it next week and share source that works fine (at least on kernel 2.6.32.33). @Hasturkun , thank you very much. – Makc Oct 09 '11 at 22:57
1

Read /sys/block/dev-name/removable as it should contain 1 if the device is removable or 0 if not. (dev-name = the device's name: sda, hda, fd0, ...)

alk
  • 69,737
  • 10
  • 105
  • 255
  • i know about this, but it's not working under old linux versions, anyway, thank you. – Makc Oct 02 '11 at 12:50
  • Also, i don't know any safe ways to read files from kernel modules. (I've tryed sys_read() and vfs_read() - it's causes "Oops" :) ) Maybe you know any ways to acces sysfs from kernel module ? – Makc Oct 09 '11 at 15:54