]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/fs-ioctl.c
Update bcachefs sources to 25de2b00dc bcachefs: Change check for invalid key types
[bcachefs-tools-debian] / libbcachefs / fs-ioctl.c
index bab0707bc2f4f003395b2ece347f919b5979e64c..dfa1bf73c8541187abbe87e7127213d337ee24e7 100644 (file)
@@ -26,6 +26,9 @@ struct flags_set {
        unsigned                flags;
 
        unsigned                projid;
+
+       bool                    set_projinherit;
+       bool                    projinherit;
 };
 
 static int bch2_inode_flags_set(struct bch_inode_info *inode,
@@ -50,6 +53,11 @@ static int bch2_inode_flags_set(struct bch_inode_info *inode,
            (newflags & (BCH_INODE_NODUMP|BCH_INODE_NOATIME)) != newflags)
                return -EINVAL;
 
+       if (s->set_projinherit) {
+               bi->bi_fields_set &= ~(1 << Inode_opt_project);
+               bi->bi_fields_set |= ((int) s->projinherit << Inode_opt_project);
+       }
+
        bi->bi_flags &= ~s->mask;
        bi->bi_flags |= newflags;
 
@@ -85,7 +93,7 @@ static int bch2_ioc_setflags(struct bch_fs *c,
                return ret;
 
        inode_lock(&inode->v);
-       if (!inode_owner_or_capable(file_mnt_user_ns(file), &inode->v)) {
+       if (!inode_owner_or_capable(file_mnt_idmap(file), &inode->v)) {
                ret = -EACCES;
                goto setflags_out;
        }
@@ -107,6 +115,10 @@ static int bch2_ioc_fsgetxattr(struct bch_inode_info *inode,
        struct fsxattr fa = { 0 };
 
        fa.fsx_xflags = map_flags(bch_flags_to_xflags, inode->ei_inode.bi_flags);
+
+       if (inode->ei_inode.bi_fields_set & (1 << Inode_opt_project))
+               fa.fsx_xflags |= FS_XFLAG_PROJINHERIT;
+
        fa.fsx_projid = inode->ei_qid.q[QTYP_PRJ];
 
        return copy_to_user(arg, &fa, sizeof(fa));
@@ -138,6 +150,10 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
        if (copy_from_user(&fa, arg, sizeof(fa)))
                return -EFAULT;
 
+       s.set_projinherit = true;
+       s.projinherit = (fa.fsx_xflags & FS_XFLAG_PROJINHERIT) != 0;
+       fa.fsx_xflags &= ~FS_XFLAG_PROJINHERIT;
+
        s.flags = map_flags_rev(bch_flags_to_xflags, fa.fsx_xflags);
        if (fa.fsx_xflags)
                return -EOPNOTSUPP;
@@ -156,7 +172,7 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
                return ret;
 
        inode_lock(&inode->v);
-       if (!inode_owner_or_capable(file_mnt_user_ns(file), &inode->v)) {
+       if (!inode_owner_or_capable(file_mnt_idmap(file), &inode->v)) {
                ret = -EACCES;
                goto err;
        }
@@ -366,7 +382,7 @@ retry:
 
        dir = dst_path.dentry->d_inode;
        if (IS_DEADDIR(dir)) {
-               error = -ENOENT;
+               error = -BCH_ERR_ENOENT_directory_dead;
                goto err3;
        }
 
@@ -377,7 +393,7 @@ retry:
                goto err3;
        }
 
-       error = inode_permission(file_mnt_user_ns(filp),
+       error = inode_permission(file_mnt_idmap(filp),
                                 dir, MAY_WRITE | MAY_EXEC);
        if (error)
                goto err3;
@@ -393,7 +409,7 @@ retry:
            !arg.src_ptr)
                snapshot_src.subvol = to_bch_ei(dir)->ei_inode.bi_subvol;
 
-       inode = __bch2_create(file_mnt_user_ns(filp), to_bch_ei(dir),
+       inode = __bch2_create(file_mnt_idmap(filp), to_bch_ei(dir),
                              dst_dentry, arg.mode|S_IFDIR,
                              0, snapshot_src, create_flags);
        error = PTR_ERR_OR_ZERO(inode);
@@ -435,19 +451,20 @@ static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp,
                return ret;
 
        if (path.dentry->d_sb->s_fs_info != c) {
-               path_put(&path);
-               return -EXDEV;
+               ret = -EXDEV;
+               goto err;
        }
 
        dir = path.dentry->d_parent->d_inode;
 
        ret = __bch2_unlink(dir, path.dentry, true);
-       if (!ret) {
-               fsnotify_rmdir(dir, path.dentry);
-               d_delete(path.dentry);
-       }
-       path_put(&path);
+       if (ret)
+               goto err;
 
+       fsnotify_rmdir(dir, path.dentry);
+       d_delete(path.dentry);
+err:
+       path_put(&path);
        return ret;
 }