]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/fs-ioctl.c
Update bcachefs sources to 171da96d76 bcachefs: Drop some anonymous structs, unions
[bcachefs-tools-debian] / libbcachefs / fs-ioctl.c
index 3ed53f420e7e713d6b8d51a19bc42d604610a61a..2bb680827b44763783f663e6c2a5b223852430e4 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;
 
@@ -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;
@@ -422,6 +438,7 @@ static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp,
                                struct bch_ioctl_subvolume arg)
 {
        struct path path;
+       struct inode *dir;
        int ret = 0;
 
        if (arg.flags)
@@ -438,7 +455,13 @@ static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp,
                return -EXDEV;
        }
 
-       ret = __bch2_unlink(path.dentry->d_parent->d_inode, path.dentry, 1);
+       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);
 
        return ret;
@@ -448,51 +471,67 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
        struct bch_inode_info *inode = file_bch_inode(file);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
+       long ret;
 
        switch (cmd) {
        case FS_IOC_GETFLAGS:
-               return bch2_ioc_getflags(inode, (int __user *) arg);
+               ret = bch2_ioc_getflags(inode, (int __user *) arg);
+               break;
 
        case FS_IOC_SETFLAGS:
-               return bch2_ioc_setflags(c, file, inode, (int __user *) arg);
+               ret = bch2_ioc_setflags(c, file, inode, (int __user *) arg);
+               break;
 
        case FS_IOC_FSGETXATTR:
-               return bch2_ioc_fsgetxattr(inode, (void __user *) arg);
+               ret = bch2_ioc_fsgetxattr(inode, (void __user *) arg);
+               break;
+
        case FS_IOC_FSSETXATTR:
-               return bch2_ioc_fssetxattr(c, file, inode,
-                                          (void __user *) arg);
+               ret = bch2_ioc_fssetxattr(c, file, inode,
+                                         (void __user *) arg);
+               break;
 
        case BCHFS_IOC_REINHERIT_ATTRS:
-               return bch2_ioc_reinherit_attrs(c, file, inode,
-                                               (void __user *) arg);
+               ret = bch2_ioc_reinherit_attrs(c, file, inode,
+                                              (void __user *) arg);
+               break;
 
        case FS_IOC_GETVERSION:
-               return -ENOTTY;
+               ret = -ENOTTY;
+               break;
+
        case FS_IOC_SETVERSION:
-               return -ENOTTY;
+               ret = -ENOTTY;
+               break;
 
        case FS_IOC_GOINGDOWN:
-               return bch2_ioc_goingdown(c, (u32 __user *) arg);
+               ret = bch2_ioc_goingdown(c, (u32 __user *) arg);
+               break;
 
        case BCH_IOCTL_SUBVOLUME_CREATE: {
                struct bch_ioctl_subvolume i;
 
-               if (copy_from_user(&i, (void __user *) arg, sizeof(i)))
-                       return -EFAULT;
-               return bch2_ioctl_subvolume_create(c, file, i);
+               ret = copy_from_user(&i, (void __user *) arg, sizeof(i))
+                       ? -EFAULT
+                       : bch2_ioctl_subvolume_create(c, file, i);
+               break;
        }
 
        case BCH_IOCTL_SUBVOLUME_DESTROY: {
                struct bch_ioctl_subvolume i;
 
-               if (copy_from_user(&i, (void __user *) arg, sizeof(i)))
-                       return -EFAULT;
-               return bch2_ioctl_subvolume_destroy(c, file, i);
+               ret = copy_from_user(&i, (void __user *) arg, sizeof(i))
+                       ? -EFAULT
+                       : bch2_ioctl_subvolume_destroy(c, file, i);
+               break;
        }
 
        default:
-               return bch2_fs_ioctl(c, cmd, (void __user *) arg);
+               ret = bch2_fs_ioctl(c, cmd, (void __user *) arg);
+               break;
        }
+
+       return bch2_err_class(ret);
 }
 
 #ifdef CONFIG_COMPAT