bend = dbend(dentry);
BUG_ON(bstart == -1);
for (bindex = bstart; bindex <= bend; bindex++) {
+ int err;
+ struct nameidata lower_nd;
+
lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
if (!lower_dentry || !lower_dentry->d_op
|| !lower_dentry->d_op->d_revalidate)
* invariants). We will open lower files as and when needed
* later on.
*/
- if (!lower_dentry->d_op->d_revalidate(lower_dentry, NULL))
+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
+ if (unlikely(err < 0)) {
+ valid = false;
+ break;
+ }
+ if (!lower_dentry->d_op->d_revalidate(lower_dentry, &lower_nd))
valid = false;
+ release_lower_nd(&lower_nd, err);
}
if (!dentry->d_inode ||
struct dentry *lower_dentry;
struct dentry *lower_parent;
int err = 0;
+ struct nameidata lower_nd;
verify_locked(dentry);
BUG_ON(!S_ISDIR(lower_parent->d_inode->i_mode));
- lower_dentry = lookup_one_len(dentry->d_name.name, lower_parent,
- dentry->d_name.len);
+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
+ if (unlikely(err < 0))
+ goto out;
+ lower_dentry = lookup_one_len_nd(dentry->d_name.name, lower_parent,
+ dentry->d_name.len, &lower_nd);
+ release_lower_nd(&lower_nd, err);
if (IS_ERR(lower_dentry)) {
err = PTR_ERR(lower_dentry);
goto out;
struct dentry *base, int len)
{
struct dentry *d;
+ struct nameidata lower_nd;
+ int err;
+
+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
+ if (unlikely(err < 0)) {
+ d = ERR_PTR(err);
+ goto out;
+ }
mutex_lock(&base->d_inode->i_mutex);
- d = lookup_one_len(name, base, len);
+ d = lookup_one_len_nd(name, base, len, &lower_nd);
+ release_lower_nd(&lower_nd, err);
mutex_unlock(&base->d_inode->i_mutex);
+out:
return d;
}
struct dentry *wh_lower_dentry;
struct inode *lower_inode;
struct sioq_args args;
+ struct nameidata lower_nd;
lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
lower_inode = lower_dentry->d_inode;
mutex_lock(&lower_inode->i_mutex);
if (!inode_permission(lower_inode, MAY_EXEC)) {
+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
+ if (unlikely(err < 0)) {
+ mutex_unlock(&lower_inode->i_mutex);
+ goto out;
+ }
wh_lower_dentry =
- lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
- sizeof(UNIONFS_DIR_OPAQUE) - 1);
+ lookup_one_len_nd(UNIONFS_DIR_OPAQUE, lower_dentry,
+ sizeof(UNIONFS_DIR_OPAQUE) - 1,
+ &lower_nd);
+ release_lower_nd(&lower_nd, err);
} else {
args.is_opaque.dentry = lower_dentry;
run_sioq(__is_opaque_dir, &args);
void __is_opaque_dir(struct work_struct *work)
{
struct sioq_args *args = container_of(work, struct sioq_args, work);
+ struct nameidata lower_nd;
+ int err;
- args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE, args->is_opaque.dentry,
- sizeof(UNIONFS_DIR_OPAQUE) - 1);
+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
+ if (unlikely(err < 0))
+ return;
+ args->ret = lookup_one_len_nd(UNIONFS_DIR_OPAQUE,
+ args->is_opaque.dentry,
+ sizeof(UNIONFS_DIR_OPAQUE) - 1,
+ &lower_nd);
+ release_lower_nd(&lower_nd, err);
complete(&args->comp);
}
!S_ISDIR(lower_dir->i_mode));
mutex_lock(&lower_dir->i_mutex);
- diropq = lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
- sizeof(UNIONFS_DIR_OPAQUE) - 1);
+ err = init_lower_nd(&nd, LOOKUP_OPEN);
+ if (unlikely(err < 0))
+ goto out;
+ diropq = lookup_one_len_nd(UNIONFS_DIR_OPAQUE, lower_dentry,
+ sizeof(UNIONFS_DIR_OPAQUE) - 1, &nd);
+ release_lower_nd(&nd, err);
if (IS_ERR(diropq)) {
err = PTR_ERR(diropq);
goto out;