Exemple #1
0
static int _native_check_pv_min_size(struct device *dev)
{
	uint64_t size;
	int ret = 0;

	/* Check it's accessible */
	if (!dev_open_readonly_quiet(dev)) {
		log_debug_devs("%s: Skipping: open failed", dev_name(dev));
		return 0;
	}

	/* Check it's not too small */
	if (!dev_get_size(dev, &size)) {
		log_debug_devs("%s: Skipping: dev_get_size failed", dev_name(dev));
		goto out;
	}

	if (size < pv_min_size()) {
		log_debug_devs("%s: Skipping: %s", dev_name(dev),
				_too_small_to_hold_pv_msg);
		goto out;
	}

	ret = 1;
out:
	if (!dev_close(dev))
		stack;

	return ret;
}
Exemple #2
0
static int _udev_check_pv_min_size(struct device *dev)
{
	struct dev_ext *ext;
	const char *size_str;
	char *endp;
	uint64_t size;

	if (!(ext = dev_ext_get(dev)))
		return_0;

	if (!(size_str = udev_device_get_sysattr_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_SYSFS_ATTR_SIZE))) {
		log_debug_devs("%s: Skipping: failed to get size from sysfs [%s:%p]",
				dev_name(dev), dev_ext_name(dev), dev->ext.handle);
		return 0;
	}

	errno = 0;
	size = strtoull(size_str, &endp, 10);
	if (errno || !endp || *endp) {
		log_debug_devs("%s: Skipping: failed to parse size from sysfs [%s:%p]",
				dev_name(dev), dev_ext_name(dev), dev->ext.handle);
		return 0;
	}

	if (size < pv_min_size()) {
		log_debug_devs("%s: Skipping: %s [%s:%p]", dev_name(dev),
				_too_small_to_hold_pv_msg,
				dev_ext_name(dev), dev->ext.handle);
		return 0;
	}

	return 1;
}
Exemple #3
0
static int _dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64_t size_bytes)
{
	uint64_t discard_range[2];

	if (!dev_open(dev))
		return_0;

	discard_range[0] = offset_bytes;
	discard_range[1] = size_bytes;

	log_debug_devs("Discarding %" PRIu64 " bytes offset %" PRIu64 " bytes on %s.",
		       size_bytes, offset_bytes, dev_name(dev));
	if (ioctl(dev->fd, BLKDISCARD, &discard_range) < 0) {
		log_error("%s: BLKDISCARD ioctl at offset %" PRIu64 " size %" PRIu64 " failed: %s.",
			  dev_name(dev), offset_bytes, size_bytes, strerror(errno));
		if (!dev_close(dev))
			stack;
		/* It doesn't matter if discard failed, so return success. */
		return 1;
	}

	if (!dev_close(dev))
		stack;

	return 1;
}
Exemple #4
0
struct dev_ext *dev_ext_get(struct device *dev)
{
	struct dev_ext *ext;
	void *handle_ptr;

	handle_ptr = dev->ext.handle;

	if (!(ext = _ext_registry[dev->ext.src].dev_ext_get(dev)))
		log_error("Failed to get external handle for device %s [%s].",
			   dev_name(dev), dev_ext_name(dev));
	else if (handle_ptr != dev->ext.handle)
		log_debug_devs("%s %s [%s:%p]", _ext_attached_msg, dev_name(dev),
				dev_ext_name(dev), dev->ext.handle);

