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
149149 noasyncreaddir
150150 Do not use the dcache as above for readdir.
151151
152+ noquotadf
153+ Report overall filesystem usage in statfs instead of using the root
154+ directory quota.
155+
152156 More Information
153157 ================
154158
fs/ceph/quota.c+56−0
@@ -18,6 +18,8 @@ · 17 unmodified lines
1818 * along with this program; if not, see <http://www.gnu.org/licenses/>.
1919 */
2020
21+#include <linux/statfs.h>
22+
2123 #include "super.h"
2224 #include "mds_client.h"
2325
@@ -303,3 +305,57 @@ bool ceph_quota_is_max_bytes_approaching(struct inode *inode, loff_t newsize) · 279 unmodified lines
303305 return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_APPROACHING_OP,
304306 (newsize - size));
305307 }
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+ */
319+bool 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
7676 */
7777 buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
7878 buf->f_frsize = 1 << CEPH_BLOCK_SHIFT;
79− buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
80− buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
81− buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
79+
80+ /*
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+ }
8291
8392 buf->f_files = le64_to_cpu(st.num_objects);
8493 buf->f_ffree = -1;
@@ -151,6 +160,8 @@ enum { · 66 unmodified lines
151160 Opt_acl,
152161 #endif
153162 Opt_noacl,
163+ Opt_quotadf,
164+ Opt_noquotadf,
154165 };
155166
156167 static match_table_t fsopt_tokens = {
@@ -187,6 +198,8 @@ static match_table_t fsopt_tokens = { · 30 unmodified lines
187198 {Opt_acl, "acl"},
188199 #endif
189200 {Opt_noacl, "noacl"},
201+ {Opt_quotadf, "quotadf"},
202+ {Opt_noquotadf, "noquotadf"},
190203 {-1, NULL}
191204 };
192205
@@ -334,6 +347,12 @@ static int parse_fsopt_token(char *c, void *private) · 141 unmodified lines
334347 case Opt_norequire_active_mds:
335348 fsopt->flags |= CEPH_MOUNT_OPT_MOUNTWAIT;
336349 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;
337356 #ifdef CONFIG_CEPH_FS_POSIX_ACL
338357 case Opt_acl:
339358 fsopt->sb_flags |= SB_POSIXACL;
@@ -520,6 +539,8 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) · 180 unmodified lines
520539 }
521540 if (fsopt->flags & CEPH_MOUNT_OPT_NOPOOLPERM)
522541 seq_puts(m, ",nopoolperm");
542+ if (fsopt->flags & CEPH_MOUNT_OPT_NOQUOTADF)
543+ seq_puts(m, ",noquotadf");
523544
524545 #ifdef CONFIG_CEPH_FS_POSIX_ACL
525546 if (fsopt->sb_flags & SB_POSIXACL)
fs/ceph/super.h+3−0
@@ -39,6 +39,7 @@ · 38 unmodified lines
3939 #define CEPH_MOUNT_OPT_FSCACHE (1<<10) /* use fscache */
4040 #define CEPH_MOUNT_OPT_NOPOOLPERM (1<<11) /* no pool permission check */
4141 #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 */
4243
4344 #define CEPH_MOUNT_OPT_DEFAULT CEPH_MOUNT_OPT_DCACHE
4445
@@ -1104,5 +1105,7 @@ extern bool ceph_quota_is_max_bytes_exceeded(struct inode *inode, · 1059 unmodified lines
11041105 loff_t newlen);
11051106 extern bool ceph_quota_is_max_bytes_approaching(struct inode *inode,
11061107 loff_t newlen);
1108+extern bool ceph_quota_update_statfs(struct ceph_fs_client *fsc,
1109+ struct kstatfs *buf);
11071110
11081111 #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