Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Xiubo Li and committed by
Ilya Dryomov
e027ddb6 842d6b01

+6 -4
+3 -2
fs/ceph/caps.c
··· 1978 1978 } 1979 1979 1980 1980 dout("check_caps %llx.%llx file_want %s used %s dirty %s flushing %s" 1981 - " issued %s revoking %s retain %s %s%s\n", ceph_vinop(inode), 1981 + " issued %s revoking %s retain %s %s%s%s\n", ceph_vinop(inode), 1982 1982 ceph_cap_string(file_wanted), 1983 1983 ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps), 1984 1984 ceph_cap_string(ci->i_flushing_caps), 1985 1985 ceph_cap_string(issued), ceph_cap_string(revoking), 1986 1986 ceph_cap_string(retain), 1987 1987 (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "", 1988 - (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : ""); 1988 + (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "", 1989 + (flags & CHECK_CAPS_NOINVAL) ? " NOINVAL" : ""); 1989 1990 1990 1991 /* 1991 1992 * If we no longer need to hold onto old our caps, and we may
+3 -2
fs/ceph/file.c
··· 1912 1912 if (dirty) 1913 1913 __mark_inode_dirty(inode, dirty); 1914 1914 if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos)) 1915 - ceph_check_caps(ci, 0, NULL); 1915 + ceph_check_caps(ci, CHECK_CAPS_FLUSH, NULL); 1916 1916 } 1917 1917 1918 1918 dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n", ··· 2529 2529 /* Let the MDS know about dst file size change */ 2530 2530 if (ceph_inode_set_size(dst_inode, dst_off) || 2531 2531 ceph_quota_is_max_bytes_approaching(dst_inode, dst_off)) 2532 - ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY, NULL); 2532 + ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_FLUSH, 2533 + NULL); 2533 2534 } 2534 2535 /* Mark Fw dirty */ 2535 2536 spin_lock(&dst_ci->i_ceph_lock);