static int zvol_open(struct block_device *bdev, fmode_t flag) { zvol_state_t *zv; int error = 0, drop_mutex = 0; /* * If the caller is already holding the mutex do not take it * again, this will happen as part of zvol_create_minor_impl(). * Once add_disk() is called the device is live and the kernel * will attempt to open it to read the partition information. */ if (!mutex_owned(&zvol_state_lock)) { mutex_enter(&zvol_state_lock); drop_mutex = 1; } /* * Obtain a copy of private_data under the lock to make sure * that either the result of zvol_freeg() setting * bdev->bd_disk->private_data to NULL is observed, or zvol_free() * is not called on this zv because of the positive zv_open_count. */ zv = bdev->bd_disk->private_data; if (zv == NULL) { error = -ENXIO; goto out_mutex; } if (zv->zv_open_count == 0) { error = zvol_first_open(zv); if (error) goto out_mutex; } if ((flag & FMODE_WRITE) && (zv->zv_flags & ZVOL_RDONLY)) { error = -EROFS; goto out_open_count; } zv->zv_open_count++; check_disk_change(bdev); out_open_count: if (zv->zv_open_count == 0) zvol_last_close(zv); out_mutex: if (drop_mutex) mutex_exit(&zvol_state_lock); return (SET_ERROR(error)); }
static int zvol_open(struct block_device *bdev, fmode_t flag) { zvol_state_t *zv = bdev->bd_disk->private_data; int error = 0, drop_mutex = 0; /* * If the caller is already holding the mutex do not take it * again, this will happen as part of zvol_create_minor(). * Once add_disk() is called the device is live and the kernel * will attempt to open it to read the partition information. */ if (!mutex_owned(&zvol_state_lock)) { mutex_enter(&zvol_state_lock); drop_mutex = 1; } ASSERT3P(zv, !=, NULL); if (zv->zv_open_count == 0) { error = zvol_first_open(zv); if (error) goto out_mutex; } if ((flag & FMODE_WRITE) && (get_disk_ro(zv->zv_disk) || (zv->zv_flags & ZVOL_RDONLY))) { error = -EROFS; goto out_open_count; } zv->zv_open_count++; out_open_count: if (zv->zv_open_count == 0) zvol_last_close(zv); out_mutex: if (drop_mutex) mutex_exit(&zvol_state_lock); check_disk_change(bdev); return (error); }