2 * Copyright (C) 2005-2012 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
20 * file operations for special files.
21 * while they exist in aufs virtually,
22 * their file I/O is handled out of aufs.
27 static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
28 unsigned long nv, loff_t pos)
33 struct file *file, *h_file;
34 struct super_block *sb;
37 sb = file->f_dentry->d_sb;
38 si_read_lock(sb, AuLock_FLUSH);
40 bstart = au_fbstart(file);
41 h_file = au_hf_top(file);
43 wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
46 /* do not change the file in kio */
47 AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
48 err = h_file->f_op->aio_read(kio, iov, nv, pos);
50 file_accessed(h_file);
55 static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
56 unsigned long nv, loff_t pos)
61 struct super_block *sb;
62 struct file *file, *h_file;
65 sb = file->f_dentry->d_sb;
66 si_read_lock(sb, AuLock_FLUSH);
68 bstart = au_fbstart(file);
69 h_file = au_hf_top(file);
71 wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
74 /* do not change the file in kio */
75 AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
76 err = h_file->f_op->aio_write(kio, iov, nv, pos);
78 file_update_time(h_file);
83 /* ---------------------------------------------------------------------- */
85 static int aufs_release_sp(struct inode *inode, struct file *file)
91 h_file = au_hf_top(file);
93 /* close this fifo in aufs */
94 err = h_file->f_op->release(inode, file); /* ignore */
95 aufs_release_nondir(inode, file); /* ignore */
99 /* ---------------------------------------------------------------------- */
101 /* currently, support only FIFO */
103 AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
104 /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
107 static int aufs_open_sp(struct inode *inode, struct file *file);
108 static struct au_sp_fop {
110 struct file_operations fop; /* not 'const' */
112 } au_sp_fop[AuSp_Last] = {
115 .owner = THIS_MODULE,
121 static void au_init_fop_sp(struct file *file)
128 if (unlikely(!p->done)) {
129 /* initialize first time only */
130 static DEFINE_SPINLOCK(spin);
134 BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
136 for (i = 0; i < AuSp_Last; i++)
137 spin_lock_init(&p[i].spin);
143 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
150 case FMODE_READ | FMODE_WRITE:
158 if (unlikely(!p->done)) {
159 /* initialize first time only */
160 h_file = au_hf_top(file);
163 p->fop = *h_file->f_op;
164 p->fop.owner = THIS_MODULE;
166 p->fop.aio_read = aufs_aio_read_sp;
167 if (p->fop.aio_write)
168 p->fop.aio_write = aufs_aio_write_sp;
169 p->fop.release = aufs_release_sp;
172 spin_unlock(&p->spin);
174 file->f_op = &p->fop;
177 static int au_cpup_sp(struct dentry *dentry)
182 struct au_wr_dir_args wr_dir_args = {
187 AuDbg("%.*s\n", AuDLNPair(dentry));
189 di_read_unlock(dentry, AuLock_IR);
190 di_write_lock_child(dentry);
191 err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
192 if (unlikely(err < 0))
196 if (bcpup == au_dbstart(dentry))
197 goto out; /* success */
199 err = au_pin(&pin, dentry, bcpup, au_opt_udba(dentry->d_sb),
202 err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME);
207 di_downgrade_lock(dentry, AuLock_IR);
211 static int au_do_open_sp(struct file *file, int flags)
214 struct dentry *dentry;
215 struct super_block *sb;
217 struct inode *h_inode;
219 dentry = file->f_dentry;
220 AuDbg("%.*s\n", AuDLNPair(dentry));
224 * operate on the ro branch is not an error.
226 au_cpup_sp(dentry); /* ignore */
229 err = au_do_open_nondir(file, vfsub_file_flags(file));
234 h_file = au_hf_top(file);
235 h_inode = h_file->f_dentry->d_inode;
236 di_read_unlock(dentry, AuLock_IR);
237 fi_write_unlock(file);
239 /* open this fifo in aufs */
240 err = h_inode->i_fop->open(file->f_dentry->d_inode, file);
241 si_noflush_read_lock(sb);
243 di_read_lock_child(dentry, AuLock_IR);
245 au_init_fop_sp(file);
251 static int aufs_open_sp(struct inode *inode, struct file *file)
254 struct super_block *sb;
256 sb = file->f_dentry->d_sb;
257 si_read_lock(sb, AuLock_FLUSH);
258 err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
263 /* ---------------------------------------------------------------------- */
265 void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
267 init_special_inode(inode, mode, rdev);
269 switch (mode & S_IFMT) {
271 inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
282 int au_special_file(umode_t mode)
287 switch (mode & S_IFMT) {