#include "aufs.h"
-int au_hn_alloc(struct au_hinode *hinode, struct inode *inode,
- struct inode *h_inode)
+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
{
int err;
struct au_hnotify *hn;
hn = au_cache_alloc_hnotify();
if (hn) {
hn->hn_aufs_inode = inode;
- err = au_hnotify_op.alloc(hn, h_inode);
- if (!err)
- hinode->hi_notify = hn;
- else {
+ hinode->hi_notify = hn;
+ err = au_hnotify_op.alloc(hinode);
+ AuTraceErr(err);
+ if (unlikely(err)) {
+ hinode->hi_notify = NULL;
au_cache_free_hnotify(hn);
/*
* The upper dir was removed by udba, but the same named
}
}
+ AuTraceErr(err);
return err;
}
hn = hinode->hi_notify;
if (hn) {
- au_hnotify_op.free(hn);
+ au_hnotify_op.free(hinode);
au_cache_free_hnotify(hn);
hinode->hi_notify = NULL;
}
if (IS_ROOT(d))
continue;
- d_drop(d);
au_digen_dec(d);
if (d->d_inode)
/* todo: reset children xino?
&& memcmp(dname->name, name, nlen))
continue;
err = 0;
- spin_lock(&d->d_lock);
- __d_drop(d);
au_digen_dec(d);
- spin_unlock(&d->d_lock);
break;
}
spin_unlock(&dcache_lock);
} else {
- au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS);
+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
d = d_find_alias(inode);
if (!d) {
au_iigen_dec(inode);
err = 0;
if (!isdir) {
- d_drop(dentry);
au_digen_dec(dentry);
if (inode)
au_iigen_dec(inode);
} else {
- au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS);
+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
if (inode)
err = hn_gen_tree(dentry);
}
dname = &d->d_name;
if (dname->len != nlen || memcmp(dname->name, name, nlen))
continue;
- if (!atomic_read(&d->d_count) || !d->d_fsdata) {
- spin_lock(&d->d_lock);
- __d_drop(d);
- spin_unlock(&d->d_lock);
+ if (au_di(d))
+ au_digen_dec(d);
+ else
+ continue;
+ if (!atomic_read(&d->d_count))
continue;
- }
dentry = dget(d);
break;
args.h_nlen = a->h_child_nlen;
err = hn_job(&args);
if (dentry) {
- if (dentry->d_fsdata)
+ if (au_di(dentry))
di_write_unlock(dentry);
dput(dentry);
}
ii_write_unlock(a->dir);
out:
- au_nwt_done(&sbinfo->si_nowait);
- si_write_unlock(sb);
-
iput(a->h_child_inode);
iput(a->h_dir);
iput(a->dir);
+ si_write_unlock(sb);
+ au_nwt_done(&sbinfo->si_nowait);
kfree(a);
}
return err;
}
+/* ---------------------------------------------------------------------- */
+
+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
+{
+ int err;
+
+ AuDebugOn(!(udba & AuOptMask_UDBA));
+
+ err = 0;
+ if (au_hnotify_op.reset_br)
+ err = au_hnotify_op.reset_br(udba, br, perm);
+
+ return err;
+}
+
+int au_hnotify_init_br(struct au_branch *br, int perm)
+{
+ int err;
+
+ err = 0;
+ if (au_hnotify_op.init_br)
+ err = au_hnotify_op.init_br(br, perm);
+
+ return err;
+}
+
+void au_hnotify_fin_br(struct au_branch *br)
+{
+ if (au_hnotify_op.fin_br)
+ au_hnotify_op.fin_br(br);
+}
+
static void au_hn_destroy_cache(void)
{
kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
err = -ENOMEM;
au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
if (au_cachep[AuCache_HNOTIFY]) {
- err = au_hnotify_op.init();
+ err = 0;
+ if (au_hnotify_op.init)
+ err = au_hnotify_op.init();
if (unlikely(err))
au_hn_destroy_cache();
}
void au_hnotify_fin(void)
{
- au_hnotify_op.fin();
+ if (au_hnotify_op.fin)
+ au_hnotify_op.fin();
/* cf. au_cache_fin() */
if (au_cachep[AuCache_HNOTIFY])
au_hn_destroy_cache();