]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - fs/aufs/ioctl.c
2 * Copyright (C) 2005-2017 Junjiro R. Okajima
4 * This program, aufs is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * plink-management and readdir in userspace.
21 * assist the pathconf(3) wrapper library.
23 * File-based Hierarchical Storage Management.
26 #include <linux/compat.h>
27 #include <linux/file.h>
30 static int au_wbr_fd(struct path
*path
, struct aufs_wbr_fd __user
*arg
)
33 aufs_bindex_t wbi
, bindex
, bbot
;
35 struct super_block
*sb
;
38 struct aufs_wbr_fd wbrfd
= {
39 .oflags
= au_dir_roflags
,
42 const int valid
= O_RDONLY
| O_NONBLOCK
| O_LARGEFILE
| O_DIRECTORY
43 | O_NOATIME
| O_CLOEXEC
;
45 AuDebugOn(wbrfd
.oflags
& ~valid
);
48 err
= copy_from_user(&wbrfd
, arg
, sizeof(wbrfd
));
55 AuDbg("wbrfd{0%o, %d}\n", wbrfd
.oflags
, wbrfd
.brid
);
56 wbrfd
.oflags
|= au_dir_roflags
;
57 AuDbg("0%o\n", wbrfd
.oflags
);
58 if (unlikely(wbrfd
.oflags
& ~valid
))
62 fd
= get_unused_fd_flags(0);
67 h_file
= ERR_PTR(-EINVAL
);
70 sb
= path
->dentry
->d_sb
;
72 aufs_read_lock(root
, AuLock_IR
);
74 if (wbrfd
.brid
>= 0) {
75 wbi
= au_br_index(sb
, wbrfd
.brid
);
76 if (unlikely(wbi
< 0 || wbi
> bbot
))
80 h_file
= ERR_PTR(-ENOENT
);
82 if (!au_br_writable(br
->br_perm
)) {
88 for (; bindex
<= bbot
; bindex
++) {
89 br
= au_sbr(sb
, bindex
);
90 if (au_br_writable(br
->br_perm
)) {
97 AuDbg("wbi %d\n", wbi
);
99 h_file
= au_h_open(root
, wbi
, wbrfd
.oflags
, NULL
,
103 aufs_read_unlock(root
, AuLock_IR
);
104 err
= PTR_ERR(h_file
);
108 au_br_put(br
); /* cf. au_h_open() */
109 fd_install(fd
, h_file
);
111 goto out
; /* success */
120 /* ---------------------------------------------------------------------- */
122 long aufs_ioctl_dir(struct file
*file
, unsigned int cmd
, unsigned long arg
)
125 struct dentry
*dentry
;
129 case AUFS_CTL_RDU_INO
:
130 err
= au_rdu_ioctl(file
, cmd
, arg
);
133 case AUFS_CTL_WBR_FD
:
134 err
= au_wbr_fd(&file
->f_path
, (void __user
*)arg
);
138 err
= au_ibusy_ioctl(file
, arg
);
141 case AUFS_CTL_BRINFO
:
142 err
= au_brinfo_ioctl(file
, arg
);
145 case AUFS_CTL_FHSM_FD
:
146 dentry
= file
->f_path
.dentry
;
148 err
= au_fhsm_fd(dentry
->d_sb
, arg
);
154 /* do not call the lower */
155 AuDbg("0x%x\n", cmd
);
163 long aufs_ioctl_nondir(struct file
*file
, unsigned int cmd
, unsigned long arg
)
168 case AUFS_CTL_MVDOWN
:
169 err
= au_mvdown(file
->f_path
.dentry
, (void __user
*)arg
);
172 case AUFS_CTL_WBR_FD
:
173 err
= au_wbr_fd(&file
->f_path
, (void __user
*)arg
);
177 /* do not call the lower */
178 AuDbg("0x%x\n", cmd
);
187 long aufs_compat_ioctl_dir(struct file
*file
, unsigned int cmd
,
194 case AUFS_CTL_RDU_INO
:
195 err
= au_rdu_compat_ioctl(file
, cmd
, arg
);
199 err
= au_ibusy_compat_ioctl(file
, arg
);
202 case AUFS_CTL_BRINFO
:
203 err
= au_brinfo_compat_ioctl(file
, arg
);
207 err
= aufs_ioctl_dir(file
, cmd
, arg
);
214 long aufs_compat_ioctl_nondir(struct file
*file
, unsigned int cmd
,
217 return aufs_ioctl_nondir(file
, cmd
, (unsigned long)compat_ptr(arg
));