Skip to content

Commit 45ec4ab

Browse files
Michael HalcrowLinus Torvalds
authored andcommitted
[PATCH] eCryptfs: Fix handling of lower d_count
Fix the use of dget/dput calls to balance out on the lower filesystem. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent 316bb95 commit 45ec4ab

2 files changed

Lines changed: 27 additions & 43 deletions

File tree

‎fs/ecryptfs/dentry.c‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <linux/dcache.h>
2626
#include <linux/namei.h>
27+
#include <linux/mount.h>
2728
#include "ecryptfs_kernel.h"
2829

2930
/**
@@ -76,8 +77,13 @@ static void ecryptfs_d_release(struct dentry *dentry)
7677
if (ecryptfs_dentry_to_private(dentry))
7778
kmem_cache_free(ecryptfs_dentry_info_cache,
7879
ecryptfs_dentry_to_private(dentry));
79-
if (lower_dentry)
80+
if (lower_dentry) {
81+
struct vfsmount *lower_mnt =
82+
ecryptfs_dentry_to_lower_mnt(dentry);
83+
84+
mntput(lower_mnt);
8085
dput(lower_dentry);
86+
}
8187
return;
8288
}
8389

‎fs/ecryptfs/inode.c‎

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
325325
struct dentry *lower_dir_dentry;
326326
struct dentry *lower_dentry;
327327
struct vfsmount *lower_mnt;
328-
struct dentry *tlower_dentry = NULL;
329328
char *encoded_name;
330329
unsigned int encoded_namelen;
331330
struct ecryptfs_crypt_stat *crypt_stat = NULL;
@@ -336,27 +335,32 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
336335
lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
337336
dentry->d_op = &ecryptfs_dops;
338337
if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, "."))
339-
|| (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, "..")))
340-
goto out_drop;
338+
|| (dentry->d_name.len == 2
339+
&& !strcmp(dentry->d_name.name, ".."))) {
340+
d_drop(dentry);
341+
goto out;
342+
}
341343
encoded_namelen = ecryptfs_encode_filename(crypt_stat,
342344
dentry->d_name.name,
343345
dentry->d_name.len,
344346
&encoded_name);
345347
if (encoded_namelen < 0) {
346348
rc = encoded_namelen;
347-
goto out_drop;
349+
d_drop(dentry);
350+
goto out;
348351
}
349352
ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen "
350353
"= [%d]\n", encoded_name, encoded_namelen);
351354
lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry,
352355
encoded_namelen - 1);
353356
kfree(encoded_name);
354-
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
355357
if (IS_ERR(lower_dentry)) {
356358
ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n");
357359
rc = PTR_ERR(lower_dentry);
358-
goto out_drop;
360+
d_drop(dentry);
361+
goto out;
359362
}
363+
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
360364
ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->"
361365
"d_name.name = [%s]\n", lower_dentry,
362366
lower_dentry->d_name.name);
@@ -397,12 +401,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
397401
"as we *think* we are about to unlink\n");
398402
goto out;
399403
}
400-
tlower_dentry = dget(lower_dentry);
401-
if (!tlower_dentry || IS_ERR(tlower_dentry)) {
402-
rc = -ENOMEM;
403-
ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n");
404-
goto out_dput;
405-
}
406404
/* Released in this function */
407405
page_virt =
408406
(char *)kmem_cache_alloc(ecryptfs_header_cache_2,
@@ -414,7 +412,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
414412
goto out_dput;
415413
}
416414
memset(page_virt, 0, PAGE_CACHE_SIZE);
417-
rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt);
415+
rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt);
418416
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
419417
if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
420418
ecryptfs_set_default_sizes(crypt_stat);
@@ -437,9 +435,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
437435

438436
out_dput:
439437
dput(lower_dentry);
440-
if (tlower_dentry)
441-
dput(tlower_dentry);
442-
out_drop:
443438
d_drop(dentry);
444439
out:
445440
return ERR_PTR(rc);
@@ -475,8 +470,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
475470
unlock_dir(lower_dir_dentry);
476471
dput(lower_new_dentry);
477472
dput(lower_old_dentry);
478-
if (!new_dentry->d_inode)
479-
d_drop(new_dentry);
473+
d_drop(new_dentry);
474+
d_drop(old_dentry);
480475
return rc;
481476
}
482477

@@ -565,41 +560,24 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
565560

566561
static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
567562
{
568-
int rc = 0;
569-
struct dentry *tdentry = NULL;
570563
struct dentry *lower_dentry;
571-
struct dentry *tlower_dentry = NULL;
572564
struct dentry *lower_dir_dentry;
565+
int rc;
573566

574567
lower_dentry = ecryptfs_dentry_to_lower(dentry);
575-
if (!(tdentry = dget(dentry))) {
576-
rc = -EINVAL;
577-
ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n",
578-
dentry);
579-
goto out;
580-
}
568+
dget(dentry);
581569
lower_dir_dentry = lock_parent(lower_dentry);
582-
if (!(tlower_dentry = dget(lower_dentry))) {
583-
rc = -EINVAL;
584-
ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry "
585-
"[%p]\n", lower_dentry);
586-
goto out;
587-
}
570+
dget(lower_dentry);
588571
rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
589-
if (!rc) {
590-
d_delete(tlower_dentry);
591-
tlower_dentry = NULL;
592-
}
572+
dput(lower_dentry);
573+
if (!rc)
574+
d_delete(lower_dentry);
593575
ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode);
594576
dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
595577
unlock_dir(lower_dir_dentry);
596578
if (!rc)
597579
d_drop(dentry);
598-
out:
599-
if (tdentry)
600-
dput(tdentry);
601-
if (tlower_dentry)
602-
dput(tlower_dentry);
580+
dput(dentry);
603581
return rc;
604582
}
605583

0 commit comments

Comments
 (0)