2 * Copyright (C) 2005-2013 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, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 * plink-management and readdir in userspace.
22 * assist the pathconf(3) wrapper library.
27 static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
30 aufs_bindex_t wbi, bindex, bend;
32 struct super_block *sb;
35 struct aufs_wbr_fd wbrfd = {
36 .oflags = au_dir_roflags,
39 const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
40 | O_NOATIME | O_CLOEXEC;
42 AuDebugOn(wbrfd.oflags & ~valid);
45 err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
52 AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
53 wbrfd.oflags |= au_dir_roflags;
54 AuDbg("0%o\n", wbrfd.oflags);
55 if (unlikely(wbrfd.oflags & ~valid))
64 h_file = ERR_PTR(-EINVAL);
67 sb = path->dentry->d_sb;
69 aufs_read_lock(root, AuLock_IR);
71 if (wbrfd.brid >= 0) {
72 wbi = au_br_index(sb, wbrfd.brid);
73 if (unlikely(wbi < 0 || wbi > bend))
77 h_file = ERR_PTR(-ENOENT);
79 if (!au_br_writable(br->br_perm)) {
85 for (; bindex <= bend; bindex++) {
86 br = au_sbr(sb, bindex);
87 if (au_br_writable(br->br_perm)) {
94 AuDbg("wbi %d\n", wbi);
96 h_file = au_h_open(root, wbi, wbrfd.oflags, NULL);
99 aufs_read_unlock(root, AuLock_IR);
100 err = PTR_ERR(h_file);
104 atomic_dec(&br->br_count); /* cf. au_h_open() */
105 fd_install(fd, h_file);
107 goto out; /* success */
116 /* ---------------------------------------------------------------------- */
118 long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
124 case AUFS_CTL_RDU_INO:
125 err = au_rdu_ioctl(file, cmd, arg);
128 case AUFS_CTL_WBR_FD:
129 err = au_wbr_fd(&file->f_path, (void __user *)arg);
133 err = au_ibusy_ioctl(file, arg);
137 /* do not call the lower */
138 AuDbg("0x%x\n", cmd);
146 long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
151 case AUFS_CTL_WBR_FD:
152 err = au_wbr_fd(&file->f_path, (void __user *)arg);
156 /* do not call the lower */
157 AuDbg("0x%x\n", cmd);
166 long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
173 case AUFS_CTL_RDU_INO:
174 err = au_rdu_compat_ioctl(file, cmd, arg);
178 err = au_ibusy_compat_ioctl(file, arg);
182 err = aufs_ioctl_dir(file, cmd, arg);
189 #if 0 /* unused yet */
190 long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
193 return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));