diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:34:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:34:18 -0500 |
commit | 9bc9ccd7db1c9f043f75380b5a5b94912046a60e (patch) | |
tree | dd0a1b3396ae9414f668b0110cc39d11268ad3ed /fs/ecryptfs | |
parent | f0230294271f511b41797305b685365a9e569a09 (diff) | |
parent | bdd3536618443809d18868563eeafa63b9d29603 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"All kinds of stuff this time around; some more notable parts:
- RCU'd vfsmounts handling
- new primitives for coredump handling
- files_lock is gone
- Bruce's delegations handling series
- exportfs fixes
plus misc stuff all over the place"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (101 commits)
ecryptfs: ->f_op is never NULL
locks: break delegations on any attribute modification
locks: break delegations on link
locks: break delegations on rename
locks: helper functions for delegation breaking
locks: break delegations on unlink
namei: minor vfs_unlink cleanup
locks: implement delegations
locks: introduce new FL_DELEG lock flag
vfs: take i_mutex on renamed file
vfs: rename I_MUTEX_QUOTA now that it's not used for quotas
vfs: don't use PARENT/CHILD lock classes for non-directories
vfs: pull ext4's double-i_mutex-locking into common code
exportfs: fix quadratic behavior in filehandle lookup
exportfs: better variable name
exportfs: move most of reconnect_path to helper function
exportfs: eliminate unused "noprogress" counter
exportfs: stop retrying once we race with rename/remove
exportfs: clear DISCONNECTED on all parents sooner
exportfs: more detailed comment for path_reconnect
...
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/dentry.c | 29 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 19 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 8 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 29 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 3 |
5 files changed, 34 insertions, 54 deletions
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index bf12ba5dd223..4000f6b3a750 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
@@ -44,15 +44,15 @@ | |||
44 | */ | 44 | */ |
45 | static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) | 45 | static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) |
46 | { | 46 | { |
47 | struct dentry *lower_dentry; | 47 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
48 | int rc = 1; | 48 | int rc; |
49 | |||
50 | if (!(lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) | ||
51 | return 1; | ||
49 | 52 | ||
50 | if (flags & LOOKUP_RCU) | 53 | if (flags & LOOKUP_RCU) |
51 | return -ECHILD; | 54 | return -ECHILD; |
52 | 55 | ||
53 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
54 | if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) | ||
55 | goto out; | ||
56 | rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); | 56 | rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); |
57 | if (dentry->d_inode) { | 57 | if (dentry->d_inode) { |
58 | struct inode *lower_inode = | 58 | struct inode *lower_inode = |
@@ -60,12 +60,17 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
60 | 60 | ||
61 | fsstack_copy_attr_all(dentry->d_inode, lower_inode); | 61 | fsstack_copy_attr_all(dentry->d_inode, lower_inode); |
62 | } | 62 | } |
63 | out: | ||
64 | return rc; | 63 | return rc; |
65 | } | 64 | } |
66 | 65 | ||
67 | struct kmem_cache *ecryptfs_dentry_info_cache; | 66 | struct kmem_cache *ecryptfs_dentry_info_cache; |
68 | 67 | ||
68 | static void ecryptfs_dentry_free_rcu(struct rcu_head *head) | ||
69 | { | ||
70 | kmem_cache_free(ecryptfs_dentry_info_cache, | ||
71 | container_of(head, struct ecryptfs_dentry_info, rcu)); | ||
72 | } | ||
73 | |||
69 | /** | 74 | /** |
70 | * ecryptfs_d_release | 75 | * ecryptfs_d_release |
71 | * @dentry: The ecryptfs dentry | 76 | * @dentry: The ecryptfs dentry |
@@ -74,15 +79,11 @@ struct kmem_cache *ecryptfs_dentry_info_cache; | |||
74 | */ | 79 | */ |
75 | static void ecryptfs_d_release(struct dentry *dentry) | 80 | static void ecryptfs_d_release(struct dentry *dentry) |
76 | { | 81 | { |
77 | if (ecryptfs_dentry_to_private(dentry)) { | 82 | struct ecryptfs_dentry_info *p = dentry->d_fsdata; |
78 | if (ecryptfs_dentry_to_lower(dentry)) { | 83 | if (p) { |
79 | dput(ecryptfs_dentry_to_lower(dentry)); | 84 | path_put(&p->lower_path); |
80 | mntput(ecryptfs_dentry_to_lower_mnt(dentry)); | 85 | call_rcu(&p->rcu, ecryptfs_dentry_free_rcu); |
81 | } | ||
82 | kmem_cache_free(ecryptfs_dentry_info_cache, | ||
83 | ecryptfs_dentry_to_private(dentry)); | ||
84 | } | 86 | } |
85 | return; | ||
86 | } | 87 | } |
87 | 88 | ||
88 | const struct dentry_operations ecryptfs_dops = { | 89 | const struct dentry_operations ecryptfs_dops = { |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index df19d34a033b..90d1882b306f 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -261,7 +261,10 @@ struct ecryptfs_inode_info { | |||
261 | * vfsmount too. */ | 261 | * vfsmount too. */ |
262 | struct ecryptfs_dentry_info { | 262 | struct ecryptfs_dentry_info { |
263 | struct path lower_path; | 263 | struct path lower_path; |
264 | struct ecryptfs_crypt_stat *crypt_stat; | 264 | union { |
265 | struct ecryptfs_crypt_stat *crypt_stat; | ||
266 | struct rcu_head rcu; | ||
267 | }; | ||
265 | }; | 268 | }; |
266 | 269 | ||
267 | /** | 270 | /** |
@@ -512,13 +515,6 @@ ecryptfs_dentry_to_lower(struct dentry *dentry) | |||
512 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry; | 515 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry; |
513 | } | 516 | } |
514 | 517 | ||
515 | static inline void | ||
516 | ecryptfs_set_dentry_lower(struct dentry *dentry, struct dentry *lower_dentry) | ||
517 | { | ||
518 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry = | ||
519 | lower_dentry; | ||
520 | } | ||
521 | |||
522 | static inline struct vfsmount * | 518 | static inline struct vfsmount * |
523 | ecryptfs_dentry_to_lower_mnt(struct dentry *dentry) | 519 | ecryptfs_dentry_to_lower_mnt(struct dentry *dentry) |
524 | { | 520 | { |
@@ -531,13 +527,6 @@ ecryptfs_dentry_to_lower_path(struct dentry *dentry) | |||
531 | return &((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path; | 527 | return &((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path; |
532 | } | 528 | } |
533 | 529 | ||
534 | static inline void | ||
535 | ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt) | ||
536 | { | ||
537 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.mnt = | ||
538 | lower_mnt; | ||
539 | } | ||
540 | |||
541 | #define ecryptfs_printk(type, fmt, arg...) \ | 530 | #define ecryptfs_printk(type, fmt, arg...) \ |
542 | __ecryptfs_printk(type "%s: " fmt, __func__, ## arg); | 531 | __ecryptfs_printk(type "%s: " fmt, __func__, ## arg); |
543 | __printf(1, 2) | 532 | __printf(1, 2) |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 992cf95830b5..2229a74aeeed 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -271,7 +271,7 @@ static int ecryptfs_flush(struct file *file, fl_owner_t td) | |||
271 | { | 271 | { |
272 | struct file *lower_file = ecryptfs_file_to_lower(file); | 272 | struct file *lower_file = ecryptfs_file_to_lower(file); |
273 | 273 | ||
274 | if (lower_file->f_op && lower_file->f_op->flush) { | 274 | if (lower_file->f_op->flush) { |
275 | filemap_write_and_wait(file->f_mapping); | 275 | filemap_write_and_wait(file->f_mapping); |
276 | return lower_file->f_op->flush(lower_file, td); | 276 | return lower_file->f_op->flush(lower_file, td); |
277 | } | 277 | } |
@@ -305,7 +305,7 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag) | |||
305 | struct file *lower_file = NULL; | 305 | struct file *lower_file = NULL; |
306 | 306 | ||
307 | lower_file = ecryptfs_file_to_lower(file); | 307 | lower_file = ecryptfs_file_to_lower(file); |
308 | if (lower_file->f_op && lower_file->f_op->fasync) | 308 | if (lower_file->f_op->fasync) |
309 | rc = lower_file->f_op->fasync(fd, lower_file, flag); | 309 | rc = lower_file->f_op->fasync(fd, lower_file, flag); |
310 | return rc; | 310 | return rc; |
311 | } | 311 | } |
@@ -318,7 +318,7 @@ ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
318 | 318 | ||
319 | if (ecryptfs_file_to_private(file)) | 319 | if (ecryptfs_file_to_private(file)) |
320 | lower_file = ecryptfs_file_to_lower(file); | 320 | lower_file = ecryptfs_file_to_lower(file); |
321 | if (lower_file && lower_file->f_op && lower_file->f_op->unlocked_ioctl) | 321 | if (lower_file->f_op->unlocked_ioctl) |
322 | rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); | 322 | rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); |
323 | return rc; | 323 | return rc; |
324 | } | 324 | } |
@@ -332,7 +332,7 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
332 | 332 | ||
333 | if (ecryptfs_file_to_private(file)) | 333 | if (ecryptfs_file_to_private(file)) |
334 | lower_file = ecryptfs_file_to_lower(file); | 334 | lower_file = ecryptfs_file_to_lower(file); |
335 | if (lower_file && lower_file->f_op && lower_file->f_op->compat_ioctl) | 335 | if (lower_file->f_op && lower_file->f_op->compat_ioctl) |
336 | rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); | 336 | rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); |
337 | return rc; | 337 | return rc; |
338 | } | 338 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 67e9b6339691..c36c44824471 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -153,7 +153,7 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, | |||
153 | 153 | ||
154 | dget(lower_dentry); | 154 | dget(lower_dentry); |
155 | lower_dir_dentry = lock_parent(lower_dentry); | 155 | lower_dir_dentry = lock_parent(lower_dentry); |
156 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | 156 | rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL); |
157 | if (rc) { | 157 | if (rc) { |
158 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | 158 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); |
159 | goto out_unlock; | 159 | goto out_unlock; |
@@ -208,7 +208,7 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
208 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, | 208 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, |
209 | directory_inode->i_sb); | 209 | directory_inode->i_sb); |
210 | if (IS_ERR(inode)) { | 210 | if (IS_ERR(inode)) { |
211 | vfs_unlink(lower_dir_dentry->d_inode, lower_dentry); | 211 | vfs_unlink(lower_dir_dentry->d_inode, lower_dentry, NULL); |
212 | goto out_lock; | 212 | goto out_lock; |
213 | } | 213 | } |
214 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); | 214 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); |
@@ -361,8 +361,8 @@ static int ecryptfs_lookup_interpose(struct dentry *dentry, | |||
361 | BUG_ON(!d_count(lower_dentry)); | 361 | BUG_ON(!d_count(lower_dentry)); |
362 | 362 | ||
363 | ecryptfs_set_dentry_private(dentry, dentry_info); | 363 | ecryptfs_set_dentry_private(dentry, dentry_info); |
364 | ecryptfs_set_dentry_lower(dentry, lower_dentry); | 364 | dentry_info->lower_path.mnt = lower_mnt; |
365 | ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt); | 365 | dentry_info->lower_path.dentry = lower_dentry; |
366 | 366 | ||
367 | if (!lower_dentry->d_inode) { | 367 | if (!lower_dentry->d_inode) { |
368 | /* We want to add because we couldn't find in lower */ | 368 | /* We want to add because we couldn't find in lower */ |
@@ -475,7 +475,7 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | |||
475 | dget(lower_new_dentry); | 475 | dget(lower_new_dentry); |
476 | lower_dir_dentry = lock_parent(lower_new_dentry); | 476 | lower_dir_dentry = lock_parent(lower_new_dentry); |
477 | rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, | 477 | rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, |
478 | lower_new_dentry); | 478 | lower_new_dentry, NULL); |
479 | if (rc || !lower_new_dentry->d_inode) | 479 | if (rc || !lower_new_dentry->d_inode) |
480 | goto out_lock; | 480 | goto out_lock; |
481 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); | 481 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); |
@@ -640,7 +640,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
640 | goto out_lock; | 640 | goto out_lock; |
641 | } | 641 | } |
642 | rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, | 642 | rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, |
643 | lower_new_dir_dentry->d_inode, lower_new_dentry); | 643 | lower_new_dir_dentry->d_inode, lower_new_dentry, |
644 | NULL); | ||
644 | if (rc) | 645 | if (rc) |
645 | goto out_lock; | 646 | goto out_lock; |
646 | if (target_inode) | 647 | if (target_inode) |
@@ -703,16 +704,6 @@ out: | |||
703 | return NULL; | 704 | return NULL; |
704 | } | 705 | } |
705 | 706 | ||
706 | static void | ||
707 | ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) | ||
708 | { | ||
709 | char *buf = nd_get_link(nd); | ||
710 | if (!IS_ERR(buf)) { | ||
711 | /* Free the char* */ | ||
712 | kfree(buf); | ||
713 | } | ||
714 | } | ||
715 | |||
716 | /** | 707 | /** |
717 | * upper_size_to_lower_size | 708 | * upper_size_to_lower_size |
718 | * @crypt_stat: Crypt_stat associated with file | 709 | * @crypt_stat: Crypt_stat associated with file |
@@ -891,7 +882,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
891 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 882 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
892 | 883 | ||
893 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 884 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
894 | rc = notify_change(lower_dentry, &lower_ia); | 885 | rc = notify_change(lower_dentry, &lower_ia, NULL); |
895 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | 886 | mutex_unlock(&lower_dentry->d_inode->i_mutex); |
896 | } | 887 | } |
897 | return rc; | 888 | return rc; |
@@ -992,7 +983,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
992 | lower_ia.ia_valid &= ~ATTR_MODE; | 983 | lower_ia.ia_valid &= ~ATTR_MODE; |
993 | 984 | ||
994 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 985 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
995 | rc = notify_change(lower_dentry, &lower_ia); | 986 | rc = notify_change(lower_dentry, &lower_ia, NULL); |
996 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | 987 | mutex_unlock(&lower_dentry->d_inode->i_mutex); |
997 | out: | 988 | out: |
998 | fsstack_copy_attr_all(inode, lower_inode); | 989 | fsstack_copy_attr_all(inode, lower_inode); |
@@ -1121,7 +1112,7 @@ out: | |||
1121 | const struct inode_operations ecryptfs_symlink_iops = { | 1112 | const struct inode_operations ecryptfs_symlink_iops = { |
1122 | .readlink = generic_readlink, | 1113 | .readlink = generic_readlink, |
1123 | .follow_link = ecryptfs_follow_link, | 1114 | .follow_link = ecryptfs_follow_link, |
1124 | .put_link = ecryptfs_put_link, | 1115 | .put_link = kfree_put_link, |
1125 | .permission = ecryptfs_permission, | 1116 | .permission = ecryptfs_permission, |
1126 | .setattr = ecryptfs_setattr, | 1117 | .setattr = ecryptfs_setattr, |
1127 | .getattr = ecryptfs_getattr_link, | 1118 | .getattr = ecryptfs_getattr_link, |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index eb1c5979ecaf..1b119d3bf924 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -585,8 +585,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
585 | 585 | ||
586 | /* ->kill_sb() will take care of root_info */ | 586 | /* ->kill_sb() will take care of root_info */ |
587 | ecryptfs_set_dentry_private(s->s_root, root_info); | 587 | ecryptfs_set_dentry_private(s->s_root, root_info); |
588 | ecryptfs_set_dentry_lower(s->s_root, path.dentry); | 588 | root_info->lower_path = path; |
589 | ecryptfs_set_dentry_lower_mnt(s->s_root, path.mnt); | ||
590 | 589 | ||
591 | s->s_flags |= MS_ACTIVE; | 590 | s->s_flags |= MS_ACTIVE; |
592 | return dget(s->s_root); | 591 | return dget(s->s_root); |