bcachefs: more project quota fixes
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 19 Dec 2018 13:43:01 +0000 (08:43 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:14 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs-ioctl.c
fs/bcachefs/fs.h
fs/bcachefs/quota.h
fs/bcachefs/xattr.c

index 92939befe507558206bc560c09ec76f031300e48..4925a127a3350ce31d3c23c97ef0b2f9b04c0743 100644 (file)
@@ -104,19 +104,6 @@ static int bch2_ioc_fsgetxattr(struct bch_inode_info *inode,
        return copy_to_user(arg, &fa, sizeof(fa));
 }
 
-static int bch2_set_projid(struct bch_fs *c,
-                          struct bch_inode_info *inode,
-                          u32 projid)
-{
-       struct bch_qid qid = inode->ei_qid;
-
-       qid.q[QTYP_PRJ] = projid;
-
-       return bch2_fs_quota_transfer(c, inode, qid,
-                                     1 << QTYP_PRJ,
-                                     KEY_TYPE_QUOTA_PREALLOC);
-}
-
 static int fssetxattr_inode_update_fn(struct bch_inode_info *inode,
                                      struct bch_inode_unpacked *bi,
                                      void *p)
@@ -124,11 +111,7 @@ static int fssetxattr_inode_update_fn(struct bch_inode_info *inode,
        struct flags_set *s = p;
 
        if (s->projid != bi->bi_project) {
-               if (s->projid)
-                       bi->bi_fields_set |= 1U << Inode_opt_project;
-               else
-                       bi->bi_fields_set &= ~(1U << Inode_opt_project);
-
+               bi->bi_fields_set |= 1U << Inode_opt_project;
                bi->bi_project = s->projid;
        }
 
@@ -151,7 +134,10 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
        if (fa.fsx_xflags)
                return -EOPNOTSUPP;
 
-       s.projid = fa.fsx_projid;
+       if (fa.fsx_projid >= U32_MAX)
+               return -EINVAL;
+
+       s.projid = fa.fsx_projid + 1;
 
        ret = mnt_want_write_file(file);
        if (ret)
@@ -164,7 +150,7 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
        }
 
        mutex_lock(&inode->ei_update_lock);
-       ret = bch2_set_projid(c, inode, fa.fsx_projid);
+       ret = bch2_set_projid(c, inode, s.projid);
        if (ret)
                goto err_unlock;
 
index 4c584d3a27c3ff2126f418ce6ef0a63d9cbec3fc..f949cd0d2a68e94127d43eb51623950244f2eb29 100644 (file)
@@ -121,6 +121,19 @@ int bch2_fs_quota_transfer(struct bch_fs *,
                           unsigned,
                           enum quota_acct_mode);
 
+static inline int bch2_set_projid(struct bch_fs *c,
+                                 struct bch_inode_info *inode,
+                                 u32 projid)
+{
+       struct bch_qid qid = inode->ei_qid;
+
+       qid.q[QTYP_PRJ] = projid;
+
+       return bch2_fs_quota_transfer(c, inode, qid,
+                                     1 << QTYP_PRJ,
+                                     KEY_TYPE_QUOTA_PREALLOC);
+}
+
 struct inode *bch2_vfs_inode_get(struct bch_fs *, u64);
 
 /* returns 0 if we want to do the update, or error is passed up */
index 72b5ea0d77c52a0ae5cf2117acf1457bee34c28b..51e4f9713ef0bd7904b7aea90ee72dcafcaf5ad9 100644 (file)
@@ -20,7 +20,7 @@ static inline struct bch_qid bch_qid(struct bch_inode_unpacked *u)
        return (struct bch_qid) {
                .q[QTYP_USR] = u->bi_uid,
                .q[QTYP_GRP] = u->bi_gid,
-               .q[QTYP_PRJ] = u->bi_project,
+               .q[QTYP_PRJ] = u->bi_project ? u->bi_project - 1 : 0,
        };
 }
 
index dfb5c385e8c33b10a681ad8677ec7dcb0db9ac48..f31eec2f1fcecf46fa60081bb7ba9ecec7b6b2cd 100644 (file)
@@ -515,7 +515,14 @@ static int bch2_xattr_bcachefs_set(const struct xattr_handler *handler,
        }
 
        mutex_lock(&inode->ei_update_lock);
+       if (inode_opt_id == Inode_opt_project) {
+               ret = bch2_set_projid(c, inode, s.v);
+               if (ret)
+                       goto err;
+       }
+
        ret = bch2_write_inode(c, inode, inode_opt_set_fn, &s, 0);
+err:
        mutex_unlock(&inode->ei_update_lock);
 
        if (value &&