diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-10-16 04:28:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:12 -0400 |
commit | 4981e081cfe2c3f4abcfa3924ebd999cdbed4914 (patch) | |
tree | 066d56ba49195eb0e733236fef4bb98f2d5f0114 /fs/ecryptfs/main.c | |
parent | 0216f7f7921759211e48e8b940eae29f0fe43902 (diff) |
eCryptfs: set up and destroy persistent lower file
This patch sets up and destroys the persistent lower file for each eCryptfs
inode.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/main.c')
-rw-r--r-- | fs/ecryptfs/main.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 49545951912f..fb9d85b5c7b8 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -99,6 +99,64 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | /** | 101 | /** |
102 | * ecryptfs_init_persistent_file | ||
103 | * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with | ||
104 | * the lower dentry and the lower mount set | ||
105 | * | ||
106 | * eCryptfs only ever keeps a single open file for every lower | ||
107 | * inode. All I/O operations to the lower inode occur through that | ||
108 | * file. When the first eCryptfs dentry that interposes with the first | ||
109 | * lower dentry for that inode is created, this function creates the | ||
110 | * persistent file struct and associates it with the eCryptfs | ||
111 | * inode. When the eCryptfs inode is destroyed, the file is closed. | ||
112 | * | ||
113 | * The persistent file will be opened with read/write permissions, if | ||
114 | * possible. Otherwise, it is opened read-only. | ||
115 | * | ||
116 | * This function does nothing if a lower persistent file is already | ||
117 | * associated with the eCryptfs inode. | ||
118 | * | ||
119 | * Returns zero on success; non-zero otherwise | ||
120 | */ | ||
121 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | ||
122 | { | ||
123 | struct ecryptfs_inode_info *inode_info = | ||
124 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | ||
125 | int rc = 0; | ||
126 | |||
127 | mutex_lock(&inode_info->lower_file_mutex); | ||
128 | if (!inode_info->lower_file) { | ||
129 | struct dentry *lower_dentry; | ||
130 | struct vfsmount *lower_mnt = | ||
131 | ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | ||
132 | |||
133 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
134 | /* Corresponding dput() and mntput() are done when the | ||
135 | * persistent file is fput() when the eCryptfs inode | ||
136 | * is destroyed. */ | ||
137 | dget(lower_dentry); | ||
138 | mntget(lower_mnt); | ||
139 | inode_info->lower_file = dentry_open(lower_dentry, | ||
140 | lower_mnt, | ||
141 | (O_RDWR | O_LARGEFILE)); | ||
142 | if (IS_ERR(inode_info->lower_file)) | ||
143 | inode_info->lower_file = dentry_open(lower_dentry, | ||
144 | lower_mnt, | ||
145 | (O_RDONLY | ||
146 | | O_LARGEFILE)); | ||
147 | if (IS_ERR(inode_info->lower_file)) { | ||
148 | printk(KERN_ERR "Error opening lower persistent file " | ||
149 | "for lower_dentry [0x%p] and lower_mnt [0x%p]\n", | ||
150 | lower_dentry, lower_mnt); | ||
151 | rc = PTR_ERR(inode_info->lower_file); | ||
152 | inode_info->lower_file = NULL; | ||
153 | } | ||
154 | } | ||
155 | mutex_unlock(&inode_info->lower_file_mutex); | ||
156 | return rc; | ||
157 | } | ||
158 | |||
159 | /** | ||
102 | * ecryptfs_interpose | 160 | * ecryptfs_interpose |
103 | * @lower_dentry: Existing dentry in the lower filesystem | 161 | * @lower_dentry: Existing dentry in the lower filesystem |
104 | * @dentry: ecryptfs' dentry | 162 | * @dentry: ecryptfs' dentry |
@@ -155,6 +213,13 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
155 | /* This size will be overwritten for real files w/ headers and | 213 | /* This size will be overwritten for real files w/ headers and |
156 | * other metadata */ | 214 | * other metadata */ |
157 | fsstack_copy_inode_size(inode, lower_inode); | 215 | fsstack_copy_inode_size(inode, lower_inode); |
216 | rc = ecryptfs_init_persistent_file(dentry); | ||
217 | if (rc) { | ||
218 | printk(KERN_ERR "%s: Error attempting to initialize the " | ||
219 | "persistent file for the dentry with name [%s]; " | ||
220 | "rc = [%d]\n", __FUNCTION__, dentry->d_name.name, rc); | ||
221 | goto out; | ||
222 | } | ||
158 | out: | 223 | out: |
159 | return rc; | 224 | return rc; |
160 | } | 225 | } |