Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 653f42f6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  ceph: add missing spin_unlock at ceph_mdsc_build_path()
  ceph: fix SEEK_CUR, SEEK_SET regression
  crush: fix mapping calculation when force argument doesn't exist
  ceph: use i_ceph_lock instead of i_lock
  rbd: remove buggy rollback functionality
  rbd: return an error when an invalid header is read
  ceph: fix rasize reporting by ceph_show_options
parents 4dde6ded 9d5a09e6
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -57,13 +57,6 @@ create_snap

	 $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create

rollback_snap

	Rolls back data to the specified snapshot. This goes over the entire
	list of rados blocks and sends a rollback command to each.

	 $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_rollback

snap_*

	A directory per each snapshot
+10 −91
Original line number Diff line number Diff line
@@ -183,10 +183,6 @@ static LIST_HEAD(rbd_client_list); /* clients */

static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
static void rbd_dev_release(struct device *dev);
static ssize_t rbd_snap_rollback(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf,
				 size_t size);
static ssize_t rbd_snap_add(struct device *dev,
			    struct device_attribute *attr,
			    const char *buf,
@@ -461,6 +457,10 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
	u32 snap_count = le32_to_cpu(ondisk->snap_count);
	int ret = -ENOMEM;

	if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT))) {
		return -ENXIO;
	}

	init_rwsem(&header->snap_rwsem);
	header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
	header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
@@ -1355,32 +1355,6 @@ fail:
	return ret;
}

/*
 * Request sync osd rollback
 */
static int rbd_req_sync_rollback_obj(struct rbd_device *dev,
				     u64 snapid,
				     const char *obj)
{
	struct ceph_osd_req_op *ops;
	int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_ROLLBACK, 0);
	if (ret < 0)
		return ret;

	ops[0].snap.snapid = snapid;

	ret = rbd_req_sync_op(dev, NULL,
			       CEPH_NOSNAP,
			       0,
			       CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
			       ops,
			       1, obj, 0, 0, NULL, NULL, NULL);

	rbd_destroy_ops(ops);

	return ret;
}

/*
 * Request sync osd read
 */
@@ -1610,8 +1584,13 @@ static int rbd_read_header(struct rbd_device *rbd_dev,
			goto out_dh;

		rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL);
		if (rc < 0)
		if (rc < 0) {
			if (rc == -ENXIO) {
				pr_warning("unrecognized header format"
					   " for image %s", rbd_dev->obj);
			}
			goto out_dh;
		}

		if (snap_count != header->total_snaps) {
			snap_count = header->total_snaps;
@@ -1882,7 +1861,6 @@ static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback);

static struct attribute *rbd_attrs[] = {
	&dev_attr_size.attr,
@@ -1893,7 +1871,6 @@ static struct attribute *rbd_attrs[] = {
	&dev_attr_current_snap.attr,
	&dev_attr_refresh.attr,
	&dev_attr_create_snap.attr,
	&dev_attr_rollback_snap.attr,
	NULL
};

@@ -2424,64 +2401,6 @@ err_unlock:
	return ret;
}

static ssize_t rbd_snap_rollback(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf,
				 size_t count)
{
	struct rbd_device *rbd_dev = dev_to_rbd(dev);
	int ret;
	u64 snapid;
	u64 cur_ofs;
	char *seg_name = NULL;
	char *snap_name = kmalloc(count + 1, GFP_KERNEL);
	ret = -ENOMEM;
	if (!snap_name)
		return ret;

	/* parse snaps add command */
	snprintf(snap_name, count, "%s", buf);
	seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
	if (!seg_name)
		goto done;

	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);

	ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL);
	if (ret < 0)
		goto done_unlock;

	dout("snapid=%lld\n", snapid);

	cur_ofs = 0;
	while (cur_ofs < rbd_dev->header.image_size) {
		cur_ofs += rbd_get_segment(&rbd_dev->header,
					   rbd_dev->obj,
					   cur_ofs, (u64)-1,
					   seg_name, NULL);
		dout("seg_name=%s\n", seg_name);

		ret = rbd_req_sync_rollback_obj(rbd_dev, snapid, seg_name);
		if (ret < 0)
			pr_warning("could not roll back obj %s err=%d\n",
				   seg_name, ret);
	}

	ret = __rbd_update_snaps(rbd_dev);
	if (ret < 0)
		goto done_unlock;

	ret = count;

done_unlock:
	mutex_unlock(&ctl_mutex);
done:
	kfree(seg_name);
	kfree(snap_name);

	return ret;
}

static struct bus_attribute rbd_bus_attrs[] = {
	__ATTR(add, S_IWUSR, NULL, rbd_add),
	__ATTR(remove, S_IWUSR, NULL, rbd_remove),
+4 −4
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ static int ceph_set_page_dirty(struct page *page)
	snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context);

	/* dirty the head */
	spin_lock(&inode->i_lock);
	spin_lock(&ci->i_ceph_lock);
	if (ci->i_head_snapc == NULL)
		ci->i_head_snapc = ceph_get_snap_context(snapc);
	++ci->i_wrbuffer_ref_head;
@@ -100,7 +100,7 @@ static int ceph_set_page_dirty(struct page *page)
	     ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref_head-1,
	     ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
	     snapc, snapc->seq, snapc->num_snaps);
	spin_unlock(&inode->i_lock);
	spin_unlock(&ci->i_ceph_lock);

	/* now adjust page */
	spin_lock_irq(&mapping->tree_lock);
@@ -391,7 +391,7 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode,
	struct ceph_snap_context *snapc = NULL;
	struct ceph_cap_snap *capsnap = NULL;

	spin_lock(&inode->i_lock);
	spin_lock(&ci->i_ceph_lock);
	list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
		dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap,
		     capsnap->context, capsnap->dirty_pages);
@@ -407,7 +407,7 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode,
		dout(" head snapc %p has %d dirty pages\n",
		     snapc, ci->i_wrbuffer_ref_head);
	}
	spin_unlock(&inode->i_lock);
	spin_unlock(&ci->i_ceph_lock);
	return snapc;
}

+94 −93

File changed.

Preview size limit exceeded, changes collapsed.

+12 −12

File changed.

Preview size limit exceeded, changes collapsed.

Loading