]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - fs/aufs/ioctl.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2005-2021 Junjiro R. Okajima
5 * This program, aufs is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * plink-management and readdir in userspace.
22 * assist the pathconf(3) wrapper library.
24 * File-based Hierarchical Storage Management.
27 #include <linux/compat.h>
28 #include <linux/file.h>
31 static int au_wbr_fd(struct path
*path
, struct aufs_wbr_fd __user
*arg
)
34 aufs_bindex_t wbi
, bindex
, bbot
;
36 struct super_block
*sb
;
39 struct aufs_wbr_fd wbrfd
= {
40 .oflags
= au_dir_roflags
,
43 const int valid
= O_RDONLY
| O_NONBLOCK
| O_LARGEFILE
| O_DIRECTORY
44 | O_NOATIME
| O_CLOEXEC
;
46 AuDebugOn(wbrfd
.oflags
& ~valid
);
49 err
= copy_from_user(&wbrfd
, arg
, sizeof(wbrfd
));
56 AuDbg("wbrfd{0%o, %d}\n", wbrfd
.oflags
, wbrfd
.brid
);
57 wbrfd
.oflags
|= au_dir_roflags
;
58 AuDbg("0%o\n", wbrfd
.oflags
);
59 if (unlikely(wbrfd
.oflags
& ~valid
))
63 fd
= get_unused_fd_flags(0);
68 h_file
= ERR_PTR(-EINVAL
);
71 sb
= path
->dentry
->d_sb
;
73 aufs_read_lock(root
, AuLock_IR
);
75 if (wbrfd
.brid
>= 0) {
76 wbi
= au_br_index(sb
, wbrfd
.brid
);
77 if (unlikely(wbi
< 0 || wbi
> bbot
))
81 h_file
= ERR_PTR(-ENOENT
);
83 if (!au_br_writable(br
->br_perm
)) {
89 for (; bindex
<= bbot
; bindex
++) {
90 br
= au_sbr(sb
, bindex
);
91 if (au_br_writable(br
->br_perm
)) {
98 AuDbg("wbi %d\n", wbi
);
100 h_file
= au_h_open(root
, wbi
, wbrfd
.oflags
, NULL
,
104 aufs_read_unlock(root
, AuLock_IR
);
105 err
= PTR_ERR(h_file
);
109 au_lcnt_dec(&br
->br_nfiles
); /* cf. au_h_open() */
110 fd_install(fd
, h_file
);
112 goto out
; /* success */
121 /* ---------------------------------------------------------------------- */
123 long aufs_ioctl_dir(struct file
*file
, unsigned int cmd
, unsigned long arg
)
126 struct dentry
*dentry
;
130 case AUFS_CTL_RDU_INO
:
131 err
= au_rdu_ioctl(file
, cmd
, arg
);
134 case AUFS_CTL_WBR_FD
:
135 err
= au_wbr_fd(&file
->f_path
, (void __user
*)arg
);
139 err
= au_ibusy_ioctl(file
, arg
);
142 case AUFS_CTL_BRINFO
:
143 err
= au_brinfo_ioctl(file
, arg
);
146 case AUFS_CTL_FHSM_FD
:
147 dentry
= file
->f_path
.dentry
;
149 err
= au_fhsm_fd(dentry
->d_sb
, arg
);
155 /* do not call the lower */
156 AuDbg("0x%x\n", cmd
);
164 long aufs_ioctl_nondir(struct file
*file
, unsigned int cmd
, unsigned long arg
)
169 case AUFS_CTL_MVDOWN
:
170 err
= au_mvdown(file
->f_path
.dentry
, (void __user
*)arg
);
173 case AUFS_CTL_WBR_FD
:
174 err
= au_wbr_fd(&file
->f_path
, (void __user
*)arg
);
178 /* do not call the lower */
179 AuDbg("0x%x\n", cmd
);
188 long aufs_compat_ioctl_dir(struct file
*file
, unsigned int cmd
,
195 case AUFS_CTL_RDU_INO
:
196 err
= au_rdu_compat_ioctl(file
, cmd
, arg
);
200 err
= au_ibusy_compat_ioctl(file
, arg
);
203 case AUFS_CTL_BRINFO
:
204 err
= au_brinfo_compat_ioctl(file
, arg
);
208 err
= aufs_ioctl_dir(file
, cmd
, arg
);
215 long aufs_compat_ioctl_nondir(struct file
*file
, unsigned int cmd
,
218 return aufs_ioctl_nondir(file
, cmd
, (unsigned long)compat_ptr(arg
));