aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ecryptfs/inode.c55
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
146static 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);
165out_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);
189out_lock: 216out_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
478static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) 507static 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);
497out_unlock:
498 unlock_dir(lower_dir_dentry);
499 dput(lower_dentry);
500 return rc;
501} 510}
502 511
503static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, 512static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,