Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b83845f authored by Luis Henriques's avatar Luis Henriques Committed by Ilya Dryomov
Browse files

ceph: quota: support for ceph.quota.max_bytes

parent cafe21a4
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
+4 −0
Original line number Diff line number Diff line
@@ -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))
+27 −1
Original line number Diff line number Diff line
@@ -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 */
};

/*
@@ -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);
@@ -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);
@@ -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));
}
+2 −0
Original line number Diff line number Diff line
@@ -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 */