diff options
| -rw-r--r-- | fs/ecryptfs/inode.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index a07441a0a878..65efe5fa687c 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: |
| @@ -265,7 +292,9 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | |||
| 265 | * that this on disk file is prepared to be an ecryptfs file */ | 292 | * that this on disk file is prepared to be an ecryptfs file */ |
| 266 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); | 293 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); |
| 267 | if (rc) { | 294 | if (rc) { |
| 268 | drop_nlink(ecryptfs_inode); | 295 | ecryptfs_do_unlink(directory_inode, ecryptfs_dentry, |
| 296 | ecryptfs_inode); | ||
| 297 | make_bad_inode(ecryptfs_inode); | ||
| 269 | unlock_new_inode(ecryptfs_inode); | 298 | unlock_new_inode(ecryptfs_inode); |
| 270 | iput(ecryptfs_inode); | 299 | iput(ecryptfs_inode); |
| 271 | goto out; | 300 | goto out; |
| @@ -477,27 +506,7 @@ out_lock: | |||
| 477 | 506 | ||
| 478 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | 507 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) |
| 479 | { | 508 | { |
| 480 | int rc = 0; | 509 | return ecryptfs_do_unlink(dir, dentry, dentry->d_inode); |
| 481 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 482 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
| 483 | struct dentry *lower_dir_dentry; | ||
| 484 | |||
| 485 | dget(lower_dentry); | ||
| 486 | lower_dir_dentry = lock_parent(lower_dentry); | ||
| 487 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
| 488 | if (rc) { | ||
| 489 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | ||
| 490 | goto out_unlock; | ||
| 491 | } | ||
| 492 | fsstack_copy_attr_times(dir, lower_dir_inode); | ||
| 493 | set_nlink(dentry->d_inode, | ||
| 494 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink); | ||
| 495 | dentry->d_inode->i_ctime = dir->i_ctime; | ||
| 496 | d_drop(dentry); | ||
| 497 | out_unlock: | ||
| 498 | unlock_dir(lower_dir_dentry); | ||
| 499 | dput(lower_dentry); | ||
| 500 | return rc; | ||
| 501 | } | 510 | } |
| 502 | 511 | ||
| 503 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | 512 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, |
