What shall read() return on deleted block device?

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

 



Hi Christoph and folks,

While debugging something else, we noticed a behavior change for the following
program:

    main()
    {
        fd = open("/dev/sdXX", O_RDWR | O_CLOEXEC);

        /* delete sdXX by echo 1 > /sys/block/sdXX/device/delete */
        sleep(10); /* to make sure delete finishes */

        ret = read(fd, buf, 4096);
        fprintf(stderr, "ret = %d errno = %d\n", ret, errno)
    }

On older kernel, we got
   ret = -1 errno = EIO;
while on newer kernel, we get
   ret = 0;

git-bisect points to [1]. However, I would not call it a bug caused by [1]. What
actually happens is:

In blkdev_read_iter(),we check
     size = bdev_nr_bytes(bdev);
     if (pos >= size)
          return 0;
     /* do the read, which may return -EIO */

Before [1], size is not set to 0 when the device is deleted.
Therefore, blkdev_read_iter
will not hit pos >= size, and return -EIO. After [1], size is set to
zero on device delete,
so blkdev_read_iter returns 0 after the delete.

I think this is not a bug, but a clear behavior change. However, no
one seems to care
after a year. So the question is, which behavior shall we keep for the
future. And, if we
want to go back to ret = -1, what's the proper fix?

Thanks,
Song

[1] commit a782483cc1f8 ("block: remove the nr_sects field in struct hd_struct")



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux