ceph: check inode type for CEPH_CAP_FILE_{CACHE,RD,REXTEND,LAZYIO}
These bits will have new meaning for directory inodes. Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
f85122afeb
commit
525d15e8e5
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user