2
* Copyright (C) 2007-2008 Junjiro 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
* sub-routines for VFS
22
* $Id: vfsub.c,v 1.2 2008/04/21 01:49:05 sfjro Exp $
24
// I'm going to slightly mad
26
#include <linux/uaccess.h>
29
/* ---------------------------------------------------------------------- */
31
void vfsub_args_init(struct vfsub_args *vargs, struct au_hin_ignore *ign,
32
int dlgt, int force_unlink)
34
do_vfsub_args_reinit(vargs, ign);
37
vfsub_fset(vargs->flags, DLGT);
39
vfsub_fset(vargs->flags, FORCE_UNLINK);
42
/* ---------------------------------------------------------------------- */
44
struct file *vfsub_filp_open(const char *path, int oflags, int mode)
48
LKTRTrace("%s\n", path);
51
err = filp_open(path, oflags, mode);
54
au_update_fuse_h_inode(err->f_vfsmnt, err->f_dentry); /*ignore*/
58
int vfsub_path_lookup(const char *name, unsigned int flags,
63
LKTRTrace("%s\n", name);
66
err = path_lookup(name, flags, nd);
69
au_update_fuse_h_inode(nd->path.mnt, nd->path.dentry);
74
struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
79
LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name);
80
IMustLock(parent->d_inode);
82
d = lookup_one_len(name, parent, len);
84
au_update_fuse_h_inode(NULL, d); /*ignore*/
88
#ifdef CONFIG_AUFS_LHASH_PATCH
89
struct dentry *vfsub__lookup_hash(struct qstr *name, struct dentry *parent,
94
LKTRTrace("%.*s/%.*s, nd %d\n",
95
AuDLNPair(parent), AuLNPair(name), !!nd);
96
IMustLock(parent->d_inode);
98
d = __lookup_hash(name, parent, nd);
100
au_update_fuse_h_inode(NULL, d); /*ignore*/
105
/* ---------------------------------------------------------------------- */
107
int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode,
108
struct nameidata *nd)
111
struct vfsmount *mnt;
113
LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
116
err = vfs_create(dir, dentry, mode, nd);
121
/* dir inode is locked */
122
au_update_fuse_h_inode(mnt, dentry->d_parent); /*ignore*/
123
au_update_fuse_h_inode(mnt, dentry); /*ignore*/
128
int do_vfsub_symlink(struct inode *dir, struct dentry *dentry,
129
const char *symname, int mode)
133
LKTRTrace("i%lu, %.*s, %s, 0x%x\n",
134
dir->i_ino, AuDLNPair(dentry), symname, mode);
137
err = vfs_symlink(dir, dentry, symname, mode);
139
/* dir inode is locked */
140
au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
141
au_update_fuse_h_inode(NULL, dentry); /*ignore*/
146
int do_vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode,
151
LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
154
err = vfs_mknod(dir, dentry, mode, dev);
156
/* dir inode is locked */
157
au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
158
au_update_fuse_h_inode(NULL, dentry); /*ignore*/
163
int do_vfsub_link(struct dentry *src_dentry, struct inode *dir,
164
struct dentry *dentry)
168
LKTRTrace("%.*s, i%lu, %.*s\n",
169
AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry));
173
err = vfs_link(src_dentry, dir, dentry);
176
LKTRTrace("src_i %p, dst_i %p\n",
177
src_dentry->d_inode, dentry->d_inode);
178
/* fuse has different memory inode for the same inumber */
179
au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/
180
/* dir inode is locked */
181
au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
182
au_update_fuse_h_inode(NULL, dentry); /*ignore*/
187
int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
188
struct inode *dir, struct dentry *dentry)
192
LKTRTrace("i%lu, %.*s, i%lu, %.*s\n",
193
src_dir->i_ino, AuDLNPair(src_dentry),
194
dir->i_ino, AuDLNPair(dentry));
199
err = vfs_rename(src_dir, src_dentry, dir, dentry);
202
/* dir inode is locked */
203
au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
204
au_update_fuse_h_inode(NULL, src_dentry->d_parent); /*ignore*/
205
au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/
210
int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode)
214
LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
217
err = vfs_mkdir(dir, dentry, mode);
219
/* dir inode is locked */
220
au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
221
au_update_fuse_h_inode(NULL, dentry); /*ignore*/
226
int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry)
230
LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
234
err = vfs_rmdir(dir, dentry);
236
/* dir inode is locked */
238
au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
242
int do_vfsub_unlink(struct inode *dir, struct dentry *dentry)
246
LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
249
/* vfs_unlink() locks inode */
251
err = vfs_unlink(dir, dentry);
253
/* dir inode is locked */
255
au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
259
/* ---------------------------------------------------------------------- */
261
ssize_t do_vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
266
LKTRTrace("%.*s, cnt %lu, pos %Ld\n",
267
AuDLNPair(file->f_dentry), (unsigned long)count, *ppos);
269
if (0 /*!au_test_nfs(file->f_vfsmnt->mnt_sb)*/)
270
err = vfs_read(file, ubuf, count, ppos);
273
err = vfs_read(file, ubuf, count, ppos);
277
au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry);
283
ssize_t do_vfsub_read_k(struct file *file, void *kbuf, size_t count,
291
err = do_vfsub_read_u(file, (char __user *)kbuf, count, ppos);
296
ssize_t do_vfsub_write_u(struct file *file, const char __user *ubuf,
297
size_t count, loff_t *ppos)
301
LKTRTrace("%.*s, cnt %lu, pos %Ld\n",
302
AuDLNPair(file->f_dentry), (unsigned long)count, *ppos);
305
err = vfs_write(file, ubuf, count, ppos);
308
au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry);
313
ssize_t do_vfsub_write_k(struct file *file, void *kbuf, size_t count,
321
err = do_vfsub_write_u(file, (const char __user *)kbuf, count, ppos);
326
int do_vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
330
LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry));
333
err = vfs_readdir(file, filldir, arg);
336
au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry);
341
#ifdef CONFIG_AUFS_SPLICE_PATCH
342
long do_vfsub_splice_to(struct file *in, loff_t *ppos,
343
struct pipe_inode_info *pipe, size_t len,
348
LKTRTrace("%.*s, pos %Ld, len %lu, 0x%x\n",
349
AuDLNPair(in->f_dentry), *ppos, (unsigned long)len, flags);
352
err = do_splice_to(in, ppos, pipe, len, flags);
355
au_update_fuse_h_inode(in->f_vfsmnt, in->f_dentry); /*ignore*/
359
long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
360
loff_t *ppos, size_t len, unsigned int flags)
364
LKTRTrace("%.*s, pos %Ld, len %lu, 0x%x\n",
365
AuDLNPair(out->f_dentry), *ppos, (unsigned long)len, flags);
368
err = do_splice_from(pipe, out, ppos, len, flags);
371
au_update_fuse_h_inode(out->f_vfsmnt, out->f_dentry); /*ignore*/
376
/* ---------------------------------------------------------------------- */
378
struct au_vfsub_mkdir_args {
381
struct dentry *dentry;
386
static void au_call_vfsub_mkdir(void *args)
388
struct au_vfsub_mkdir_args *a = args;
389
*a->errp = vfsub_mkdir(a->dir, a->dentry, a->mode, a->dlgt);
392
int vfsub_sio_mkdir(struct inode *dir, struct dentry *dentry, int mode,
395
int err, do_sio, wkq_err;
397
LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
399
do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt);
401
err = vfsub_mkdir(dir, dentry, mode, dlgt);
403
struct au_vfsub_mkdir_args args = {
410
wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args, /*dlgt*/0);
411
if (unlikely(wkq_err))
419
struct au_vfsub_rmdir_args {
422
struct dentry *dentry;
423
struct vfsub_args *vargs;
426
static void au_call_vfsub_rmdir(void *args)
428
struct au_vfsub_rmdir_args *a = args;
429
*a->errp = vfsub_rmdir(a->dir, a->dentry, a->vargs);
432
int vfsub_sio_rmdir(struct inode *dir, struct dentry *dentry, int dlgt)
434
int err, do_sio, wkq_err;
435
struct vfsub_args vargs;
437
LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
439
vfsub_args_init(&vargs, /*ign*/NULL, dlgt, /*force_unlink*/0);
440
do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt);
442
err = vfsub_rmdir(dir, dentry, &vargs);
444
struct au_vfsub_rmdir_args args = {
450
wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args, /*dlgt*/0);
451
if (unlikely(wkq_err))
459
/* ---------------------------------------------------------------------- */
461
struct notify_change_args {
463
struct dentry *h_dentry;
465
struct vfsub_args *vargs;
468
static void call_notify_change(void *args)
470
struct notify_change_args *a = args;
471
struct inode *h_inode;
473
LKTRTrace("%.*s, ia_valid 0x%x\n",
474
AuDLNPair(a->h_dentry), a->ia->ia_valid);
475
h_inode = a->h_dentry->d_inode;
479
if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
480
vfsub_ignore(a->vargs);
482
*a->errp = notify_change(a->h_dentry, a->ia);
485
au_update_fuse_h_inode(NULL, a->h_dentry); /*ignore*/
487
vfsub_unignore(a->vargs);
489
AuTraceErr(*a->errp);
492
#ifdef CONFIG_AUFS_DLGT
493
static void vfsub_notify_change_dlgt(struct notify_change_args *args,
496
if (!vfsub_ftest(flags, DLGT))
497
call_notify_change(args);
500
wkq_err = au_wkq_wait(call_notify_change, args, /*dlgt*/1);
501
if (unlikely(wkq_err))
502
*args->errp = wkq_err;
506
static void vfsub_notify_change_dlgt(struct notify_change_args *args,
509
call_notify_change(args);
513
int vfsub_notify_change(struct dentry *dentry, struct iattr *ia,
514
struct vfsub_args *vargs)
517
struct notify_change_args args = {
524
vfsub_notify_change_dlgt(&args, vargs->flags);
530
/* ---------------------------------------------------------------------- */
535
struct dentry *dentry;
536
struct vfsub_args *vargs;
539
static void call_unlink(void *args)
541
struct unlink_args *a = args;
542
struct inode *h_inode;
543
const int stop_sillyrename = (au_test_nfs(a->dentry->d_sb)
544
&& atomic_read(&a->dentry->d_count) == 1);
546
LKTRTrace("%.*s, stop_silly %d, cnt %d\n",
547
AuDLNPair(a->dentry), stop_sillyrename,
548
atomic_read(&a->dentry->d_count));
551
if (!stop_sillyrename)
553
h_inode = a->dentry->d_inode;
555
atomic_inc_return(&h_inode->i_count);
556
#if 0 // partial testing
558
struct qstr *name = &a->dentry->d_name;
559
if (name->len == sizeof(AUFS_XINO_FNAME) - 1
560
&& !strncmp(name->name, AUFS_XINO_FNAME, name->len))
561
*a->errp = do_vfsub_unlink(a->dir, a->dentry);
566
*a->errp = do_vfsub_unlink(a->dir, a->dentry);
569
if (!stop_sillyrename)
574
AuTraceErr(*a->errp);
578
* @dir: must be locked.
579
* @dentry: target dentry.
581
int vfsub_unlink(struct inode *dir, struct dentry *dentry,
582
struct vfsub_args *vargs)
585
struct unlink_args args = {
592
if (!vfsub_ftest(vargs->flags, DLGT)
593
&& !vfsub_ftest(vargs->flags, FORCE_UNLINK))
597
wkq_err = au_wkq_wait(call_unlink, &args,
598
vfsub_ftest(vargs->flags, DLGT));
599
if (unlikely(wkq_err))
606
/* ---------------------------------------------------------------------- */
614
static void call_statfs(void *args)
616
struct statfs_args *a = args;
617
*a->errp = vfs_statfs(a->arg, a->buf);
620
#ifdef CONFIG_AUFS_DLGT
621
static void vfsub_statfs_dlgt(struct statfs_args *args, int dlgt)
627
wkq_err = au_wkq_wait(call_statfs, args, /*dlgt*/1);
628
if (unlikely(wkq_err))
629
*args->errp = wkq_err;
633
static void vfsub_statfs_dlgt(struct statfs_args *args, int dlgt)
639
int vfsub_statfs(void *arg, struct kstatfs *buf, int dlgt)
642
struct statfs_args args = {
648
vfsub_statfs_dlgt(&args, dlgt);