|
@@ -44,15 +44,15 @@
|
|
|
*/
|
|
|
static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
|
|
|
{
|
|
|
- struct dentry *lower_dentry;
|
|
|
- int rc = 1;
|
|
|
+ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ if (!(lower_dentry->d_flags & DCACHE_OP_REVALIDATE))
|
|
|
+ return 1;
|
|
|
|
|
|
if (flags & LOOKUP_RCU)
|
|
|
return -ECHILD;
|
|
|
|
|
|
- lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
|
|
- if (!(lower_dentry->d_flags & DCACHE_OP_REVALIDATE))
|
|
|
- goto out;
|
|
|
rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
|
|
|
if (dentry->d_inode) {
|
|
|
struct inode *lower_inode =
|
|
@@ -60,12 +60,17 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
|
|
|
|
|
|
fsstack_copy_attr_all(dentry->d_inode, lower_inode);
|
|
|
}
|
|
|
-out:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
struct kmem_cache *ecryptfs_dentry_info_cache;
|
|
|
|
|
|
+static void ecryptfs_dentry_free_rcu(struct rcu_head *head)
|
|
|
+{
|
|
|
+ kmem_cache_free(ecryptfs_dentry_info_cache,
|
|
|
+ container_of(head, struct ecryptfs_dentry_info, rcu));
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* ecryptfs_d_release
|
|
|
* @dentry: The ecryptfs dentry
|
|
@@ -74,15 +79,12 @@ struct kmem_cache *ecryptfs_dentry_info_cache;
|
|
|
*/
|
|
|
static void ecryptfs_d_release(struct dentry *dentry)
|
|
|
{
|
|
|
- if (ecryptfs_dentry_to_private(dentry)) {
|
|
|
- if (ecryptfs_dentry_to_lower(dentry)) {
|
|
|
- dput(ecryptfs_dentry_to_lower(dentry));
|
|
|
- mntput(ecryptfs_dentry_to_lower_mnt(dentry));
|
|
|
- }
|
|
|
- kmem_cache_free(ecryptfs_dentry_info_cache,
|
|
|
- ecryptfs_dentry_to_private(dentry));
|
|
|
+ struct ecryptfs_dentry_info *p = dentry->d_fsdata;
|
|
|
+ if (p) {
|
|
|
+ if (p->lower_path.dentry)
|
|
|
+ path_put(&p->lower_path);
|
|
|
+ call_rcu(&p->rcu, ecryptfs_dentry_free_rcu);
|
|
|
}
|
|
|
- return;
|
|
|
}
|
|
|
|
|
|
const struct dentry_operations ecryptfs_dops = {
|