	return ext;
}
Exemple #5
0
static void _close(struct device *dev)
{
	if (close(dev->fd))
		log_sys_error("close", dev_name(dev));
	dev->fd = -1;
	dev->block_size = -1;
	dm_list_del(&dev->open_list);

	log_debug_devs("Closed %s", dev_name(dev));

	if (dev->flags & DEV_ALLOCED) {
		dm_free((void *) dm_list_item(dev->aliases.n, struct str_list)->
			 str);
		dm_free(dev->aliases.n);
		dm_free(dev);
	}
Exemple #6
0
/*
 * Get the sector size from an _open_ device.
 */
static int _get_block_size(struct device *dev, unsigned int *size)
{
	const char *name = dev_name(dev);

	if (dev->block_size == -1) {
		if (ioctl(dev_fd(dev), BLKBSZGET, &dev->block_size) < 0) {
			log_sys_error("ioctl BLKBSZGET", name);
			return 0;
		}
		log_debug_devs("%s: block size is %u bytes", name, dev->block_size);
	}

	*size = (unsigned int) dev->block_size;

	return 1;
}
Exemple #7
0
int dev_ext_release(struct device *dev)
{
	int r;
	void *handle_ptr;

	if (!dev->ext.enabled ||
	    !dev->ext.handle)
		return 1;

	handle_ptr = dev->ext.handle;

	if (!(r = _ext_registry[dev->ext.src].dev_ext_release(dev)))
		log_error("Failed to release external handle for device %s [%s:%p].",
			  dev_name(dev), dev_ext_name(dev), dev->ext.handle);
	else
		log_debug_devs("External handle detached from device %s [%s:%p]",
				dev_name(dev), dev_ext_name(dev), handle_ptr);

	return r;
}
Exemple #8
0
static int _native_dev_is_partitioned(struct dev_types *dt, struct device *dev)
{
	int r;

	if (!_is_partitionable(dt, dev))
		return 0;

	/* Unpartitioned DASD devices are not supported. */
	if (MAJOR(dev->dev) == dt->dasd_major)
		return 1;

	if (!dev_open_readonly_quiet(dev)) {
		log_debug_devs("%s: failed to open device, considering device "
			       "is partitioned", dev_name(dev));
		return 1;
	}

	r = _has_partition_table(dev);

	if (!dev_close(dev))
		stack;

	return r;
}
Exemple #9
0
int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
{
	struct stat buf;
	const char *name;
	int need_excl = 0, need_rw = 0;

	if ((flags & O_ACCMODE) == O_RDWR)
		need_rw = 1;

	if ((flags & O_EXCL))
		need_excl = 1;

	if (dev->fd >= 0) {
		if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
		    ((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
			dev->open_count++;
			return 1;
		}

		if (dev->open_count && !need_excl) {
			log_debug_devs("%s already opened read-only. Upgrading "
				       "to read-write.", dev_name(dev));
			dev->open_count++;
		}

		dev_close_immediate(dev);
		// FIXME: dev with DEV_ALLOCED is released
		// but code is referencing it
	}

	if (critical_section())
		/* FIXME Make this log_error */
		log_verbose("dev_open(%s) called while suspended",
			    dev_name(dev));

	if (dev->flags & DEV_REGULAR)
		name = dev_name(dev);
	else if (!(name = dev_name_confirmed(dev, quiet)))
		return_0;

#ifdef O_DIRECT_SUPPORT
	if (direct) {
		if (!(dev->flags & DEV_O_DIRECT_TESTED))
			dev->flags |= DEV_O_DIRECT;

		if ((dev->flags & DEV_O_DIRECT))
			flags |= O_DIRECT;
	}
#endif

#ifdef O_NOATIME
	/* Don't update atime on device inodes */
	if (!(dev->flags & DEV_REGULAR))
		flags |= O_NOATIME;
#endif

	if ((dev->fd = open(name, flags, 0777)) < 0) {
#ifdef O_DIRECT_SUPPORT
		if (direct && !(dev->flags & DEV_O_DIRECT_TESTED)) {
			flags &= ~O_DIRECT;
			if ((dev->fd = open(name, flags, 0777)) >= 0) {
				dev->flags &= ~DEV_O_DIRECT;
				log_debug_devs("%s: Not using O_DIRECT", name);
				goto opened;
			}
		}
#endif
		if (quiet)
			log_sys_debug("open", name);
		else
			log_sys_error("open", name);
		return 0;
	}

#ifdef O_DIRECT_SUPPORT
      opened:
	if (direct)
		dev->flags |= DEV_O_DIRECT_TESTED;
#endif
	dev->open_count++;
	dev->flags &= ~DEV_ACCESSED_W;

	if (need_rw)
		dev->flags |= DEV_OPENED_RW;
	else
		dev->flags &= ~DEV_OPENED_RW;

	if (need_excl)
		dev->flags |= DEV_OPENED_EXCL;
	else
		dev->flags &= ~DEV_OPENED_EXCL;

	if (!(dev->flags & DEV_REGULAR) &&
	    ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
		log_error("%s: fstat failed: Has device name changed?", name);
		dev_close_immediate(dev);
		return 0;
	}

#ifndef O_DIRECT_SUPPORT
	if (!(dev->flags & DEV_REGULAR))
		dev_flush(dev);
#endif

	if ((flags & O_CREAT) && !(flags & O_TRUNC))
		dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);

	dm_list_add(&_open_devices, &dev->open_list);

	log_debug_devs("Opened %s %s%s%s", dev_name(dev),
		       dev->flags & DEV_OPENED_RW ? "RW" : "RO",
		       dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
		       dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");

	return 1;
}