int dev_get_block_size(struct device *dev, unsigned int *physical_block_size, unsigned int *block_size)
{
const char *name = dev_name(dev);
- int needs_open;
+ int fd = dev->bcache_fd;
+ int do_close = 0;
int r = 1;
- needs_open = (!dev->open_count && (dev->phys_block_size == -1 || dev->block_size == -1));
+ if ((dev->phys_block_size > 0) && (dev->block_size > 0)) {
+ *physical_block_size = (unsigned int)dev->phys_block_size;
+ *block_size = (unsigned int)dev->block_size;
+ return 1;
+ }
- if (needs_open && !dev_open_readonly(dev))
- return_0;
+ if (fd <= 0) {
+ if (!dev->open_count) {
+ if (!dev_open_readonly(dev))
+ return_0;
+ do_close = 1;
+ }
+ fd = dev_fd(dev);
+ }
if (dev->block_size == -1) {
- if (ioctl(dev_fd(dev), BLKBSZGET, &dev->block_size) < 0) {
+ if (ioctl(fd, BLKBSZGET, &dev->block_size) < 0) {
log_sys_error("ioctl BLKBSZGET", name);
r = 0;
goto out;
#ifdef BLKPBSZGET
/* BLKPBSZGET is available in kernel >= 2.6.32 only */
if (dev->phys_block_size == -1) {
- if (ioctl(dev_fd(dev), BLKPBSZGET, &dev->phys_block_size) < 0) {
+ if (ioctl(fd, BLKPBSZGET, &dev->phys_block_size) < 0) {
log_sys_error("ioctl BLKPBSZGET", name);
r = 0;
goto out;
#elif defined (BLKSSZGET)
/* if we can't get physical block size, just use logical block size instead */
if (dev->phys_block_size == -1) {
- if (ioctl(dev_fd(dev), BLKSSZGET, &dev->phys_block_size) < 0) {
+ if (ioctl(fd, BLKSSZGET, &dev->phys_block_size) < 0) {
log_sys_error("ioctl BLKSSZGET", name);
r = 0;
goto out;
*physical_block_size = (unsigned int) dev->phys_block_size;
*block_size = (unsigned int) dev->block_size;
out:
- if (needs_open && !dev_close_immediate(dev))
+ if (do_close && !dev_close_immediate(dev))
stack;
return r;