Skip to content

Commit

Permalink
ceph: quota: update MDS when max_bytes is approaching
Browse files Browse the repository at this point in the history
When we're reaching the ceph.quota.max_bytes limit, i.e., when writing
more than 1/16th of the space left in a quota realm, update the MDS with
the new file size.

This mirrors the fuse-client approach with commit 122c503 ("client:
Inform mds file size when approaching quota limit"), in the ceph git tree.

Signed-off-by: Luis Henriques <[email protected]>
Reviewed-by: "Yan, Zheng" <[email protected]>
Signed-off-by: Ilya Dryomov <[email protected]>
  • Loading branch information
Luis Henriques authored and idryomov committed Apr 2, 2018
1 parent 2b83845 commit 1ab302a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
6 changes: 6 additions & 0 deletions fs/ceph/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1464,13 +1464,16 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)

if (written >= 0) {
int dirty;

spin_lock(&ci->i_ceph_lock);
ci->i_inline_version = CEPH_INLINE_NONE;
dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR,
&prealloc_cf);
spin_unlock(&ci->i_ceph_lock);
if (dirty)
__mark_inode_dirty(inode, dirty);
if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos))
ceph_check_caps(ci, CHECK_CAPS_NODELAY, NULL);
}

dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n",
Expand Down Expand Up @@ -1767,6 +1770,9 @@ static long ceph_fallocate(struct file *file, int mode,
spin_unlock(&ci->i_ceph_lock);
if (dirty)
__mark_inode_dirty(inode, dirty);
if ((endoff > size) &&
ceph_quota_is_max_bytes_approaching(inode, endoff))
ceph_check_caps(ci, CHECK_CAPS_NODELAY, NULL);
}

ceph_put_cap_refs(ci, got);
Expand Down
38 changes: 37 additions & 1 deletion fs/ceph/quota.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ bool ceph_quota_is_same_realm(struct inode *old, struct inode *new)

enum quota_check_op {
QUOTA_CHECK_MAX_FILES_OP, /* check quota max_files limit */
QUOTA_CHECK_MAX_BYTES_OP /* check quota max_files limit */
QUOTA_CHECK_MAX_BYTES_OP, /* check quota max_files limit */
QUOTA_CHECK_MAX_BYTES_APPROACHING_OP /* check if quota max_files
limit is approaching */
};

/*
Expand Down Expand Up @@ -185,6 +187,20 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
case QUOTA_CHECK_MAX_BYTES_OP:
exceeded = (max && (rvalue + delta > max));
break;
case QUOTA_CHECK_MAX_BYTES_APPROACHING_OP:
if (max) {
if (rvalue >= max)
exceeded = true;
else {
/*
* when we're writing more that 1/16th
* of the available space
*/
exceeded =
(((max - rvalue) >> 4) < delta);
}
}
break;
default:
/* Shouldn't happen */
pr_warn("Invalid quota check op (%d)\n", op);
Expand Down Expand Up @@ -238,3 +254,23 @@ bool ceph_quota_is_max_bytes_exceeded(struct inode *inode, loff_t newsize)

return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_OP, (newsize - size));
}

/*
* ceph_quota_is_max_bytes_approaching - check if we're reaching max_bytes
* @inode: inode being written
* @newsize: new size if write succeeds
*
* This function returns true if the new file size @newsize will be consuming
* more than 1/16th of the available quota space; it returns false otherwise.
*/
bool ceph_quota_is_max_bytes_approaching(struct inode *inode, loff_t newsize)
{
loff_t size = ceph_inode(inode)->i_reported_size;

/* return immediately if we're decreasing file size */
if (newsize <= size)
return false;

return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_APPROACHING_OP,
(newsize - size));
}
2 changes: 2 additions & 0 deletions fs/ceph/super.h
Original file line number Diff line number Diff line change
Expand Up @@ -1081,5 +1081,7 @@ extern bool ceph_quota_is_max_files_exceeded(struct inode *inode);
extern bool ceph_quota_is_same_realm(struct inode *old, struct inode *new);
extern bool ceph_quota_is_max_bytes_exceeded(struct inode *inode,
loff_t newlen);
extern bool ceph_quota_is_max_bytes_approaching(struct inode *inode,
loff_t newlen);

#endif /* _FS_CEPH_SUPER_H */

0 comments on commit 1ab302a

Please sign in to comment.