ceph: flush the dirty caps immediatelly when quota is approaching

When the quota is approaching we need to notify it to the MDS as
soon as possible, or the client could write to the directory more
than expected.

This will flush the dirty caps without delaying after each write,
though this couldn't prevent the real size of a directory exceed
the quota but could prevent it as soon as possible.

Link: https://tracker.ceph.com/issues/56180
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Luís Henriques <lhenriques@suse.de>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Xiubo Li 2022-06-23 17:17:21 +08:00 committed by Ilya Dryomov
parent 842d6b019b
commit e027ddb6d3
2 changed files with 6 additions and 4 deletions

View File

@ -1978,14 +1978,15 @@ retry:
} }
dout("check_caps %llx.%llx file_want %s used %s dirty %s flushing %s" dout("check_caps %llx.%llx file_want %s used %s dirty %s flushing %s"
" issued %s revoking %s retain %s %s%s\n", ceph_vinop(inode), " issued %s revoking %s retain %s %s%s%s\n", ceph_vinop(inode),
ceph_cap_string(file_wanted), ceph_cap_string(file_wanted),
ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps), ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps),
ceph_cap_string(ci->i_flushing_caps), ceph_cap_string(ci->i_flushing_caps),
ceph_cap_string(issued), ceph_cap_string(revoking), ceph_cap_string(issued), ceph_cap_string(revoking),
ceph_cap_string(retain), ceph_cap_string(retain),
(flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "", (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "",
(flags & CHECK_CAPS_FLUSH) ? " FLUSH" : ""); (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "",
(flags & CHECK_CAPS_NOINVAL) ? " NOINVAL" : "");
/* /*
* If we no longer need to hold onto old our caps, and we may * If we no longer need to hold onto old our caps, and we may

View File

@ -1912,7 +1912,7 @@ retry_snap:
if (dirty) if (dirty)
__mark_inode_dirty(inode, dirty); __mark_inode_dirty(inode, dirty);
if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos)) if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos))
ceph_check_caps(ci, 0, NULL); ceph_check_caps(ci, CHECK_CAPS_FLUSH, NULL);
} }
dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n", dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n",
@ -2529,7 +2529,8 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
/* Let the MDS know about dst file size change */ /* Let the MDS know about dst file size change */
if (ceph_inode_set_size(dst_inode, dst_off) || if (ceph_inode_set_size(dst_inode, dst_off) ||
ceph_quota_is_max_bytes_approaching(dst_inode, dst_off)) ceph_quota_is_max_bytes_approaching(dst_inode, dst_off))
ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY, NULL); ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_FLUSH,
NULL);
} }
/* Mark Fw dirty */ /* Mark Fw dirty */
spin_lock(&dst_ci->i_ceph_lock); spin_lock(&dst_ci->i_ceph_lock);