Commit 525d15e8 authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov
Browse files

ceph: check inode type for CEPH_CAP_FILE_{CACHE,RD,REXTEND,LAZYIO}



These bits will have new meaning for directory inodes.

Signed-off-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent f85122af
Loading
Loading
Loading
Loading
+32 −12
Original line number Diff line number Diff line
@@ -573,7 +573,8 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
	 * Each time we receive FILE_CACHE anew, we increment
	 * i_rdcache_gen.
	 */
	if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) &&
	if (S_ISREG(ci->vfs_inode.i_mode) &&
	    (issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) &&
	    (had & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0) {
		ci->i_rdcache_gen++;
	}
@@ -958,7 +959,7 @@ int __ceph_caps_used(struct ceph_inode_info *ci)
	if (ci->i_rd_ref)
		used |= CEPH_CAP_FILE_RD;
	if (ci->i_rdcache_ref ||
	    (!S_ISDIR(ci->vfs_inode.i_mode) && /* ignore readdir cache */
	    (S_ISREG(ci->vfs_inode.i_mode) &&
	     ci->vfs_inode.i_data.nrpages))
		used |= CEPH_CAP_FILE_CACHE;
	if (ci->i_wr_ref)
@@ -985,6 +986,20 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
	return ceph_caps_for_mode(bits >> 1);
}

/*
 * wanted, by virtue of open file modes AND cap refs (buffered/cached data)
 */
int __ceph_caps_wanted(struct ceph_inode_info *ci)
{
	int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
	if (!S_ISDIR(ci->vfs_inode.i_mode)) {
		/* we want EXCL if dirty data */
		if (w & CEPH_CAP_FILE_BUFFER)
			w |= CEPH_CAP_FILE_EXCL;
	}
	return w;
}

/*
 * Return caps we have registered with the MDS(s) as 'wanted'.
 */
@@ -1903,7 +1918,7 @@ retry_locked:
	 * If we fail, it's because pages are locked.... try again later.
	 */
	if ((!no_delay || mdsc->stopping) &&
	    !S_ISDIR(inode->i_mode) &&		/* ignore readdir cache */
	    S_ISREG(inode->i_mode) &&
	    !(ci->i_wb_ref || ci->i_wrbuffer_ref) &&   /* no dirty pages... */
	    inode->i_data.nrpages &&		/* have cached pages */
	    (revoking & (CEPH_CAP_FILE_CACHE|
@@ -2635,7 +2650,8 @@ again:
				snap_rwsem_locked = true;
			}
			*got = need | (have & want);
			if ((need & CEPH_CAP_FILE_RD) &&
			if (S_ISREG(inode->i_mode) &&
			    (need & CEPH_CAP_FILE_RD) &&
			    !(*got & CEPH_CAP_FILE_CACHE))
				ceph_disable_fscache_readpage(ci);
			__take_cap_refs(ci, *got, true);
@@ -2643,7 +2659,8 @@ again:
		}
	} else {
		int session_readonly = false;
		if ((need & CEPH_CAP_FILE_WR) && ci->i_auth_cap) {
		if (ci->i_auth_cap &&
		    (need & (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_EXCL))) {
			struct ceph_mds_session *s = ci->i_auth_cap->session;
			spin_lock(&s->s_cap_lock);
			session_readonly = s->s_readonly;
@@ -2817,7 +2834,8 @@ int ceph_get_caps(struct file *filp, int need, int want,
			return ret;
		}

		if (ci->i_inline_version != CEPH_INLINE_NONE &&
		if (S_ISREG(ci->vfs_inode.i_mode) &&
		    ci->i_inline_version != CEPH_INLINE_NONE &&
		    (_got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) &&
		    i_size_read(inode) > 0) {
			struct page *page =
@@ -2850,7 +2868,8 @@ int ceph_get_caps(struct file *filp, int need, int want,
		break;
	}

	if ((_got & CEPH_CAP_FILE_RD) && (_got & CEPH_CAP_FILE_CACHE))
	if (S_ISREG(ci->vfs_inode.i_mode) &&
	    (_got & CEPH_CAP_FILE_RD) && (_got & CEPH_CAP_FILE_CACHE))
		ceph_fscache_revalidate_cookie(ci);

	*got = _got;
@@ -3140,7 +3159,7 @@ static void handle_cap_grant(struct inode *inode,
	 * try to invalidate (once).  (If there are dirty buffers, we
	 * will invalidate _after_ writeback.)
	 */
	if (!S_ISDIR(inode->i_mode) && /* don't invalidate readdir cache */
	if (S_ISREG(inode->i_mode) && /* don't invalidate readdir cache */
	    ((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) &&
	    (newcaps & CEPH_CAP_FILE_LAZYIO) == 0 &&
	    !(ci->i_wrbuffer_ref || ci->i_wb_ref)) {
@@ -3304,11 +3323,12 @@ static void handle_cap_grant(struct inode *inode,
		     ceph_cap_string(cap->issued),
		     ceph_cap_string(newcaps),
		     ceph_cap_string(revoking));
		if (revoking & used & CEPH_CAP_FILE_BUFFER)
		if (S_ISREG(inode->i_mode) &&
		    (revoking & used & CEPH_CAP_FILE_BUFFER))
			writeback = true;  /* initiate writeback; will delay ack */
		else if (revoking == CEPH_CAP_FILE_CACHE &&
			 (newcaps & CEPH_CAP_FILE_LAZYIO) == 0 &&
			 queue_invalidate)
		else if (queue_invalidate &&
			 revoking == CEPH_CAP_FILE_CACHE &&
			 (newcaps & CEPH_CAP_FILE_LAZYIO) == 0)
			; /* do nothing yet, invalidation will be queued */
		else if (cap == ci->i_auth_cap)
			check_caps = 1; /* check auth cap only */
+2 −1
Original line number Diff line number Diff line
@@ -1776,7 +1776,8 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
	}
	/* The inode has cached pages, but it's no longer used.
	 * we can safely drop it */
	if (wanted == 0 && used == CEPH_CAP_FILE_CACHE &&
	if (S_ISREG(inode->i_mode) &&
	    wanted == 0 && used == CEPH_CAP_FILE_CACHE &&
	    !(oissued & CEPH_CAP_FILE_CACHE)) {
	  used = 0;
	  oissued = 0;
+1 −11
Original line number Diff line number Diff line
@@ -675,17 +675,7 @@ extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask);
extern int __ceph_caps_used(struct ceph_inode_info *ci);

extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci);

/*
 * wanted, by virtue of open file modes AND cap refs (buffered/cached data)
 */
static inline int __ceph_caps_wanted(struct ceph_inode_info *ci)
{
	int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
	if (w & CEPH_CAP_FILE_BUFFER)
		w |= CEPH_CAP_FILE_EXCL;  /* we want EXCL if dirty data */
	return w;
}
extern int __ceph_caps_wanted(struct ceph_inode_info *ci);

/* what the mds thinks we want */
extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci, bool check);