diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 136 |
1 files changed, 73 insertions, 63 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 7349ade17de..19b1f9035b0 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -69,6 +69,7 @@ static int ecryptfs_inode_set(struct inode *inode, void *opaque) | |||
69 | inode->i_ino = lower_inode->i_ino; | 69 | inode->i_ino = lower_inode->i_ino; |
70 | inode->i_version++; | 70 | inode->i_version++; |
71 | inode->i_mapping->a_ops = &ecryptfs_aops; | 71 | inode->i_mapping->a_ops = &ecryptfs_aops; |
72 | inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi; | ||
72 | 73 | ||
73 | if (S_ISLNK(inode->i_mode)) | 74 | if (S_ISLNK(inode->i_mode)) |
74 | inode->i_op = &ecryptfs_symlink_iops; | 75 | inode->i_op = &ecryptfs_symlink_iops; |
@@ -147,7 +148,6 @@ static int ecryptfs_interpose(struct dentry *lower_dentry, | |||
147 | * @lower_dir_inode: inode of the parent in the lower fs of the new file | 148 | * @lower_dir_inode: inode of the parent in the lower fs of the new file |
148 | * @dentry: New file's dentry | 149 | * @dentry: New file's dentry |
149 | * @mode: The mode of the new file | 150 | * @mode: The mode of the new file |
150 | * @nd: nameidata of ecryptfs' parent's dentry & vfsmount | ||
151 | * | 151 | * |
152 | * Creates the file in the lower file system. | 152 | * Creates the file in the lower file system. |
153 | * | 153 | * |
@@ -155,31 +155,10 @@ static int ecryptfs_interpose(struct dentry *lower_dentry, | |||
155 | */ | 155 | */ |
156 | static int | 156 | static int |
157 | ecryptfs_create_underlying_file(struct inode *lower_dir_inode, | 157 | ecryptfs_create_underlying_file(struct inode *lower_dir_inode, |
158 | struct dentry *dentry, int mode, | 158 | struct dentry *dentry, int mode) |
159 | struct nameidata *nd) | ||
160 | { | 159 | { |
161 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 160 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
162 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | 161 | return vfs_create(lower_dir_inode, lower_dentry, mode, NULL); |
163 | struct dentry *dentry_save; | ||
164 | struct vfsmount *vfsmount_save; | ||
165 | unsigned int flags_save; | ||
166 | int rc; | ||
167 | |||
168 | if (nd) { | ||
169 | dentry_save = nd->path.dentry; | ||
170 | vfsmount_save = nd->path.mnt; | ||
171 | flags_save = nd->flags; | ||
172 | nd->path.dentry = lower_dentry; | ||
173 | nd->path.mnt = lower_mnt; | ||
174 | nd->flags &= ~LOOKUP_OPEN; | ||
175 | } | ||
176 | rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); | ||
177 | if (nd) { | ||
178 | nd->path.dentry = dentry_save; | ||
179 | nd->path.mnt = vfsmount_save; | ||
180 | nd->flags = flags_save; | ||
181 | } | ||
182 | return rc; | ||
183 | } | 162 | } |
184 | 163 | ||
185 | /** | 164 | /** |
@@ -193,44 +172,43 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode, | |||
193 | * it. It will also update the eCryptfs directory inode to mimic the | 172 | * it. It will also update the eCryptfs directory inode to mimic the |
194 | * stat of the lower directory inode. | 173 | * stat of the lower directory inode. |
195 | * | 174 | * |
196 | * Returns zero on success; non-zero on error condition | 175 | * Returns the new eCryptfs inode on success; an ERR_PTR on error condition |
197 | */ | 176 | */ |
198 | static int | 177 | static struct inode * |
199 | ecryptfs_do_create(struct inode *directory_inode, | 178 | ecryptfs_do_create(struct inode *directory_inode, |
200 | struct dentry *ecryptfs_dentry, int mode, | 179 | struct dentry *ecryptfs_dentry, int mode) |
201 | struct nameidata *nd) | ||
202 | { | 180 | { |
203 | int rc; | 181 | int rc; |
204 | struct dentry *lower_dentry; | 182 | struct dentry *lower_dentry; |
205 | struct dentry *lower_dir_dentry; | 183 | struct dentry *lower_dir_dentry; |
184 | struct inode *inode; | ||
206 | 185 | ||
207 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 186 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
208 | lower_dir_dentry = lock_parent(lower_dentry); | 187 | lower_dir_dentry = lock_parent(lower_dentry); |
209 | if (IS_ERR(lower_dir_dentry)) { | 188 | if (IS_ERR(lower_dir_dentry)) { |
210 | ecryptfs_printk(KERN_ERR, "Error locking directory of " | 189 | ecryptfs_printk(KERN_ERR, "Error locking directory of " |
211 | "dentry\n"); | 190 | "dentry\n"); |
212 | rc = PTR_ERR(lower_dir_dentry); | 191 | inode = ERR_CAST(lower_dir_dentry); |
213 | goto out; | 192 | goto out; |
214 | } | 193 | } |
215 | rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, | 194 | rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, |
216 | ecryptfs_dentry, mode, nd); | 195 | ecryptfs_dentry, mode); |
217 | if (rc) { | 196 | if (rc) { |
218 | printk(KERN_ERR "%s: Failure to create dentry in lower fs; " | 197 | printk(KERN_ERR "%s: Failure to create dentry in lower fs; " |
219 | "rc = [%d]\n", __func__, rc); | 198 | "rc = [%d]\n", __func__, rc); |
199 | inode = ERR_PTR(rc); | ||
220 | goto out_lock; | 200 | goto out_lock; |
221 | } | 201 | } |
222 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | 202 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, |
223 | directory_inode->i_sb); | 203 | directory_inode->i_sb); |
224 | if (rc) { | 204 | if (IS_ERR(inode)) |
225 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); | ||
226 | goto out_lock; | 205 | goto out_lock; |
227 | } | ||
228 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); | 206 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); |
229 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); | 207 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); |
230 | out_lock: | 208 | out_lock: |
231 | unlock_dir(lower_dir_dentry); | 209 | unlock_dir(lower_dir_dentry); |
232 | out: | 210 | out: |
233 | return rc; | 211 | return inode; |
234 | } | 212 | } |
235 | 213 | ||
236 | /** | 214 | /** |
@@ -241,26 +219,26 @@ out: | |||
241 | * | 219 | * |
242 | * Returns zero on success | 220 | * Returns zero on success |
243 | */ | 221 | */ |
244 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | 222 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, |
223 | struct inode *ecryptfs_inode) | ||
245 | { | 224 | { |
246 | struct ecryptfs_crypt_stat *crypt_stat = | 225 | struct ecryptfs_crypt_stat *crypt_stat = |
247 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 226 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
248 | int rc = 0; | 227 | int rc = 0; |
249 | 228 | ||
250 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 229 | if (S_ISDIR(ecryptfs_inode->i_mode)) { |
251 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | 230 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); |
252 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 231 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
253 | goto out; | 232 | goto out; |
254 | } | 233 | } |
255 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); | 234 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); |
256 | rc = ecryptfs_new_file_context(ecryptfs_dentry); | 235 | rc = ecryptfs_new_file_context(ecryptfs_inode); |
257 | if (rc) { | 236 | if (rc) { |
258 | ecryptfs_printk(KERN_ERR, "Error creating new file " | 237 | ecryptfs_printk(KERN_ERR, "Error creating new file " |
259 | "context; rc = [%d]\n", rc); | 238 | "context; rc = [%d]\n", rc); |
260 | goto out; | 239 | goto out; |
261 | } | 240 | } |
262 | rc = ecryptfs_get_lower_file(ecryptfs_dentry, | 241 | rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode); |
263 | ecryptfs_dentry->d_inode); | ||
264 | if (rc) { | 242 | if (rc) { |
265 | printk(KERN_ERR "%s: Error attempting to initialize " | 243 | printk(KERN_ERR "%s: Error attempting to initialize " |
266 | "the lower file for the dentry with name " | 244 | "the lower file for the dentry with name " |
@@ -268,10 +246,10 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
268 | ecryptfs_dentry->d_name.name, rc); | 246 | ecryptfs_dentry->d_name.name, rc); |
269 | goto out; | 247 | goto out; |
270 | } | 248 | } |
271 | rc = ecryptfs_write_metadata(ecryptfs_dentry); | 249 | rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode); |
272 | if (rc) | 250 | if (rc) |
273 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); | 251 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
274 | ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | 252 | ecryptfs_put_lower_file(ecryptfs_inode); |
275 | out: | 253 | out: |
276 | return rc; | 254 | return rc; |
277 | } | 255 | } |
@@ -291,18 +269,28 @@ static int | |||
291 | ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | 269 | ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, |
292 | int mode, struct nameidata *nd) | 270 | int mode, struct nameidata *nd) |
293 | { | 271 | { |
272 | struct inode *ecryptfs_inode; | ||
294 | int rc; | 273 | int rc; |
295 | 274 | ||
296 | /* ecryptfs_do_create() calls ecryptfs_interpose() */ | 275 | ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry, |
297 | rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd); | 276 | mode); |
298 | if (unlikely(rc)) { | 277 | if (unlikely(IS_ERR(ecryptfs_inode))) { |
299 | ecryptfs_printk(KERN_WARNING, "Failed to create file in" | 278 | ecryptfs_printk(KERN_WARNING, "Failed to create file in" |
300 | "lower filesystem\n"); | 279 | "lower filesystem\n"); |
280 | rc = PTR_ERR(ecryptfs_inode); | ||
301 | goto out; | 281 | goto out; |
302 | } | 282 | } |
303 | /* At this point, a file exists on "disk"; we need to make sure | 283 | /* At this point, a file exists on "disk"; we need to make sure |
304 | * that this on disk file is prepared to be an ecryptfs file */ | 284 | * that this on disk file is prepared to be an ecryptfs file */ |
305 | rc = ecryptfs_initialize_file(ecryptfs_dentry); | 285 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); |
286 | if (rc) { | ||
287 | drop_nlink(ecryptfs_inode); | ||
288 | unlock_new_inode(ecryptfs_inode); | ||
289 | iput(ecryptfs_inode); | ||
290 | goto out; | ||
291 | } | ||
292 | d_instantiate(ecryptfs_dentry, ecryptfs_inode); | ||
293 | unlock_new_inode(ecryptfs_inode); | ||
306 | out: | 294 | out: |
307 | return rc; | 295 | return rc; |
308 | } | 296 | } |
@@ -853,18 +841,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
853 | size_t num_zeros = (PAGE_CACHE_SIZE | 841 | size_t num_zeros = (PAGE_CACHE_SIZE |
854 | - (ia->ia_size & ~PAGE_CACHE_MASK)); | 842 | - (ia->ia_size & ~PAGE_CACHE_MASK)); |
855 | 843 | ||
856 | |||
857 | /* | ||
858 | * XXX(truncate) this should really happen at the begginning | ||
859 | * of ->setattr. But the code is too messy to that as part | ||
860 | * of a larger patch. ecryptfs is also totally missing out | ||
861 | * on the inode_change_ok check at the beginning of | ||
862 | * ->setattr while would include this. | ||
863 | */ | ||
864 | rc = inode_newsize_ok(inode, ia->ia_size); | ||
865 | if (rc) | ||
866 | goto out; | ||
867 | |||
868 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 844 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
869 | truncate_setsize(inode, ia->ia_size); | 845 | truncate_setsize(inode, ia->ia_size); |
870 | lower_ia->ia_size = ia->ia_size; | 846 | lower_ia->ia_size = ia->ia_size; |
@@ -914,6 +890,28 @@ out: | |||
914 | return rc; | 890 | return rc; |
915 | } | 891 | } |
916 | 892 | ||
893 | static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset) | ||
894 | { | ||
895 | struct ecryptfs_crypt_stat *crypt_stat; | ||
896 | loff_t lower_oldsize, lower_newsize; | ||
897 | |||
898 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
899 | lower_oldsize = upper_size_to_lower_size(crypt_stat, | ||
900 | i_size_read(inode)); | ||
901 | lower_newsize = upper_size_to_lower_size(crypt_stat, offset); | ||
902 | if (lower_newsize > lower_oldsize) { | ||
903 | /* | ||
904 | * The eCryptfs inode and the new *lower* size are mixed here | ||
905 | * because we may not have the lower i_mutex held and/or it may | ||
906 | * not be appropriate to call inode_newsize_ok() with inodes | ||
907 | * from other filesystems. | ||
908 | */ | ||
909 | return inode_newsize_ok(inode, lower_newsize); | ||
910 | } | ||
911 | |||
912 | return 0; | ||
913 | } | ||
914 | |||
917 | /** | 915 | /** |
918 | * ecryptfs_truncate | 916 | * ecryptfs_truncate |
919 | * @dentry: The ecryptfs layer dentry | 917 | * @dentry: The ecryptfs layer dentry |
@@ -930,6 +928,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
930 | struct iattr lower_ia = { .ia_valid = 0 }; | 928 | struct iattr lower_ia = { .ia_valid = 0 }; |
931 | int rc; | 929 | int rc; |
932 | 930 | ||
931 | rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length); | ||
932 | if (rc) | ||
933 | return rc; | ||
934 | |||
933 | rc = truncate_upper(dentry, &ia, &lower_ia); | 935 | rc = truncate_upper(dentry, &ia, &lower_ia); |
934 | if (!rc && lower_ia.ia_valid & ATTR_SIZE) { | 936 | if (!rc && lower_ia.ia_valid & ATTR_SIZE) { |
935 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 937 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
@@ -942,10 +944,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
942 | } | 944 | } |
943 | 945 | ||
944 | static int | 946 | static int |
945 | ecryptfs_permission(struct inode *inode, int mask, unsigned int flags) | 947 | ecryptfs_permission(struct inode *inode, int mask) |
946 | { | 948 | { |
947 | if (flags & IPERM_FLAG_RCU) | ||
948 | return -ECHILD; | ||
949 | return inode_permission(ecryptfs_inode_to_lower(inode), mask); | 949 | return inode_permission(ecryptfs_inode_to_lower(inode), mask); |
950 | } | 950 | } |
951 | 951 | ||
@@ -1011,6 +1011,16 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
1011 | } | 1011 | } |
1012 | } | 1012 | } |
1013 | mutex_unlock(&crypt_stat->cs_mutex); | 1013 | mutex_unlock(&crypt_stat->cs_mutex); |
1014 | |||
1015 | rc = inode_change_ok(inode, ia); | ||
1016 | if (rc) | ||
1017 | goto out; | ||
1018 | if (ia->ia_valid & ATTR_SIZE) { | ||
1019 | rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size); | ||
1020 | if (rc) | ||
1021 | goto out; | ||
1022 | } | ||
1023 | |||
1014 | if (S_ISREG(inode->i_mode)) { | 1024 | if (S_ISREG(inode->i_mode)) { |
1015 | rc = filemap_write_and_wait(inode->i_mapping); | 1025 | rc = filemap_write_and_wait(inode->i_mapping); |
1016 | if (rc) | 1026 | if (rc) |