| 
									
										
										
										
											2006-10-04 02:16:22 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * eCryptfs: Linux filesystem encryption layer | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 1997-2003 Erez Zadok | 
					
						
							|  |  |  |  * Copyright (C) 2001-2003 Stony Brook University | 
					
						
							|  |  |  |  * Copyright (C) 2004-2006 International Business Machines Corp. | 
					
						
							|  |  |  |  *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation; either version 2 of the | 
					
						
							|  |  |  |  * License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, but | 
					
						
							|  |  |  |  * WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | 
					
						
							|  |  |  |  * 02111-1307, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/dcache.h>
 | 
					
						
							|  |  |  | #include <linux/namei.h>
 | 
					
						
							| 
									
										
										
										
											2006-10-30 22:07:20 -08:00
										 |  |  | #include <linux/mount.h>
 | 
					
						
							| 
									
										
										
										
											2006-12-08 02:36:31 -08:00
										 |  |  | #include <linux/fs_stack.h>
 | 
					
						
							| 
									
										
										
										
											2006-10-04 02:16:22 -07:00
										 |  |  | #include "ecryptfs_kernel.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * ecryptfs_d_revalidate - revalidate an ecryptfs dentry | 
					
						
							|  |  |  |  * @dentry: The ecryptfs dentry | 
					
						
							|  |  |  |  * @nd: The associated nameidata | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Called when the VFS needs to revalidate a dentry. This | 
					
						
							|  |  |  |  * is called whenever a name lookup finds a dentry in the | 
					
						
							|  |  |  |  * dcache. Most filesystems leave this as NULL, because all their | 
					
						
							|  |  |  |  * dentries in the dcache are valid. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns 1 if valid, 0 otherwise. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 
					
						
							|  |  |  | 	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | 
					
						
							|  |  |  | 	struct dentry *dentry_save; | 
					
						
							|  |  |  | 	struct vfsmount *vfsmount_save; | 
					
						
							|  |  |  | 	int rc = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) | 
					
						
							|  |  |  | 		goto out; | 
					
						
							| 
									
										
										
										
											2008-02-14 19:34:32 -08:00
										 |  |  | 	dentry_save = nd->path.dentry; | 
					
						
							|  |  |  | 	vfsmount_save = nd->path.mnt; | 
					
						
							|  |  |  | 	nd->path.dentry = lower_dentry; | 
					
						
							|  |  |  | 	nd->path.mnt = lower_mnt; | 
					
						
							| 
									
										
										
										
											2006-10-04 02:16:22 -07:00
										 |  |  | 	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); | 
					
						
							| 
									
										
										
										
											2008-02-14 19:34:32 -08:00
										 |  |  | 	nd->path.dentry = dentry_save; | 
					
						
							|  |  |  | 	nd->path.mnt = vfsmount_save; | 
					
						
							| 
									
										
										
										
											2006-11-16 01:19:30 -08:00
										 |  |  | 	if (dentry->d_inode) { | 
					
						
							|  |  |  | 		struct inode *lower_inode = | 
					
						
							|  |  |  | 			ecryptfs_inode_to_lower(dentry->d_inode); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-08 02:36:31 -08:00
										 |  |  | 		fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL); | 
					
						
							| 
									
										
										
										
											2006-11-16 01:19:30 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-10-04 02:16:22 -07:00
										 |  |  | out: | 
					
						
							|  |  |  | 	return rc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct kmem_cache *ecryptfs_dentry_info_cache; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * ecryptfs_d_release | 
					
						
							|  |  |  |  * @dentry: The ecryptfs dentry | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Called when a dentry is really deallocated. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void ecryptfs_d_release(struct dentry *dentry) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-03-16 13:38:22 -08:00
										 |  |  | 	if (ecryptfs_dentry_to_private(dentry)) { | 
					
						
							|  |  |  | 		if (ecryptfs_dentry_to_lower(dentry)) { | 
					
						
							|  |  |  | 			dput(ecryptfs_dentry_to_lower(dentry)); | 
					
						
							| 
									
										
										
										
											2008-03-19 17:00:58 -07:00
										 |  |  | 			mntput(ecryptfs_dentry_to_lower_mnt(dentry)); | 
					
						
							| 
									
										
										
										
											2007-03-16 13:38:22 -08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-10-04 02:16:22 -07:00
										 |  |  | 		kmem_cache_free(ecryptfs_dentry_info_cache, | 
					
						
							|  |  |  | 				ecryptfs_dentry_to_private(dentry)); | 
					
						
							| 
									
										
										
										
											2006-10-30 22:07:20 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-10-04 02:16:22 -07:00
										 |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-20 05:57:52 +00:00
										 |  |  | const struct dentry_operations ecryptfs_dops = { | 
					
						
							| 
									
										
										
										
											2006-10-04 02:16:22 -07:00
										 |  |  | 	.d_revalidate = ecryptfs_d_revalidate, | 
					
						
							|  |  |  | 	.d_release = ecryptfs_d_release, | 
					
						
							|  |  |  | }; |