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

Commit 40889e8d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull Ceph update from Sage Weil:
 "There are a few different groups of commits here.  The largest is
  Alex's ongoing work to enable the coming RBD features (cloning,
  striping).  There is some cleanup in libceph that goes along with it.

  Cyril and David have fixed some problems with NFS reexport (leaking
  dentries and page locks), and there is a batch of patches from Yan
  fixing problems with the fs client when running against a clustered
  MDS.  There are a few bug fixes mixed in for good measure, many of
  which will be going to the stable trees once they're upstream.

  My apologies for the late pull.  There is still a gremlin in the rbd
  map/unmap code and I was hoping to include the fix for that as well,
  but we haven't been able to confirm the fix is correct yet; I'll send
  that in a separate pull once it's nailed down."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (68 commits)
  rbd: get rid of rbd_{get,put}_dev()
  libceph: register request before unregister linger
  libceph: don't use rb_init_node() in ceph_osdc_alloc_request()
  libceph: init event->node in ceph_osdc_create_event()
  libceph: init osd->o_node in create_osd()
  libceph: report connection fault with warning
  libceph: socket can close in any connection state
  rbd: don't use ENOTSUPP
  rbd: remove linger unconditionally
  rbd: get rid of RBD_MAX_SEG_NAME_LEN
  libceph: avoid using freed osd in __kick_osd_requests()
  ceph: don't reference req after put
  rbd: do not allow remove of mounted-on image
  libceph: Unlock unprocessed pages in start_read() error path
  ceph: call handle_cap_grant() for cap import message
  ceph: Fix __ceph_do_pending_vmtruncate
  ceph: Don't add dirty inode to dirty list if caps is in migration
  ceph: Fix infinite loop in __wake_requests
  ceph: Don't update i_max_size when handling non-auth cap
  bdi_register: add __printf verification, fix arg mismatch
  ...
parents 1ca22254 c3e946ce
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -70,6 +70,10 @@ snap_*

	A directory per each snapshot

parent

	Information identifying the pool, image, and snapshot id for
	the parent image in a layered rbd image (format 2 only).

Entries under /sys/bus/rbd/devices/<dev-id>/snap_<snap-name>
-------------------------------------------------------------
+963 −426

File changed.

Preview size limit exceeded, changes collapsed.

+0 −2
Original line number Diff line number Diff line
@@ -46,8 +46,6 @@
#define RBD_MIN_OBJ_ORDER       16
#define RBD_MAX_OBJ_ORDER       30

#define RBD_MAX_SEG_NAME_LEN	128

#define RBD_COMP_NONE		0
#define RBD_CRYPT_NONE		0

+56 −4
Original line number Diff line number Diff line
@@ -267,6 +267,14 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg)
	kfree(req->r_pages);
}

static void ceph_unlock_page_vector(struct page **pages, int num_pages)
{
	int i;

	for (i = 0; i < num_pages; i++)
		unlock_page(pages[i]);
}

/*
 * start an async read(ahead) operation.  return nr_pages we submitted
 * a read for on success, or negative error code.
@@ -347,6 +355,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
	return nr_pages;

out_pages:
	ceph_unlock_page_vector(pages, nr_pages);
	ceph_release_page_vector(pages, nr_pages);
out:
	ceph_osdc_put_request(req);
@@ -1078,23 +1087,51 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
			    struct page **pagep, void **fsdata)
{
	struct inode *inode = file->f_dentry->d_inode;
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_file_info *fi = file->private_data;
	struct page *page;
	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
	int r;
	int r, want, got = 0;

	if (fi->fmode & CEPH_FILE_MODE_LAZY)
		want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
	else
		want = CEPH_CAP_FILE_BUFFER;

	dout("write_begin %p %llx.%llx %llu~%u getting caps. i_size %llu\n",
	     inode, ceph_vinop(inode), pos, len, inode->i_size);
	r = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, &got, pos+len);
	if (r < 0)
		return r;
	dout("write_begin %p %llx.%llx %llu~%u  got cap refs on %s\n",
	     inode, ceph_vinop(inode), pos, len, ceph_cap_string(got));
	if (!(got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO))) {
		ceph_put_cap_refs(ci, got);
		return -EAGAIN;
	}

	do {
		/* get a page */
		page = grab_cache_page_write_begin(mapping, index, 0);
		if (!page)
			return -ENOMEM;
		*pagep = page;
		if (!page) {
			r = -ENOMEM;
			break;
		}

		dout("write_begin file %p inode %p page %p %d~%d\n", file,
		     inode, page, (int)pos, (int)len);

		r = ceph_update_writeable_page(file, pos, len, page);
		if (r)
			page_cache_release(page);
	} while (r == -EAGAIN);

	if (r) {
		ceph_put_cap_refs(ci, got);
	} else {
		*pagep = page;
		*(int *)fsdata = got;
	}
	return r;
}

