| 167 | } |
| 168 | |
| 169 | static int |
| 170 | vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, |
| 171 | uint64_t *logical_ashift, uint64_t *physical_ashift) |
| 172 | { |
| 173 | struct block_device *bdev; |
| 174 | fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); |
| 175 | hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms); |
| 176 | vdev_disk_t *vd; |
| 177 | |
| 178 | /* Must have a pathname and it must be absolute. */ |
| 179 | if (v->vdev_path == NULL || v->vdev_path[0] != '/') { |
| 180 | v->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; |
| 181 | vdev_dbgmsg(v, "invalid vdev_path"); |
| 182 | return (SET_ERROR(EINVAL)); |
| 183 | } |
| 184 | |
| 185 | /* |
| 186 | * Reopen the device if it is currently open. When expanding a |
| 187 | * partition force re-scanning the partition table if userland |
| 188 | * did not take care of this already. We need to do this while closed |
| 189 | * in order to get an accurate updated block device size. Then |
| 190 | * since udev may need to recreate the device links increase the |
| 191 | * open retry timeout before reporting the device as unavailable. |
| 192 | */ |
| 193 | vd = v->vdev_tsd; |
| 194 | if (vd) { |
| 195 | char disk_name[BDEVNAME_SIZE + 6] = "/dev/"; |
| 196 | boolean_t reread_part = B_FALSE; |
| 197 | |
| 198 | rw_enter(&vd->vd_lock, RW_WRITER); |
| 199 | bdev = vd->vd_bdev; |
| 200 | vd->vd_bdev = NULL; |
| 201 | |
| 202 | if (bdev) { |
| 203 | if (v->vdev_expanding && bdev != bdev_whole(bdev)) { |
| 204 | bdevname(bdev_whole(bdev), disk_name + 5); |
| 205 | /* |
| 206 | * If userland has BLKPG_RESIZE_PARTITION, |
| 207 | * then it should have updated the partition |
| 208 | * table already. We can detect this by |
| 209 | * comparing our current physical size |
| 210 | * with that of the device. If they are |
| 211 | * the same, then we must not have |
| 212 | * BLKPG_RESIZE_PARTITION or it failed to |
| 213 | * update the partition table online. We |
| 214 | * fallback to rescanning the partition |
| 215 | * table from the kernel below. However, |
| 216 | * if the capacity already reflects the |
| 217 | * updated partition, then we skip |
| 218 | * rescanning the partition table here. |
| 219 | */ |
| 220 | if (v->vdev_psize == bdev_capacity(bdev)) |
| 221 | reread_part = B_TRUE; |
| 222 | } |
| 223 | |
| 224 | blkdev_put(bdev, mode | FMODE_EXCL); |
| 225 | } |
| 226 |
nothing calls this directly
no test coverage detected