pr_debug("unionfs: trying to rename %s to %s\n",
dentry->d_name.name, name);
- tmp_dentry = lookup_one_len(name, lower_dentry->d_parent,
+ tmp_dentry = lookup_lck_len(name, lower_dentry->d_parent,
nlen);
if (IS_ERR(tmp_dentry)) {
err = PTR_ERR(tmp_dentry);
if (child_dentry != dentry) {
/* lookup child in the underlying file system */
- lower_dentry = lookup_one_len(childname, lower_parent_dentry,
+ lower_dentry = lookup_lck_len(childname, lower_parent_dentry,
childnamelen);
if (IS_ERR(lower_dentry))
goto out;
* Is the name a whiteout of the child name ? lookup the
* whiteout child in the underlying file system
*/
- lower_dentry = lookup_one_len(name, lower_parent_dentry,
+ lower_dentry = lookup_lck_len(name, lower_parent_dentry,
strlen(name));
if (IS_ERR(lower_dentry))
goto out;
* it's safe to call lookup_one_len (which doesn't take a
* vfsmount).
*/
- dentry = lookup_one_len(name, base, strlen(name));
+ dentry = lookup_lck_len(name, base, strlen(name));
if (new_mnt)
*new_mnt = mntget(lower_nd.path.mnt);
break;
if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode))
goto out; /* XXX: should be BUG_ON */
/* XXX: do we need to cross bind mounts here? */
- lower_dentry = lookup_one_len(name, lower_dir_dentry, namelen);
+ lower_dentry = lookup_lck_len(name, lower_dir_dentry, namelen);
if (IS_ERR(lower_dentry)) {
err = PTR_ERR(lower_dentry);
goto out;
dput(dir);
}
+/* lock base inode mutex before calling lookup_one_len */
+static inline struct dentry *lookup_lck_len(const char *name,
+ struct dentry *base, int len)
+{
+ struct dentry *d;
+ mutex_lock(&base->d_inode->i_mutex);
+ d = lookup_one_len(name, base, len);
+ mutex_unlock(&base->d_inode->i_mutex);
+ return d;
+}
+
static inline struct vfsmount *unionfs_mntget(struct dentry *dentry,
int bindex)
{
}
/* check if whiteout exists in this branch: lookup .wh.foo */
- wh_dentry = lookup_one_len(whname, lower_parent, strlen(whname));
+ wh_dentry = lookup_lck_len(whname, lower_parent, strlen(whname));
if (IS_ERR(wh_dentry)) {
err = PTR_ERR(wh_dentry);
goto out;
}
lower_wh_dentry =
- lookup_one_len(name, lower_dentry->d_parent,
+ lookup_lck_len(name, lower_dentry->d_parent,
dentry->d_name.len + UNIONFS_WHLEN);
if (IS_ERR(lower_wh_dentry))
continue;
if (!err)
err = vfs_create(lower_dir_dentry->d_inode,
lower_wh_dentry,
- ~current->fs->umask & S_IRUGO,
+ current_umask() & S_IRUGO,
&nd);
unlock_dir(lower_dir_dentry);
dput(lower_wh_dentry);
strlcpy(p, cursor->name, PATH_MAX - UNIONFS_WHLEN);
lower_dentry =
- lookup_one_len(name, lower_dir_dentry,
+ lookup_lck_len(name, lower_dir_dentry,
cursor->namelen +
UNIONFS_WHLEN);
if (IS_ERR(lower_dentry)) {