@@ -1108,10 +1145,12 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
			  struct page *page, void *fsdata)
{
	struct inode *inode = file->f_dentry->d_inode;
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
	struct ceph_mds_client *mdsc = fsc->mdsc;
	unsigned from = pos & (PAGE_CACHE_SIZE - 1);
	int check_cap = 0;
	int got = (unsigned long)fsdata;

	dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
	     inode, page, (int)pos, (int)copied, (int)len);
@@ -1134,6 +1173,19 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
	up_read(&mdsc->snap_rwsem);
	page_cache_release(page);

	if (copied > 0) {
		int dirty;
		spin_lock(&ci->i_ceph_lock);
		dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
		spin_unlock(&ci->i_ceph_lock);
		if (dirty)
			__mark_inode_dirty(inode, dirty);
	}

	dout("write_end %p %llx.%llx %llu~%u  dropping cap refs on %s\n",
	     inode, ceph_vinop(inode), pos, len, ceph_cap_string(got));
	ceph_put_cap_refs(ci, got);

	if (check_cap)
		ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL);

+12 −6
Original line number Diff line number Diff line
@@ -236,8 +236,10 @@ static struct ceph_cap *get_cap(struct ceph_mds_client *mdsc,
	if (!ctx) {
		cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
		if (cap) {
			spin_lock(&mdsc->caps_list_lock);
			mdsc->caps_use_count++;
			mdsc->caps_total_count++;
			spin_unlock(&mdsc->caps_list_lock);
		}
		return cap;
	}
@@ -1349,11 +1351,15 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
		if (!ci->i_head_snapc)
			ci->i_head_snapc = ceph_get_snap_context(
				ci->i_snap_realm->cached_context);
		dout(" inode %p now dirty snapc %p\n", &ci->vfs_inode,
			ci->i_head_snapc);
		dout(" inode %p now dirty snapc %p auth cap %p\n",
		     &ci->vfs_inode, ci->i_head_snapc, ci->i_auth_cap);
		BUG_ON(!list_empty(&ci->i_dirty_item));
		spin_lock(&mdsc->cap_dirty_lock);
		if (ci->i_auth_cap)
			list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
		else
			list_add(&ci->i_dirty_item,
				 &mdsc->cap_dirty_migrating);
		spin_unlock(&mdsc->cap_dirty_lock);
		if (ci->i_flushing_caps == 0) {
			ihold(inode);
@@ -2388,7 +2394,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
			    &atime);

	/* max size increase? */
	if (max_size != ci->i_max_size) {
	if (ci->i_auth_cap == cap && max_size != ci->i_max_size) {
		dout("max_size %lld -> %llu\n", ci->i_max_size, max_size);
		ci->i_max_size = max_size;
		if (max_size >= ci->i_wanted_max_size) {
@@ -2745,6 +2751,7 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,

	/* make sure we re-request max_size, if necessary */
	spin_lock(&ci->i_ceph_lock);
	ci->i_wanted_max_size = 0;  /* reset */
	ci->i_requested_max_size = 0;
	spin_unlock(&ci->i_ceph_lock);
}
@@ -2840,8 +2847,6 @@ void ceph_handle_caps(struct ceph_mds_session *session,
	case CEPH_CAP_OP_IMPORT:
		handle_cap_import(mdsc, inode, h, session,
				  snaptrace, snaptrace_len);
		ceph_check_caps(ceph_inode(inode), 0, session);
		goto done_unlocked;
	}

	/* the rest require a cap */
@@ -2858,6 +2863,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
	switch (op) {
	case CEPH_CAP_OP_REVOKE:
	case CEPH_CAP_OP_GRANT:
	case CEPH_CAP_OP_IMPORT:
		handle_cap_grant(inode, h, session, cap, msg->middle);
		goto done_unlocked;

Loading