diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 194 |
1 files changed, 43 insertions, 151 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 64ff02330752..f99051b7adab 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -74,16 +74,20 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode, | |||
74 | unsigned int flags_save; | 74 | unsigned int flags_save; |
75 | int rc; | 75 | int rc; |
76 | 76 | ||
77 | dentry_save = nd->path.dentry; | 77 | if (nd) { |
78 | vfsmount_save = nd->path.mnt; | 78 | dentry_save = nd->path.dentry; |
79 | flags_save = nd->flags; | 79 | vfsmount_save = nd->path.mnt; |
80 | nd->path.dentry = lower_dentry; | 80 | flags_save = nd->flags; |
81 | nd->path.mnt = lower_mnt; | 81 | nd->path.dentry = lower_dentry; |
82 | nd->flags &= ~LOOKUP_OPEN; | 82 | nd->path.mnt = lower_mnt; |
83 | nd->flags &= ~LOOKUP_OPEN; | ||
84 | } | ||
83 | rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); | 85 | rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); |
84 | nd->path.dentry = dentry_save; | 86 | if (nd) { |
85 | nd->path.mnt = vfsmount_save; | 87 | nd->path.dentry = dentry_save; |
86 | nd->flags = flags_save; | 88 | nd->path.mnt = vfsmount_save; |
89 | nd->flags = flags_save; | ||
90 | } | ||
87 | return rc; | 91 | return rc; |
88 | } | 92 | } |
89 | 93 | ||
@@ -139,26 +143,6 @@ out: | |||
139 | } | 143 | } |
140 | 144 | ||
141 | /** | 145 | /** |
142 | * grow_file | ||
143 | * @ecryptfs_dentry: the eCryptfs dentry | ||
144 | * | ||
145 | * This is the code which will grow the file to its correct size. | ||
146 | */ | ||
147 | static int grow_file(struct dentry *ecryptfs_dentry) | ||
148 | { | ||
149 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | ||
150 | char zero_virt[] = { 0x00 }; | ||
151 | int rc = 0; | ||
152 | |||
153 | rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1); | ||
154 | i_size_write(ecryptfs_inode, 0); | ||
155 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | ||
156 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= | ||
157 | ECRYPTFS_NEW_FILE; | ||
158 | return rc; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * ecryptfs_initialize_file | 146 | * ecryptfs_initialize_file |
163 | * | 147 | * |
164 | * Cause the file to be changed from a basic empty file to an ecryptfs | 148 | * Cause the file to be changed from a basic empty file to an ecryptfs |
@@ -177,7 +161,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
177 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 161 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
178 | goto out; | 162 | goto out; |
179 | } | 163 | } |
180 | crypt_stat->flags |= ECRYPTFS_NEW_FILE; | ||
181 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); | 164 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); |
182 | rc = ecryptfs_new_file_context(ecryptfs_dentry); | 165 | rc = ecryptfs_new_file_context(ecryptfs_dentry); |
183 | if (rc) { | 166 | if (rc) { |
@@ -185,24 +168,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
185 | "context; rc = [%d]\n", rc); | 168 | "context; rc = [%d]\n", rc); |
186 | goto out; | 169 | goto out; |
187 | } | 170 | } |
188 | if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) { | 171 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); |
189 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 172 | if (rc) { |
190 | if (rc) { | 173 | printk(KERN_ERR "%s: Error attempting to initialize " |
191 | printk(KERN_ERR "%s: Error attempting to initialize " | 174 | "the persistent file for the dentry with name " |
192 | "the persistent file for the dentry with name " | 175 | "[%s]; rc = [%d]\n", __func__, |
193 | "[%s]; rc = [%d]\n", __func__, | 176 | ecryptfs_dentry->d_name.name, rc); |
194 | ecryptfs_dentry->d_name.name, rc); | 177 | goto out; |
195 | goto out; | ||
196 | } | ||
197 | } | 178 | } |
198 | rc = ecryptfs_write_metadata(ecryptfs_dentry); | 179 | rc = ecryptfs_write_metadata(ecryptfs_dentry); |
199 | if (rc) { | 180 | if (rc) { |
200 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); | 181 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
201 | goto out; | 182 | goto out; |
202 | } | 183 | } |
203 | rc = grow_file(ecryptfs_dentry); | ||
204 | if (rc) | ||
205 | printk(KERN_ERR "Error growing file; rc = [%d]\n", rc); | ||
206 | out: | 184 | out: |
207 | return rc; | 185 | return rc; |
208 | } | 186 | } |
@@ -243,8 +221,7 @@ out: | |||
243 | */ | 221 | */ |
244 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | 222 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, |
245 | struct dentry *lower_dentry, | 223 | struct dentry *lower_dentry, |
246 | struct inode *ecryptfs_dir_inode, | 224 | struct inode *ecryptfs_dir_inode) |
247 | struct nameidata *ecryptfs_nd) | ||
248 | { | 225 | { |
249 | struct dentry *lower_dir_dentry; | 226 | struct dentry *lower_dir_dentry; |
250 | struct vfsmount *lower_mnt; | 227 | struct vfsmount *lower_mnt; |
@@ -292,8 +269,6 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
292 | goto out; | 269 | goto out; |
293 | if (special_file(lower_inode->i_mode)) | 270 | if (special_file(lower_inode->i_mode)) |
294 | goto out; | 271 | goto out; |
295 | if (!ecryptfs_nd) | ||
296 | goto out; | ||
297 | /* Released in this function */ | 272 | /* Released in this function */ |
298 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER); | 273 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER); |
299 | if (!page_virt) { | 274 | if (!page_virt) { |
@@ -302,15 +277,13 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
302 | rc = -ENOMEM; | 277 | rc = -ENOMEM; |
303 | goto out; | 278 | goto out; |
304 | } | 279 | } |
305 | if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) { | 280 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); |
306 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 281 | if (rc) { |
307 | if (rc) { | 282 | printk(KERN_ERR "%s: Error attempting to initialize " |
308 | printk(KERN_ERR "%s: Error attempting to initialize " | 283 | "the persistent file for the dentry with name " |
309 | "the persistent file for the dentry with name " | 284 | "[%s]; rc = [%d]\n", __func__, |
310 | "[%s]; rc = [%d]\n", __func__, | 285 | ecryptfs_dentry->d_name.name, rc); |
311 | ecryptfs_dentry->d_name.name, rc); | 286 | goto out_free_kmem; |
312 | goto out_free_kmem; | ||
313 | } | ||
314 | } | 287 | } |
315 | crypt_stat = &ecryptfs_inode_to_private( | 288 | crypt_stat = &ecryptfs_inode_to_private( |
316 | ecryptfs_dentry->d_inode)->crypt_stat; | 289 | ecryptfs_dentry->d_inode)->crypt_stat; |
@@ -353,75 +326,6 @@ out: | |||
353 | } | 326 | } |
354 | 327 | ||
355 | /** | 328 | /** |
356 | * ecryptfs_new_lower_dentry | ||
357 | * @name: The name of the new dentry. | ||
358 | * @lower_dir_dentry: Parent directory of the new dentry. | ||
359 | * @nd: nameidata from last lookup. | ||
360 | * | ||
361 | * Create a new dentry or get it from lower parent dir. | ||
362 | */ | ||
363 | static struct dentry * | ||
364 | ecryptfs_new_lower_dentry(struct qstr *name, struct dentry *lower_dir_dentry, | ||
365 | struct nameidata *nd) | ||
366 | { | ||
367 | struct dentry *new_dentry; | ||
368 | struct dentry *tmp; | ||
369 | struct inode *lower_dir_inode; | ||
370 | |||
371 | lower_dir_inode = lower_dir_dentry->d_inode; | ||
372 | |||
373 | tmp = d_alloc(lower_dir_dentry, name); | ||
374 | if (!tmp) | ||
375 | return ERR_PTR(-ENOMEM); | ||
376 | |||
377 | mutex_lock(&lower_dir_inode->i_mutex); | ||
378 | new_dentry = lower_dir_inode->i_op->lookup(lower_dir_inode, tmp, nd); | ||
379 | mutex_unlock(&lower_dir_inode->i_mutex); | ||
380 | |||
381 | if (!new_dentry) | ||
382 | new_dentry = tmp; | ||
383 | else | ||
384 | dput(tmp); | ||
385 | |||
386 | return new_dentry; | ||
387 | } | ||
388 | |||
389 | |||
390 | /** | ||
391 | * ecryptfs_lookup_one_lower | ||
392 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | ||
393 | * @lower_dir_dentry: lower parent directory | ||
394 | * @name: lower file name | ||
395 | * | ||
396 | * Get the lower dentry from vfs. If lower dentry does not exist yet, | ||
397 | * create it. | ||
398 | */ | ||
399 | static struct dentry * | ||
400 | ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, | ||
401 | struct dentry *lower_dir_dentry, struct qstr *name) | ||
402 | { | ||
403 | struct nameidata nd; | ||
404 | struct vfsmount *lower_mnt; | ||
405 | int err; | ||
406 | |||
407 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | ||
408 | ecryptfs_dentry->d_parent)); | ||
409 | err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); | ||
410 | mntput(lower_mnt); | ||
411 | |||
412 | if (!err) { | ||
413 | /* we dont need the mount */ | ||
414 | mntput(nd.path.mnt); | ||
415 | return nd.path.dentry; | ||
416 | } | ||
417 | if (err != -ENOENT) | ||
418 | return ERR_PTR(err); | ||
419 | |||
420 | /* create a new lower dentry */ | ||
421 | return ecryptfs_new_lower_dentry(name, lower_dir_dentry, &nd); | ||
422 | } | ||
423 | |||
424 | /** | ||
425 | * ecryptfs_lookup | 329 | * ecryptfs_lookup |
426 | * @ecryptfs_dir_inode: The eCryptfs directory inode | 330 | * @ecryptfs_dir_inode: The eCryptfs directory inode |
427 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | 331 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up |
@@ -438,7 +342,6 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
438 | size_t encrypted_and_encoded_name_size; | 342 | size_t encrypted_and_encoded_name_size; |
439 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; | 343 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
440 | struct dentry *lower_dir_dentry, *lower_dentry; | 344 | struct dentry *lower_dir_dentry, *lower_dentry; |
441 | struct qstr lower_name; | ||
442 | int rc = 0; | 345 | int rc = 0; |
443 | 346 | ||
444 | if ((ecryptfs_dentry->d_name.len == 1 | 347 | if ((ecryptfs_dentry->d_name.len == 1 |
@@ -448,20 +351,14 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
448 | goto out_d_drop; | 351 | goto out_d_drop; |
449 | } | 352 | } |
450 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | 353 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
451 | lower_name.name = ecryptfs_dentry->d_name.name; | 354 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); |
452 | lower_name.len = ecryptfs_dentry->d_name.len; | 355 | lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, |
453 | lower_name.hash = ecryptfs_dentry->d_name.hash; | 356 | lower_dir_dentry, |
454 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | 357 | ecryptfs_dentry->d_name.len); |
455 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | 358 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
456 | lower_dir_dentry->d_inode, &lower_name); | ||
457 | if (rc < 0) | ||
458 | goto out_d_drop; | ||
459 | } | ||
460 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, | ||
461 | lower_dir_dentry, &lower_name); | ||
462 | if (IS_ERR(lower_dentry)) { | 359 | if (IS_ERR(lower_dentry)) { |
463 | rc = PTR_ERR(lower_dentry); | 360 | rc = PTR_ERR(lower_dentry); |
464 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " | 361 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
465 | "[%d] on lower_dentry = [%s]\n", __func__, rc, | 362 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
466 | encrypted_and_encoded_name); | 363 | encrypted_and_encoded_name); |
467 | goto out_d_drop; | 364 | goto out_d_drop; |
@@ -483,28 +380,21 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
483 | "filename; rc = [%d]\n", __func__, rc); | 380 | "filename; rc = [%d]\n", __func__, rc); |
484 | goto out_d_drop; | 381 | goto out_d_drop; |
485 | } | 382 | } |
486 | lower_name.name = encrypted_and_encoded_name; | 383 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); |
487 | lower_name.len = encrypted_and_encoded_name_size; | 384 | lower_dentry = lookup_one_len(encrypted_and_encoded_name, |
488 | lower_name.hash = full_name_hash(lower_name.name, lower_name.len); | 385 | lower_dir_dentry, |
489 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | 386 | encrypted_and_encoded_name_size); |
490 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | 387 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
491 | lower_dir_dentry->d_inode, &lower_name); | ||
492 | if (rc < 0) | ||
493 | goto out_d_drop; | ||
494 | } | ||
495 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, | ||
496 | lower_dir_dentry, &lower_name); | ||
497 | if (IS_ERR(lower_dentry)) { | 388 | if (IS_ERR(lower_dentry)) { |
498 | rc = PTR_ERR(lower_dentry); | 389 | rc = PTR_ERR(lower_dentry); |
499 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " | 390 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
500 | "[%d] on lower_dentry = [%s]\n", __func__, rc, | 391 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
501 | encrypted_and_encoded_name); | 392 | encrypted_and_encoded_name); |
502 | goto out_d_drop; | 393 | goto out_d_drop; |
503 | } | 394 | } |
504 | lookup_and_interpose: | 395 | lookup_and_interpose: |
505 | rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, | 396 | rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, |
506 | ecryptfs_dir_inode, | 397 | ecryptfs_dir_inode); |
507 | ecryptfs_nd); | ||
508 | goto out; | 398 | goto out; |
509 | out_d_drop: | 399 | out_d_drop: |
510 | d_drop(ecryptfs_dentry); | 400 | d_drop(ecryptfs_dentry); |
@@ -1096,6 +986,8 @@ int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1096 | rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry), | 986 | rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry), |
1097 | ecryptfs_dentry_to_lower(dentry), &lower_stat); | 987 | ecryptfs_dentry_to_lower(dentry), &lower_stat); |
1098 | if (!rc) { | 988 | if (!rc) { |
989 | fsstack_copy_attr_all(dentry->d_inode, | ||
990 | ecryptfs_inode_to_lower(dentry->d_inode)); | ||
1099 | generic_fillattr(dentry->d_inode, stat); | 991 | generic_fillattr(dentry->d_inode, stat); |
1100 | stat->blocks = lower_stat.blocks; | 992 | stat->blocks = lower_stat.blocks; |
1101 | } | 993 | } |