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

Commit 19746cad 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: select CRYPTO
  ceph: check mapping to determine if FILE_CACHE cap is used
  ceph: only send one flushsnap per cap_snap per mds session
  ceph: fix cap_snap and realm split
  ceph: stop sending FLUSHSNAPs when we hit a dirty capsnap
  ceph: correctly set 'follows' in flushsnap messages
  ceph: fix dn offset during readdir_prepopulate
  ceph: fix file offset wrapping at 4GB on 32-bit archs
  ceph: fix reconnect encoding for old servers
  ceph: fix pagelist kunmap tail
  ceph: fix null pointer deref on anon root dentry release
parents 0ffe37de be4f104d
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -3,6 +3,7 @@ config CEPH_FS
	depends on INET && EXPERIMENTAL
	depends on INET && EXPERIMENTAL
	select LIBCRC32C
	select LIBCRC32C
	select CRYPTO_AES
	select CRYPTO_AES
	select CRYPTO
	help
	help
	  Choose Y or M here to include support for mounting the
	  Choose Y or M here to include support for mounting the
	  experimental Ceph distributed file system.  Ceph is an extremely
	  experimental Ceph distributed file system.  Ceph is an extremely
+4 −3
Original line number Original line Diff line number Diff line
@@ -411,8 +411,8 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
	if (i_size < page_off + len)
	if (i_size < page_off + len)
		len = i_size - page_off;
		len = i_size - page_off;


	dout("writepage %p page %p index %lu on %llu~%u\n",
	dout("writepage %p page %p index %lu on %llu~%u snapc %p\n",
	     inode, page, page->index, page_off, len);
	     inode, page, page->index, page_off, len, snapc);


	writeback_stat = atomic_long_inc_return(&client->writeback_count);
	writeback_stat = atomic_long_inc_return(&client->writeback_count);
	if (writeback_stat >
	if (writeback_stat >
@@ -766,7 +766,8 @@ static int ceph_writepages_start(struct address_space *mapping,
			/* ok */
			/* ok */
			if (locked_pages == 0) {
			if (locked_pages == 0) {
				/* prepare async write request */
				/* prepare async write request */
				offset = page->index << PAGE_CACHE_SHIFT;
				offset = (unsigned long long)page->index
					<< PAGE_CACHE_SHIFT;
				len = wsize;
				len = wsize;
				req = ceph_osdc_new_request(&client->osdc,
				req = ceph_osdc_new_request(&client->osdc,
					    &ci->i_layout,
					    &ci->i_layout,
+19 −8
Original line number Original line Diff line number Diff line
@@ -814,7 +814,7 @@ int __ceph_caps_used(struct ceph_inode_info *ci)
		used |= CEPH_CAP_PIN;
		used |= CEPH_CAP_PIN;
	if (ci->i_rd_ref)
	if (ci->i_rd_ref)
		used |= CEPH_CAP_FILE_RD;
		used |= CEPH_CAP_FILE_RD;
	if (ci->i_rdcache_ref || ci->i_rdcache_gen)
	if (ci->i_rdcache_ref || ci->vfs_inode.i_data.nrpages)
		used |= CEPH_CAP_FILE_CACHE;
		used |= CEPH_CAP_FILE_CACHE;
	if (ci->i_wr_ref)
	if (ci->i_wr_ref)
		used |= CEPH_CAP_FILE_WR;
		used |= CEPH_CAP_FILE_WR;
@@ -1195,10 +1195,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
 * asynchronously back to the MDS once sync writes complete and dirty
 * asynchronously back to the MDS once sync writes complete and dirty
 * data is written out.
 * data is written out.
 *
 *
 * Unless @again is true, skip cap_snaps that were already sent to
 * the MDS (i.e., during this session).
 *
 * Called under i_lock.  Takes s_mutex as needed.
 * Called under i_lock.  Takes s_mutex as needed.
 */
 */
void __ceph_flush_snaps(struct ceph_inode_info *ci,
void __ceph_flush_snaps(struct ceph_inode_info *ci,
			struct ceph_mds_session **psession)
			struct ceph_mds_session **psession,
			int again)
		__releases(ci->vfs_inode->i_lock)
		__releases(ci->vfs_inode->i_lock)
		__acquires(ci->vfs_inode->i_lock)
		__acquires(ci->vfs_inode->i_lock)
{
{
@@ -1227,7 +1231,7 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci,
		 * pages to be written out.
		 * pages to be written out.
		 */
		 */
		if (capsnap->dirty_pages || capsnap->writing)
		if (capsnap->dirty_pages || capsnap->writing)
			continue;
			break;


		/*
		/*
		 * if cap writeback already occurred, we should have dropped
		 * if cap writeback already occurred, we should have dropped
@@ -1240,6 +1244,13 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci,
			dout("no auth cap (migrating?), doing nothing\n");
			dout("no auth cap (migrating?), doing nothing\n");
			goto out;
			goto out;
		}
		}

		/* only flush each capsnap once */
		if (!again && !list_empty(&capsnap->flushing_item)) {
			dout("already flushed %p, skipping\n", capsnap);
			continue;
		}

		mds = ci->i_auth_cap->session->s_mds;
		mds = ci->i_auth_cap->session->s_mds;
		mseq = ci->i_auth_cap->mseq;
		mseq = ci->i_auth_cap->mseq;


@@ -1276,8 +1287,8 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci,
			      &session->s_cap_snaps_flushing);
			      &session->s_cap_snaps_flushing);
		spin_unlock(&inode->i_lock);
		spin_unlock(&inode->i_lock);


		dout("flush_snaps %p cap_snap %p follows %lld size %llu\n",
		dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n",
		     inode, capsnap, next_follows, capsnap->size);
		     inode, capsnap, capsnap->follows, capsnap->flush_tid);
		send_cap_msg(session, ceph_vino(inode).ino, 0,
		send_cap_msg(session, ceph_vino(inode).ino, 0,
			     CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0,
			     CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0,
			     capsnap->dirty, 0, capsnap->flush_tid, 0, mseq,
			     capsnap->dirty, 0, capsnap->flush_tid, 0, mseq,
@@ -1314,7 +1325,7 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci)
	struct inode *inode = &ci->vfs_inode;
	struct inode *inode = &ci->vfs_inode;


	spin_lock(&inode->i_lock);
	spin_lock(&inode->i_lock);
	__ceph_flush_snaps(ci, NULL);
	__ceph_flush_snaps(ci, NULL, 0);
	spin_unlock(&inode->i_lock);
	spin_unlock(&inode->i_lock);
}
}


@@ -1477,7 +1488,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,


	/* flush snaps first time around only */
	/* flush snaps first time around only */
	if (!list_empty(&ci->i_cap_snaps))
	if (!list_empty(&ci->i_cap_snaps))
		__ceph_flush_snaps(ci, &session);
		__ceph_flush_snaps(ci, &session, 0);
	goto retry_locked;
	goto retry_locked;
retry:
retry:
	spin_lock(&inode->i_lock);
	spin_lock(&inode->i_lock);
@@ -1894,7 +1905,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
		if (cap && cap->session == session) {
		if (cap && cap->session == session) {
			dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
			dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
			     cap, capsnap);
			     cap, capsnap);
			__ceph_flush_snaps(ci, &session);
			__ceph_flush_snaps(ci, &session, 1);
		} else {
		} else {
			pr_err("%p auth cap %p not mds%d ???\n", inode,
			pr_err("%p auth cap %p not mds%d ???\n", inode,
			       cap, session->s_mds);
			       cap, session->s_mds);
+7 −3
Original line number Original line Diff line number Diff line
@@ -1021,11 +1021,15 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
static void ceph_dentry_release(struct dentry *dentry)
static void ceph_dentry_release(struct dentry *dentry)
{
{
	struct ceph_dentry_info *di = ceph_dentry(dentry);
	struct ceph_dentry_info *di = ceph_dentry(dentry);
	struct inode *parent_inode = dentry->d_parent->d_inode;
	struct inode *parent_inode = NULL;
	u64 snapid = ceph_snap(parent_inode);
	u64 snapid = CEPH_NOSNAP;


	if (!IS_ROOT(dentry)) {
		parent_inode = dentry->d_parent->d_inode;
		if (parent_inode)
			snapid = ceph_snap(parent_inode);
	}
	dout("dentry_release %p parent %p\n", dentry, parent_inode);
	dout("dentry_release %p parent %p\n", dentry, parent_inode);

	if (parent_inode && snapid != CEPH_SNAPDIR) {
	if (parent_inode && snapid != CEPH_SNAPDIR) {
		struct ceph_inode_info *ci = ceph_inode(parent_inode);
		struct ceph_inode_info *ci = ceph_inode(parent_inode);


+6 −5
Original line number Original line Diff line number Diff line
@@ -845,7 +845,7 @@ static void ceph_set_dentry_offset(struct dentry *dn)
 * the caller) if we fail.
 * the caller) if we fail.
 */
 */
static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
				    bool *prehash)
				    bool *prehash, bool set_offset)
{
{
	struct dentry *realdn;
	struct dentry *realdn;


@@ -877,6 +877,7 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
	}
	}
	if ((!prehash || *prehash) && d_unhashed(dn))
	if ((!prehash || *prehash) && d_unhashed(dn))
		d_rehash(dn);
		d_rehash(dn);
	if (set_offset)
		ceph_set_dentry_offset(dn);
		ceph_set_dentry_offset(dn);
out:
out:
	return dn;
	return dn;
@@ -1062,7 +1063,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
				d_delete(dn);
				d_delete(dn);
				goto done;
				goto done;
			}
			}
			dn = splice_dentry(dn, in, &have_lease);
			dn = splice_dentry(dn, in, &have_lease, true);
			if (IS_ERR(dn)) {
			if (IS_ERR(dn)) {
				err = PTR_ERR(dn);
				err = PTR_ERR(dn);
				goto done;
				goto done;
@@ -1105,7 +1106,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
			goto done;
			goto done;
		}
		}
		dout(" linking snapped dir %p to dn %p\n", in, dn);
		dout(" linking snapped dir %p to dn %p\n", in, dn);
		dn = splice_dentry(dn, in, NULL);
		dn = splice_dentry(dn, in, NULL, true);
		if (IS_ERR(dn)) {
		if (IS_ERR(dn)) {
			err = PTR_ERR(dn);
			err = PTR_ERR(dn);
			goto done;
			goto done;
@@ -1237,7 +1238,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
				err = PTR_ERR(in);
				err = PTR_ERR(in);
				goto out;
				goto out;
			}
			}
			dn = splice_dentry(dn, in, NULL);
			dn = splice_dentry(dn, in, NULL, false);
			if (IS_ERR(dn))
			if (IS_ERR(dn))
				dn = NULL;
				dn = NULL;
		}
		}
Loading