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)
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;
}
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)
}
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;
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 */
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,
};
}
}
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 &&