ceph: fix request max size
ceph_check_caps() requests new max size only when there is Fw cap. If we call check_max_size() while there is no Fw cap. It updates i_wanted_max_size and calls ceph_check_caps(), but ceph_check_caps() does nothing. Later when Fw cap is issued, we call check_max_size() again. But i_wanted_max_size is equal to 'endoff' at this time, so check_max_size() doesn't call ceph_check_caps() and we end up with waiting for the new max size forever. The fix is duplicate ceph_check_caps()'s "request max size" code in check_max_size(), and make try_get_cap_refs() wait for the Fw cap before retry requesting new max size. This patch also removes the "endoff > (inode->i_size << 1)" check in check_max_size(). It's useless because there is no corresponding logic in ceph_check_caps(). Reviewed-by: Sage Weil <sage@inktank.com> Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
This commit is contained in:
parent
b0d7c22310
commit
3871cbb9a4
@ -2076,11 +2076,13 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
|
||||
spin_lock(&ci->i_ceph_lock);
|
||||
}
|
||||
|
||||
if (need & CEPH_CAP_FILE_WR) {
|
||||
have = __ceph_caps_issued(ci, &implemented);
|
||||
|
||||
if (have & need & CEPH_CAP_FILE_WR) {
|
||||
if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) {
|
||||
dout("get_cap_refs %p endoff %llu > maxsize %llu\n",
|
||||
inode, endoff, ci->i_max_size);
|
||||
if (endoff > ci->i_wanted_max_size) {
|
||||
if (endoff > ci->i_requested_max_size) {
|
||||
*check_max = 1;
|
||||
ret = 1;
|
||||
}
|
||||
@ -2095,7 +2097,6 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
have = __ceph_caps_issued(ci, &implemented);
|
||||
|
||||
if ((have & need) == need) {
|
||||
/*
|
||||
@ -2137,14 +2138,17 @@ static void check_max_size(struct inode *inode, loff_t endoff)
|
||||
|
||||
/* do we need to explicitly request a larger max_size? */
|
||||
spin_lock(&ci->i_ceph_lock);
|
||||
if ((endoff >= ci->i_max_size ||
|
||||
endoff > (inode->i_size << 1)) &&
|
||||
endoff > ci->i_wanted_max_size) {
|
||||
if (endoff >= ci->i_max_size && endoff > ci->i_wanted_max_size) {
|
||||
dout("write %p at large endoff %llu, req max_size\n",
|
||||
inode, endoff);
|
||||
ci->i_wanted_max_size = endoff;
|
||||
check = 1;
|
||||
}
|
||||
/* duplicate ceph_check_caps()'s logic */
|
||||
if (ci->i_auth_cap &&
|
||||
(ci->i_auth_cap->issued & CEPH_CAP_FILE_WR) &&
|
||||
ci->i_wanted_max_size > ci->i_max_size &&
|
||||
ci->i_wanted_max_size > ci->i_requested_max_size)
|
||||
check = 1;
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
if (check)
|
||||
ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user