History

ceph: quota: report root dir quota usage in statfs

This commit changes statfs default behaviour when reporting usage statistics. Instead of using the overall filesystem usage, statfs now reports the quota for the filesystem root, if ceph.quota.max_bytes has been set for this inode. If quota hasn't been set, it falls back to the old statfs behaviour. A new mount option is also added ('noquotadf') to disable this behaviour.

Luis Henriques committed 8 years ago

Commit 9122eed1 parent d557c484 files · +87 −3Browse files

Unified · Split

4 files
  1. Documentation/filesystems/ceph.txt +4 −0
  2. fs/ceph/quota.c +56 −0
  3. fs/ceph/super.c +24 −3
  4. fs/ceph/super.h +3 −0
Documentation/filesystems/ceph.txt+4−0
@@ -149,6 +149,10 @@ Mount Options · 148 unmodified lines
149 noasyncreaddir149 noasyncreaddir
150 Do not use the dcache as above for readdir.150 Do not use the dcache as above for readdir.
151 151
152 noquotadf
153 Report overall filesystem usage in statfs instead of using the root
154 directory quota.
155
152More Information156More Information
153================157================
154 158
fs/ceph/quota.c+56−0
@@ -18,6 +18,8 @@ · 17 unmodified lines
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */19 */
20 20
21#include <linux/statfs.h>
22
21#include "super.h"23#include "super.h"
22#include "mds_client.h"24#include "mds_client.h"
23 25
@@ -303,3 +305,57 @@ bool ceph_quota_is_max_bytes_approaching(struct inode *inode, loff_t newsize) · 279 unmodified lines
303 return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_APPROACHING_OP,305 return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_APPROACHING_OP,
304 (newsize - size));306 (newsize - size));
305}307}
308
309/*
310 * ceph_quota_update_statfs - if root has quota update statfs with quota status
311 * @fsc: filesystem client instance
312 * @buf: statfs to update
313 *
314 * If the mounted filesystem root has max_bytes quota set, update the filesystem
315 * statistics with the quota status.
316 *
317 * This function returns true if the stats have been updated, false otherwise.
318 */
319bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf)
320{
321 struct ceph_mds_client *mdsc = fsc->mdsc;
322 struct ceph_inode_info *ci;
323 struct ceph_snap_realm *realm;
324 struct inode *in;
325 u64 total = 0, used, free;
326 bool is_updated = false;
327
328 down_read(&mdsc->snap_rwsem);
329 realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root));
330 up_read(&mdsc->snap_rwsem);
331 if (!realm)
332 return false;
333
334 spin_lock(&realm->inodes_with_caps_lock);
335 in = realm->inode ? igrab(realm->inode) : NULL;
336 spin_unlock(&realm->inodes_with_caps_lock);
337 if (in) {
338 ci = ceph_inode(in);
339 spin_lock(&ci->i_ceph_lock);
340 if (ci->i_max_bytes) {
341 total = ci->i_max_bytes >> CEPH_BLOCK_SHIFT;
342 used = ci->i_rbytes >> CEPH_BLOCK_SHIFT;
343 /* It is possible for a quota to be exceeded.
344 * Report 'zero' in that case
345 */
346 free = total > used ? total - used : 0;
347 }
348 spin_unlock(&ci->i_ceph_lock);
349 if (total) {
350 buf->f_blocks = total;
351 buf->f_bfree = free;
352 buf->f_bavail = free;
353 is_updated = true;
354 }
355 iput(in);
356 }
357 ceph_put_snap_realm(mdsc, realm);
358
359 return is_updated;
360}
361
fs/ceph/super.c+24−3
@@ -76,9 +76,18 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) · 75 unmodified lines
76 */76 */
77 buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;77 buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
78 buf->f_frsize = 1 << CEPH_BLOCK_SHIFT;78 buf->f_frsize = 1 << CEPH_BLOCK_SHIFT;
79 buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);79
80 buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);80 /*
81 buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);81 * By default use root quota for stats; fallback to overall filesystem
82 * usage if using 'noquotadf' mount option or if the root dir doesn't
83 * have max_bytes quota set.
84 */
85 if (ceph_test_mount_opt(fsc, NOQUOTADF) ||
86 !ceph_quota_update_statfs(fsc, buf)) {
87 buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
88 buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
89 buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
90 }
82 91
83 buf->f_files = le64_to_cpu(st.num_objects);92 buf->f_files = le64_to_cpu(st.num_objects);
84 buf->f_ffree = -1;93 buf->f_ffree = -1;
@@ -151,6 +160,8 @@ enum { · 66 unmodified lines
151 Opt_acl,160 Opt_acl,
152#endif161#endif
153 Opt_noacl,162 Opt_noacl,
163 Opt_quotadf,
164 Opt_noquotadf,
154};165};
155 166
156static match_table_t fsopt_tokens = {167static match_table_t fsopt_tokens = {
@@ -187,6 +198,8 @@ static match_table_t fsopt_tokens = { · 30 unmodified lines
187 {Opt_acl, "acl"},198 {Opt_acl, "acl"},
188#endif199#endif
189 {Opt_noacl, "noacl"},200 {Opt_noacl, "noacl"},
201 {Opt_quotadf, "quotadf"},
202 {Opt_noquotadf, "noquotadf"},
190 {-1, NULL}203 {-1, NULL}
191};204};
192 205
@@ -334,6 +347,12 @@ static int parse_fsopt_token(char *c, void *private) · 141 unmodified lines
334 case Opt_norequire_active_mds:347 case Opt_norequire_active_mds:
335 fsopt->flags |= CEPH_MOUNT_OPT_MOUNTWAIT;348 fsopt->flags |= CEPH_MOUNT_OPT_MOUNTWAIT;
336 break;349 break;
350 case Opt_quotadf:
351 fsopt->flags &= ~CEPH_MOUNT_OPT_NOQUOTADF;
352 break;
353 case Opt_noquotadf:
354 fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF;
355 break;
337#ifdef CONFIG_CEPH_FS_POSIX_ACL356#ifdef CONFIG_CEPH_FS_POSIX_ACL
338 case Opt_acl:357 case Opt_acl:
339 fsopt->sb_flags |= SB_POSIXACL;358 fsopt->sb_flags |= SB_POSIXACL;
@@ -520,6 +539,8 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) · 180 unmodified lines
520 }539 }
521 if (fsopt->flags & CEPH_MOUNT_OPT_NOPOOLPERM)540 if (fsopt->flags & CEPH_MOUNT_OPT_NOPOOLPERM)
522 seq_puts(m, ",nopoolperm");541 seq_puts(m, ",nopoolperm");
542 if (fsopt->flags & CEPH_MOUNT_OPT_NOQUOTADF)
543 seq_puts(m, ",noquotadf");
523 544
524#ifdef CONFIG_CEPH_FS_POSIX_ACL545#ifdef CONFIG_CEPH_FS_POSIX_ACL
525 if (fsopt->sb_flags & SB_POSIXACL)546 if (fsopt->sb_flags & SB_POSIXACL)
fs/ceph/super.h+3−0
@@ -39,6 +39,7 @@ · 38 unmodified lines
39#define CEPH_MOUNT_OPT_FSCACHE (1<<10) /* use fscache */39#define CEPH_MOUNT_OPT_FSCACHE (1<<10) /* use fscache */
40#define CEPH_MOUNT_OPT_NOPOOLPERM (1<<11) /* no pool permission check */40#define CEPH_MOUNT_OPT_NOPOOLPERM (1<<11) /* no pool permission check */
41#define CEPH_MOUNT_OPT_MOUNTWAIT (1<<12) /* mount waits if no mds is up */41#define CEPH_MOUNT_OPT_MOUNTWAIT (1<<12) /* mount waits if no mds is up */
42#define CEPH_MOUNT_OPT_NOQUOTADF (1<<13) /* no root dir quota in statfs */
42 43
43#define CEPH_MOUNT_OPT_DEFAULT CEPH_MOUNT_OPT_DCACHE44#define CEPH_MOUNT_OPT_DEFAULT CEPH_MOUNT_OPT_DCACHE
44 45
@@ -1104,5 +1105,7 @@ extern bool ceph_quota_is_max_bytes_exceeded(struct inode *inode, · 1059 unmodified lines
1104 loff_t newlen);1105 loff_t newlen);
1105extern bool ceph_quota_is_max_bytes_approaching(struct inode *inode,1106extern bool ceph_quota_is_max_bytes_approaching(struct inode *inode,
1106 loff_t newlen);1107 loff_t newlen);
1108extern bool ceph_quota_update_statfs(struct ceph_fs_client *fsc,
1109 struct kstatfs *buf);
1107 1110
1108#endif /* _FS_CEPH_SUPER_H */1111#endif /* _FS_CEPH_SUPER_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t