本文整理汇总了C++中si_read_unlock函数的典型用法代码示例。如果您正苦于以下问题:C++ si_read_unlock函数的具体用法?C++ si_read_unlock怎么用?C++ si_read_unlock使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了si_read_unlock函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: aufs_poll
unsigned int aufs_poll(struct file *file, poll_table *wait)
{
unsigned int mask;
int err;
struct file *h_file;
struct dentry *dentry;
struct super_block *sb;
/* We should pretend an error happened. */
mask = POLLERR /* | POLLIN | POLLOUT */;
dentry = file->f_path.dentry;
sb = dentry->d_sb;
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
if (unlikely(err))
goto out;
/* it is not an error if h_file has no operation */
mask = DEFAULT_POLLMASK;
h_file = au_hf_top(file);
if (h_file->f_op->poll)
mask = h_file->f_op->poll(h_file, wait);
di_read_unlock(dentry, AuLock_IR);
fi_read_unlock(file);
out:
si_read_unlock(sb);
AuTraceErr((int)mask);
return mask;
}
示例2: aufs_aio_write_sp
static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
unsigned long nv, loff_t pos)
{
ssize_t err;
aufs_bindex_t bstart;
unsigned char wbr;
struct super_block *sb;
struct file *file, *h_file;
file = kio->ki_filp;
sb = file->f_dentry->d_sb;
si_read_lock(sb, AuLock_FLUSH);
fi_read_lock(file);
bstart = au_fbstart(file);
h_file = au_hf_top(file);
fi_read_unlock(file);
wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
si_read_unlock(sb);
/* do not change the file in kio */
AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
err = h_file->f_op->aio_write(kio, iov, nv, pos);
if (err > 0 && wbr)
file_update_time(h_file);
return err;
}
示例3: au_ibusy
static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
{
int err;
aufs_bindex_t bstart, bend;
struct aufs_ibusy ibusy;
struct inode *inode, *h_inode;
err = -EPERM;
if (unlikely(!capable(CAP_SYS_ADMIN)))
goto out;
err = copy_from_user(&ibusy, arg, sizeof(ibusy));
if (!err)
err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
if (unlikely(err)) {
err = -EFAULT;
AuTraceErr(err);
goto out;
}
err = -EINVAL;
si_read_lock(sb, AuLock_FLUSH);
if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
goto out_unlock;
err = 0;
ibusy.h_ino = 0; /* invalid */
inode = ilookup(sb, ibusy.ino);
if (!inode
|| inode->i_ino == AUFS_ROOT_INO
|| is_bad_inode(inode))
goto out_unlock;
ii_read_lock_child(inode);
bstart = au_ibstart(inode);
bend = au_ibend(inode);
if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
h_inode = au_h_iptr(inode, ibusy.bindex);
if (h_inode && au_test_ibusy(inode, bstart, bend))
ibusy.h_ino = h_inode->i_ino;
}
ii_read_unlock(inode);
iput(inode);
out_unlock:
si_read_unlock(sb);
if (!err) {
err = __put_user(ibusy.h_ino, &arg->h_ino);
if (unlikely(err)) {
err = -EFAULT;
AuTraceErr(err);
}
}
out:
return err;
}
示例4: aufs_commit_metadata
static int aufs_commit_metadata(struct inode *inode)
{
int err;
aufs_bindex_t bindex;
struct super_block *sb;
struct inode *h_inode;
int (*f)(struct inode *inode);
sb = inode->i_sb;
si_read_lock(sb, AuLock_FLUSH);
ii_write_lock_child(inode);
bindex = au_ibstart(inode);
AuDebugOn(bindex < 0);
h_inode = au_h_iptr(inode, bindex);
f = h_inode->i_sb->s_export_op->commit_metadata;
if (f)
err = f(h_inode);
else {
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = 0 /* metadata only */
};
err = sync_inode(h_inode, &wbc);
}
au_cpup_attr_timesizes(inode);
ii_write_unlock(inode);
si_read_unlock(sb);
return err;
}
/* ---------------------------------------------------------------------- */
static struct export_operations aufs_export_op = {
.fh_to_dentry = aufs_fh_to_dentry,
/* .fh_to_parent = aufs_fh_to_parent, */
.encode_fh = aufs_encode_fh,
.commit_metadata = aufs_commit_metadata
};
void au_export_init(struct super_block *sb)
{
struct au_sbinfo *sbinfo;
__u32 u;
sb->s_export_op = &aufs_export_op;
sbinfo = au_sbi(sb);
sbinfo->si_xigen = NULL;
get_random_bytes(&u, sizeof(u));
BUILD_BUG_ON(sizeof(u) != sizeof(int));
atomic_set(&sbinfo->si_xigen_next, u);
}
示例5: au_fhsm_fd
int au_fhsm_fd(struct super_block *sb, int oflags)
{
int err, fd;
struct au_sbinfo *sbinfo;
struct au_fhsm *fhsm;
err = -EPERM;
if (unlikely(!capable(CAP_SYS_ADMIN)))
goto out;
err = -EINVAL;
if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
goto out;
err = 0;
sbinfo = au_sbi(sb);
fhsm = &sbinfo->si_fhsm;
spin_lock(&fhsm->fhsm_spin);
if (!fhsm->fhsm_pid)
fhsm->fhsm_pid = current->pid;
else
err = -EBUSY;
spin_unlock(&fhsm->fhsm_spin);
if (unlikely(err))
goto out;
oflags |= O_RDONLY;
/* oflags |= FMODE_NONOTIFY; */
fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
err = fd;
if (unlikely(fd < 0))
goto out_pid;
/* succeed reglardless 'fhsm' status */
kobject_get(&sbinfo->si_kobj);
si_noflush_read_lock(sb);
if (au_ftest_si(sbinfo, FHSM))
au_fhsm_wrote_all(sb, /*force*/0);
si_read_unlock(sb);
goto out; /* success */
out_pid:
spin_lock(&fhsm->fhsm_spin);
fhsm->fhsm_pid = 0;
spin_unlock(&fhsm->fhsm_spin);
out:
AuTraceErr(err);
return err;
}
示例6: IMustLock
static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
struct dentry *ret, *parent;
struct inode *inode;
struct super_block *sb;
int err, npositive;
IMustLock(dir);
sb = dir->i_sb;
si_read_lock(sb, AuLock_FLUSH);
ret = ERR_PTR(-ENAMETOOLONG);
if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
goto out;
err = au_di_init(dentry);
ret = ERR_PTR(err);
if (unlikely(err))
goto out;
parent = dentry->d_parent; /* dir inode is locked */
di_read_lock_parent(parent, AuLock_IR);
npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, nd);
di_read_unlock(parent, AuLock_IR);
err = npositive;
ret = ERR_PTR(err);
if (unlikely(err < 0))
goto out_unlock;
inode = NULL;
if (npositive) {
inode = au_new_inode(dentry, /*must_new*/0);
ret = (void *)inode;
}
if (IS_ERR(inode))
goto out_unlock;
ret = d_splice_alias(inode, dentry);
if (unlikely(IS_ERR(ret) && inode))
ii_write_unlock(inode);
out_unlock:
di_write_unlock(dentry);
out:
si_read_unlock(sb);
return ret;
}
示例7: au_rdu_ino
static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
{
int err;
ino_t ino;
unsigned long long nent;
union au_rdu_ent_ul *u;
struct au_rdu_ent ent;
struct super_block *sb;
err = 0;
nent = rdu->nent;
u = &rdu->ent;
sb = file->f_dentry->d_sb;
si_read_lock(sb, AuLock_FLUSH);
while (nent-- > 0) {
err = copy_from_user(&ent, u->e, sizeof(ent));
if (!err)
err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
if (unlikely(err)) {
err = -EFAULT;
AuTraceErr(err);
break;
}
/* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
if (!ent.wh)
err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
else
err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
&ino);
if (unlikely(err)) {
AuTraceErr(err);
break;
}
err = __put_user(ino, &u->e->ino);
if (unlikely(err)) {
err = -EFAULT;
AuTraceErr(err);
break;
}
u->ul += au_rdu_len(ent.nlen);
}
si_read_unlock(sb);
return err;
}
示例8: si_nfsd_read_lock
static aufs_bindex_t si_nfsd_read_lock(struct super_block *sb,
struct au_nfsd_si_lock *nsi_lock)
{
aufs_bindex_t bindex;
si_read_lock(sb, AuLock_FLUSH);
/* branch id may be wrapped around */
bindex = au_br_index(sb, nsi_lock->br_id);
if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
goto out; /* success */
if (!nsi_lock->force_lock)
si_read_unlock(sb);
bindex = -1;
out:
return bindex;
}
示例9: au_do_open
int au_do_open(struct file *file, int (*open)(struct file *file, int flags))
{
int err;
struct dentry *dentry;
struct super_block *sb;
dentry = file->f_dentry;
sb = dentry->d_sb;
si_read_lock(sb, AuLock_FLUSH);
err = au_finfo_init(file);
if (unlikely(err))
goto out;
di_read_lock_child(dentry, AuLock_IR);
err = open(file, vfsub_file_flags(file));
di_read_unlock(dentry, AuLock_IR);
fi_write_unlock(file);
if (unlikely(err))
au_finfo_fin(file);
out:
si_read_unlock(sb);
return err;
}
示例10: aufs_decode_fh
static struct dentry *
aufs_decode_fh(struct super_block *sb, __u32 *fh, int fh_len, int fh_type,
int (*acceptable)(void *context, struct dentry *de),
void *context)
{
struct dentry *dentry;
ino_t ino, dir_ino;
aufs_bindex_t bindex;
struct au_nfsd_si_lock nsi_lock = {
.sigen = fh[Fh_sigen],
.br_id = fh[Fh_br_id],
.force_lock = 0
};
LKTRTrace("%d, fh{br_id %u, sigen %u, i%u, diri%u, g%u}\n",
fh_type, fh[Fh_br_id], fh[Fh_sigen], fh[Fh_ino],
fh[Fh_dir_ino], fh[Fh_igen]);
AuDebugOn(fh_len < Fh_tail);
dentry = ERR_PTR(-ESTALE);
/* branch id may be wrapped around */
bindex = si_nfsd_read_lock(sb, &nsi_lock);
if (unlikely(bindex < 0))
goto out;
nsi_lock.force_lock = 1;
/* is this inode still cached? */
ino = decode_ino(fh + Fh_ino);
AuDebugOn(ino == AUFS_ROOT_INO);
dir_ino = decode_ino(fh + Fh_dir_ino);
dentry = decode_by_ino(sb, ino, dir_ino);
if (IS_ERR(dentry))
goto out_unlock;
if (dentry)
goto accept;
/* is the parent dir cached? */
dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
if (IS_ERR(dentry))
goto out_unlock;
if (dentry)
goto accept;
/* lookup path */
dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock);
if (IS_ERR(dentry))
goto out_unlock;
if (unlikely(!dentry))
goto out_unlock;
accept:
LKTRLabel(accept);
if (dentry->d_inode->i_generation == fh[Fh_igen]
&& acceptable(context, dentry))
goto out_unlock; /* success */
LKTRLabel(stale);
dput(dentry);
dentry = ERR_PTR(-ESTALE);
out_unlock:
LKTRLabel(out_unlock);
si_read_unlock(sb);
out:
LKTRLabel(out);
if (0 && IS_ERR(dentry))
dentry = ERR_PTR(-ESTALE);
AuTraceErrPtr(dentry);
return dentry;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
static struct dentry *
aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
int fh_type)
{
return aufs_decode_fh(sb, fid->raw, fh_len, fh_type, h_acceptable,
/*context*/NULL);
}
#endif /* KERNEL_VERSION */
/* ---------------------------------------------------------------------- */
static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
int connectable)
{
int err;
aufs_bindex_t bindex, bend;
struct super_block *sb, *h_sb;
struct inode *inode;
struct dentry *parent, *h_parent;
struct au_branch *br;
LKTRTrace("%.*s, max %d, conn %d\n",
AuDLNPair(dentry), *max_len, connectable);
AuDebugOn(au_test_anon(dentry));
parent = NULL;
err = -ENOSPC;
if (unlikely(*max_len <= Fh_tail)) {
AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
//.........这里部分代码省略.........
示例11: IMustLock
static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags)
{
struct dentry *ret, *parent;
struct inode *inode;
struct super_block *sb;
int err, npositive;
IMustLock(dir);
/* todo: support rcu-walk? */
ret = ERR_PTR(-ECHILD);
if (flags & LOOKUP_RCU)
goto out;
ret = ERR_PTR(-ENAMETOOLONG);
if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
goto out;
sb = dir->i_sb;
err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
ret = ERR_PTR(err);
if (unlikely(err))
goto out;
err = au_di_init(dentry);
ret = ERR_PTR(err);
if (unlikely(err))
goto out_si;
inode = NULL;
npositive = 0; /* suppress a warning */
parent = dentry->d_parent; /* dir inode is locked */
di_read_lock_parent(parent, AuLock_IR);
err = au_alive_dir(parent);
if (!err)
err = au_digen_test(parent, au_sigen(sb));
if (!err) {
/* regardless LOOKUP_CREATE, always ALLOW_NEG */
npositive = au_lkup_dentry(dentry, au_dbtop(parent),
AuLkup_ALLOW_NEG);
err = npositive;
}
di_read_unlock(parent, AuLock_IR);
ret = ERR_PTR(err);
if (unlikely(err < 0))
goto out_unlock;
if (npositive) {
inode = au_new_inode(dentry, /*must_new*/0);
if (IS_ERR(inode)) {
ret = (void *)inode;
inode = NULL;
goto out_unlock;
}
}
if (inode)
atomic_inc(&inode->i_count);
ret = d_splice_alias(inode, dentry);
#if 0
if (unlikely(d_need_lookup(dentry))) {
spin_lock(&dentry->d_lock);
dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
spin_unlock(&dentry->d_lock);
} else
#endif
if (inode) {
if (!IS_ERR(ret)) {
iput(inode);
if (ret && ret != dentry)
ii_write_unlock(inode);
} else {
ii_write_unlock(inode);
iput(inode);
inode = NULL;
}
}
out_unlock:
di_write_unlock(dentry);
out_si:
si_read_unlock(sb);
out:
return ret;
}
示例12: si_read_unlock
static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
struct au_nfsd_si_lock *nsi_lock)
{
struct dentry *dentry, *parent;
struct file *file;
struct inode *dir;
struct find_name_by_ino arg;
int err;
parent = path->dentry;
if (nsi_lock)
si_read_unlock(parent->d_sb);
file = vfsub_dentry_open(path, au_dir_roflags);
dentry = (void *)file;
if (IS_ERR(file))
goto out;
dentry = ERR_PTR(-ENOMEM);
arg.name = __getname_gfp(GFP_NOFS);
if (unlikely(!arg.name))
goto out_file;
arg.ino = ino;
arg.found = 0;
do {
arg.called = 0;
/* smp_mb(); */
err = vfsub_readdir(file, find_name_by_ino, &arg);
} while (!err && !arg.found && arg.called);
dentry = ERR_PTR(err);
if (unlikely(err))
goto out_name;
dentry = ERR_PTR(-ENOENT);
if (!arg.found)
goto out_name;
/* do not call au_lkup_one() */
dir = parent->d_inode;
mutex_lock(&dir->i_mutex);
dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
mutex_unlock(&dir->i_mutex);
AuTraceErrPtr(dentry);
if (IS_ERR(dentry))
goto out_name;
AuDebugOn(au_test_anon(dentry));
if (unlikely(!dentry->d_inode)) {
dput(dentry);
dentry = ERR_PTR(-ENOENT);
}
out_name:
__putname(arg.name);
out_file:
fput(file);
out:
if (unlikely(nsi_lock
&& si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
if (!IS_ERR(dentry)) {
dput(dentry);
dentry = ERR_PTR(-ESTALE);
}
AuTraceErrPtr(dentry);
return dentry;
}
示例13: au_do_open
int au_do_open(struct inode *inode, struct file *file,
int (*open)(struct file *file, int flags))
{
int err, coo;
struct dentry *dentry;
struct super_block *sb;
aufs_bindex_t bstart;
struct inode *h_dir, *dir;
dentry = file->f_dentry;
LKTRTrace("i%lu, %.*s\n", inode->i_ino, DLNPair(dentry));
sb = dentry->d_sb;
si_read_lock(sb);
coo = 0;
#if 0
switch (au_flag_test_coo(sb)) {
case AuFlag_COO_LEAF:
coo = !S_ISDIR(inode->i_mode);
break;
case AuFlag_COO_ALL:
coo = 1;
break;
}
#endif
err = au_init_finfo(file);
//if (LktrCond) {fi_write_unlock(file); fin_finfo(file); err = -1;}
if (unlikely(err))
goto out;
if (!coo) {
di_read_lock_child(dentry, AUFS_I_RLOCK);
bstart = dbstart(dentry);
} else {
di_write_lock_child(dentry);
bstart = dbstart(dentry);
if (test_ro(sb, bstart, dentry->d_inode)) {
err = do_coo(dentry, bstart);
if (err) {
di_write_unlock(dentry);
goto out_finfo;
}
bstart = dbstart(dentry);
}
di_downgrade_lock(dentry, AUFS_I_RLOCK);
}
// todo: remove this extra locks
dir = dentry->d_parent->d_inode;
if (!IS_ROOT(dentry))
ii_read_lock_parent(dir);
h_dir = au_h_iptr_i(dir, bstart);
hdir_lock(h_dir, dir, bstart);
err = open(file, file->f_flags);
//if (LktrCond) err = -1;
hdir_unlock(h_dir, dir, bstart);
if (!IS_ROOT(dentry))
ii_read_unlock(dir);
di_read_unlock(dentry, AUFS_I_RLOCK);
out_finfo:
fi_write_unlock(file);
if (unlikely(err))
au_fin_finfo(file);
//DbgFile(file);
out:
si_read_unlock(sb);
TraceErr(err);
return err;
}
示例14: au_ready_to_write_wh
//.........这里部分代码省略.........
AuDebugOn(au_special_file(inode->i_mode));
cpg.bsrc = au_fbstart(file);
err = au_test_ro(sb, cpg.bsrc, inode);
if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
/*flags*/0);
goto out;
}
/* need to cpup or reopen */
parent = dget_parent(cpg.dentry);
di_write_lock_parent(parent);
err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
cpg.bdst = err;
if (unlikely(err < 0))
goto out_dgrade;
err = 0;
if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
err = au_cpup_dirs(cpg.dentry, cpg.bdst);
if (unlikely(err))
goto out_dgrade;
}
err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
AuPin_DI_LOCKED | AuPin_MNT_WRITE);
if (unlikely(err))
goto out_dgrade;
h_dentry = au_hf_top(file)->f_dentry;
dbstart = au_dbstart(cpg.dentry);
if (dbstart <= cpg.bdst) {
h_dentry = au_h_dptr(cpg.dentry, cpg.bdst);
AuDebugOn(!h_dentry);
cpg.bsrc = cpg.bdst;
}
if (dbstart <= cpg.bdst /* just reopen */
|| !d_unhashed(cpg.dentry) /* copyup and reopen */
) {
h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
if (IS_ERR(h_file))
err = PTR_ERR(h_file);
else {
di_downgrade_lock(parent, AuLock_IR);
if (dbstart > cpg.bdst)
err = au_sio_cpup_simple(&cpg);
if (!err)
err = au_reopen_nondir(file);
au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
}
} else { /* copyup as wh and reopen */
/*
* since writable hfsplus branch is not supported,
* h_open_pre/post() are unnecessary.
*/
err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
di_downgrade_lock(parent, AuLock_IR);
}
if (!err) {
au_pin_set_parent_lflag(pin, /*lflag*/0);
goto out_dput; /* success */
}
au_unpin(pin);
goto out_unlock;
out_dgrade:
di_downgrade_lock(parent, AuLock_IR);
out_unlock:
di_read_unlock(parent, AuLock_IR);
out_dput:
dput(parent);
out:
return err;
}
/* ---------------------------------------------------------------------- */
int au_do_flush(struct file *file, fl_owner_t id,
int (*flush)(struct file *file, fl_owner_t id))
{
int err;
struct super_block *sb;
struct inode *inode;
inode = file_inode(file);
sb = inode->i_sb;
si_noflush_read_lock(sb);
fi_read_lock(file);
ii_read_lock_child(inode);
err = flush(file, id);
au_cpup_attr_timesizes(inode);
ii_read_unlock(inode);
fi_read_unlock(file);
si_read_unlock(sb);
return err;
}
示例15: aufs_fh_to_dentry
static struct dentry *
aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
int fh_type)
{
struct dentry *dentry;
__u32 *fh = fid->raw;
ino_t ino, dir_ino;
aufs_bindex_t bindex;
struct au_nfsd_si_lock nsi_lock = {
.force_lock = 0
};
dentry = ERR_PTR(-ESTALE);
/* it should never happen, but the file handle is unreliable */
if (unlikely(fh_len < Fh_tail))
goto out;
nsi_lock.sigen = fh[Fh_sigen];
nsi_lock.br_id = fh[Fh_br_id];
/* branch id may be wrapped around */
bindex = si_nfsd_read_lock(sb, &nsi_lock);
if (unlikely(bindex < 0))
goto out;
nsi_lock.force_lock = 1;
/* is this inode still cached? */
ino = decode_ino(fh + Fh_ino);
/* it should never happen */
if (unlikely(ino == AUFS_ROOT_INO))
goto out;
dir_ino = decode_ino(fh + Fh_dir_ino);
dentry = decode_by_ino(sb, ino, dir_ino);
if (IS_ERR(dentry))
goto out_unlock;
if (dentry)
goto accept;
/* is the parent dir cached? */
dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
if (IS_ERR(dentry))
goto out_unlock;
if (dentry)
goto accept;
/* lookup path */
dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock);
if (IS_ERR(dentry))
goto out_unlock;
if (unlikely(!dentry))
/* todo?: make it ESTALE */
goto out_unlock;
accept:
if (dentry->d_inode->i_generation == fh[Fh_igen])
goto out_unlock; /* success */
dput(dentry);
dentry = ERR_PTR(-ESTALE);
out_unlock:
si_read_unlock(sb);
out:
AuTraceErrPtr(dentry);
return dentry;
}
#if 0 /* reserved for future use */
/* support subtreecheck option */
static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type)
{
struct dentry *parent;
__u32 *fh = fid->raw;
ino_t dir_ino;
dir_ino = decode_ino(fh + Fh_dir_ino);
parent = decode_by_ino(sb, dir_ino, 0);
if (IS_ERR(parent))
goto out;
if (!parent)
parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
dir_ino, fh, fh_len);
out:
AuTraceErrPtr(parent);
return parent;
}
#endif
/* ---------------------------------------------------------------------- */
static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
int connectable)
{
int err;
aufs_bindex_t bindex, bend;
struct super_block *sb, *h_sb;
struct inode *inode;
struct dentry *parent, *h_parent;
struct au_branch *br;
//.........这里部分代码省略.........