Loading fs/ceph/file.c +11 −0 Original line number Diff line number Diff line Loading @@ -1378,6 +1378,11 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) pos = iocb->ki_pos; count = iov_iter_count(from); if (ceph_quota_is_max_bytes_exceeded(inode, pos + count)) { err = -EDQUOT; goto out; } err = file_remove_privs(file); if (err) goto out; Loading Loading @@ -1708,6 +1713,12 @@ static long ceph_fallocate(struct file *file, int mode, goto unlock; } if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)) && ceph_quota_is_max_bytes_exceeded(inode, offset + length)) { ret = -EDQUOT; goto unlock; } if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) && !(mode & FALLOC_FL_PUNCH_HOLE)) { ret = -ENOSPC; Loading fs/ceph/inode.c +4 −0 Original line number Diff line number Diff line Loading @@ -2147,6 +2147,10 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if (err != 0) return err; if ((attr->ia_valid & ATTR_SIZE) && ceph_quota_is_max_bytes_exceeded(inode, attr->ia_size)) return -EDQUOT; err = __ceph_setattr(inode, attr); if (err >= 0 && (attr->ia_valid & ATTR_MODE)) Loading fs/ceph/quota.c +27 −1 Original line number Diff line number Diff line Loading @@ -134,7 +134,8 @@ 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_FILES_OP, /* check quota max_files limit */ QUOTA_CHECK_MAX_BYTES_OP /* check quota max_files limit */ }; /* Loading Loading @@ -171,6 +172,9 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op, if (op == QUOTA_CHECK_MAX_FILES_OP) { max = ci->i_max_files; rvalue = ci->i_rfiles + ci->i_rsubdirs; } else { max = ci->i_max_bytes; rvalue = ci->i_rbytes; } is_root = (ci->i_vino.ino == CEPH_INO_ROOT); spin_unlock(&ci->i_ceph_lock); Loading @@ -178,6 +182,9 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op, case QUOTA_CHECK_MAX_FILES_OP: exceeded = (max && (rvalue >= max)); break; case QUOTA_CHECK_MAX_BYTES_OP: exceeded = (max && (rvalue + delta > max)); break; default: /* Shouldn't happen */ pr_warn("Invalid quota check op (%d)\n", op); Loading Loading @@ -212,3 +219,22 @@ bool ceph_quota_is_max_files_exceeded(struct inode *inode) return check_quota_exceeded(inode, QUOTA_CHECK_MAX_FILES_OP, 0); } /* * ceph_quota_is_max_bytes_exceeded - check if we can write to a file * @inode: inode being written * @newsize: new size if write succeeds * * This functions returns true is max_bytes quota allows a file size to reach * @newsize; it returns false otherwise. */ bool ceph_quota_is_max_bytes_exceeded(struct inode *inode, loff_t newsize) { loff_t size = i_size_read(inode); /* return immediately if we're decreasing file size */ if (newsize <= size) return false; return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_OP, (newsize - size)); } fs/ceph/super.h +2 −0 Original line number Diff line number Diff line Loading @@ -1079,5 +1079,7 @@ extern void ceph_handle_quota(struct ceph_mds_client *mdsc, struct ceph_msg *msg); 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); #endif /* _FS_CEPH_SUPER_H */ Loading
fs/ceph/file.c +11 −0 Original line number Diff line number Diff line Loading @@ -1378,6 +1378,11 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) pos = iocb->ki_pos; count = iov_iter_count(from); if (ceph_quota_is_max_bytes_exceeded(inode, pos + count)) { err = -EDQUOT; goto out; } err = file_remove_privs(file); if (err) goto out; Loading Loading @@ -1708,6 +1713,12 @@ static long ceph_fallocate(struct file *file, int mode, goto unlock; } if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)) && ceph_quota_is_max_bytes_exceeded(inode, offset + length)) { ret = -EDQUOT; goto unlock; } if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) && !(mode & FALLOC_FL_PUNCH_HOLE)) { ret = -ENOSPC; Loading
fs/ceph/inode.c +4 −0 Original line number Diff line number Diff line Loading @@ -2147,6 +2147,10 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if (err != 0) return err; if ((attr->ia_valid & ATTR_SIZE) && ceph_quota_is_max_bytes_exceeded(inode, attr->ia_size)) return -EDQUOT; err = __ceph_setattr(inode, attr); if (err >= 0 && (attr->ia_valid & ATTR_MODE)) Loading
fs/ceph/quota.c +27 −1 Original line number Diff line number Diff line Loading @@ -134,7 +134,8 @@ 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_FILES_OP, /* check quota max_files limit */ QUOTA_CHECK_MAX_BYTES_OP /* check quota max_files limit */ }; /* Loading Loading @@ -171,6 +172,9 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op, if (op == QUOTA_CHECK_MAX_FILES_OP) { max = ci->i_max_files; rvalue = ci->i_rfiles + ci->i_rsubdirs; } else { max = ci->i_max_bytes; rvalue = ci->i_rbytes; } is_root = (ci->i_vino.ino == CEPH_INO_ROOT); spin_unlock(&ci->i_ceph_lock); Loading @@ -178,6 +182,9 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op, case QUOTA_CHECK_MAX_FILES_OP: exceeded = (max && (rvalue >= max)); break; case QUOTA_CHECK_MAX_BYTES_OP: exceeded = (max && (rvalue + delta > max)); break; default: /* Shouldn't happen */ pr_warn("Invalid quota check op (%d)\n", op); Loading Loading @@ -212,3 +219,22 @@ bool ceph_quota_is_max_files_exceeded(struct inode *inode) return check_quota_exceeded(inode, QUOTA_CHECK_MAX_FILES_OP, 0); } /* * ceph_quota_is_max_bytes_exceeded - check if we can write to a file * @inode: inode being written * @newsize: new size if write succeeds * * This functions returns true is max_bytes quota allows a file size to reach * @newsize; it returns false otherwise. */ bool ceph_quota_is_max_bytes_exceeded(struct inode *inode, loff_t newsize) { loff_t size = i_size_read(inode); /* return immediately if we're decreasing file size */ if (newsize <= size) return false; return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_OP, (newsize - size)); }
fs/ceph/super.h +2 −0 Original line number Diff line number Diff line Loading @@ -1079,5 +1079,7 @@ extern void ceph_handle_quota(struct ceph_mds_client *mdsc, struct ceph_msg *msg); 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); #endif /* _FS_CEPH_SUPER_H */