diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-02 13:56:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-02 13:56:34 -0400 |
commit | 410fc4ce8a373a3c35c73ac2c7c29f2bac6400bf (patch) | |
tree | 8a9e2e29f13a3ba93689f4afb951d64ffc10c9d5 /fs/ecryptfs/inode.c | |
parent | 630103ea2c286de3e7ea9ae6b1035d91ef051413 (diff) | |
parent | 5f5b331d5c21228a6519dcb793fc1629646c51a6 (diff) |
Merge tag 'ecryptfs-3.6-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs
Pull ecryptfs fixes from Tyler Hicks:
- Fixes a bug when the lower filesystem mount options include 'acl',
but the eCryptfs mount options do not
- Cleanups in the messaging code
- Better handling of empty files in the lower filesystem to improve
usability. Failed file creations are now cleaned up and empty lower
files are converted into eCryptfs during open().
- The write-through cache changes are being reverted due to bugs that
are not easy to fix. Stability outweighs the performance
enhancements here.
- Improvement to the mount code to catch unsupported ciphers specified
in the mount options
* tag 'ecryptfs-3.6-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs:
eCryptfs: check for eCryptfs cipher support at mount
eCryptfs: Revert to a writethrough cache model
eCryptfs: Initialize empty lower files when opening them
eCryptfs: Unlink lower inode when ecryptfs_create() fails
eCryptfs: Make all miscdev functions use daemon ptr in file private_data
eCryptfs: Remove unused messaging declarations and function
eCryptfs: Copy up POSIX ACL and read-only flags from lower mount
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 65 |
1 files changed, 34 insertions, 31 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c3ca12c33ca2..534b129ea676 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -143,6 +143,31 @@ static int ecryptfs_interpose(struct dentry *lower_dentry, | |||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, | ||
147 | struct inode *inode) | ||
148 | { | ||
149 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
150 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
151 | struct dentry *lower_dir_dentry; | ||
152 | int rc; | ||
153 | |||
154 | dget(lower_dentry); | ||
155 | lower_dir_dentry = lock_parent(lower_dentry); | ||
156 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
157 | if (rc) { | ||
158 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | ||
159 | goto out_unlock; | ||
160 | } | ||
161 | fsstack_copy_attr_times(dir, lower_dir_inode); | ||
162 | set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); | ||
163 | inode->i_ctime = dir->i_ctime; | ||
164 | d_drop(dentry); | ||
165 | out_unlock: | ||
166 | unlock_dir(lower_dir_dentry); | ||
167 | dput(lower_dentry); | ||
168 | return rc; | ||
169 | } | ||
170 | |||
146 | /** | 171 | /** |
147 | * ecryptfs_do_create | 172 | * ecryptfs_do_create |
148 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs | 173 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs |
@@ -182,8 +207,10 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
182 | } | 207 | } |
183 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, | 208 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, |
184 | directory_inode->i_sb); | 209 | directory_inode->i_sb); |
185 | if (IS_ERR(inode)) | 210 | if (IS_ERR(inode)) { |
211 | vfs_unlink(lower_dir_dentry->d_inode, lower_dentry); | ||
186 | goto out_lock; | 212 | goto out_lock; |
213 | } | ||
187 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); | 214 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); |
188 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); | 215 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); |
189 | out_lock: | 216 | out_lock: |
@@ -200,8 +227,8 @@ out: | |||
200 | * | 227 | * |
201 | * Returns zero on success | 228 | * Returns zero on success |
202 | */ | 229 | */ |
203 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | 230 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, |
204 | struct inode *ecryptfs_inode) | 231 | struct inode *ecryptfs_inode) |
205 | { | 232 | { |
206 | struct ecryptfs_crypt_stat *crypt_stat = | 233 | struct ecryptfs_crypt_stat *crypt_stat = |
207 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 234 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
@@ -264,7 +291,9 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | |||
264 | * that this on disk file is prepared to be an ecryptfs file */ | 291 | * that this on disk file is prepared to be an ecryptfs file */ |
265 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); | 292 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); |
266 | if (rc) { | 293 | if (rc) { |
267 | drop_nlink(ecryptfs_inode); | 294 | ecryptfs_do_unlink(directory_inode, ecryptfs_dentry, |
295 | ecryptfs_inode); | ||
296 | make_bad_inode(ecryptfs_inode); | ||
268 | unlock_new_inode(ecryptfs_inode); | 297 | unlock_new_inode(ecryptfs_inode); |
269 | iput(ecryptfs_inode); | 298 | iput(ecryptfs_inode); |
270 | goto out; | 299 | goto out; |
@@ -466,27 +495,7 @@ out_lock: | |||
466 | 495 | ||
467 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | 496 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) |
468 | { | 497 | { |
469 | int rc = 0; | 498 | return ecryptfs_do_unlink(dir, dentry, dentry->d_inode); |
470 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
471 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
472 | struct dentry *lower_dir_dentry; | ||
473 | |||
474 | dget(lower_dentry); | ||
475 | lower_dir_dentry = lock_parent(lower_dentry); | ||
476 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
477 | if (rc) { | ||
478 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | ||
479 | goto out_unlock; | ||
480 | } | ||
481 | fsstack_copy_attr_times(dir, lower_dir_inode); | ||
482 | set_nlink(dentry->d_inode, | ||
483 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink); | ||
484 | dentry->d_inode->i_ctime = dir->i_ctime; | ||
485 | d_drop(dentry); | ||
486 | out_unlock: | ||
487 | unlock_dir(lower_dir_dentry); | ||
488 | dput(lower_dentry); | ||
489 | return rc; | ||
490 | } | 499 | } |
491 | 500 | ||
492 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | 501 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, |
@@ -961,12 +970,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
961 | goto out; | 970 | goto out; |
962 | } | 971 | } |
963 | 972 | ||
964 | if (S_ISREG(inode->i_mode)) { | ||
965 | rc = filemap_write_and_wait(inode->i_mapping); | ||
966 | if (rc) | ||
967 | goto out; | ||
968 | fsstack_copy_attr_all(inode, lower_inode); | ||
969 | } | ||
970 | memcpy(&lower_ia, ia, sizeof(lower_ia)); | 973 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
971 | if (ia->ia_valid & ATTR_FILE) | 974 | if (ia->ia_valid & ATTR_FILE) |
972 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); | 975 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |