aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/zpl_inode.c
diff options
context:
space:
mode:
authorDavid Lamparter <[email protected]>2014-07-02 23:47:02 +0200
committerBrian Behlendorf <[email protected]>2015-05-11 14:35:14 -0700
commit214806c7e9833fb525a78a335b56fff5e863942e (patch)
tree5f948c782ad667ae0107dfb0fc20f209ab05867f /module/zfs/zpl_inode.c
parent76d520675e8ba0f7760fb5eefe2492fabf7a2335 (diff)
Safely handle security / ACL failures
The security and ACL operations should all be performed atomically. To accomplish this there would need to significant invasive changes made to the common code base. For the moment it's desirable for compatibility reasons to avoid this. Therefore the code has been updated to attempt to unwind the operation in case of failure rather than panic. Signed-off-by: Brian Behlendorf <[email protected]> Closes #2445
Diffstat (limited to 'module/zfs/zpl_inode.c')
-rw-r--r--module/zfs/zpl_inode.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index d72271459..31251e730 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -107,9 +107,14 @@ zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
cookie = spl_fstrans_mark();
error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
if (error == 0) {
- VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
- VERIFY0(zpl_init_acl(ip, dir));
d_instantiate(dentry, ip);
+
+ error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+ if (error == 0)
+ error = zpl_init_acl(ip, dir);
+
+ if (error)
+ (void) zfs_remove(dir, dname(dentry), cr);
}
spl_fstrans_unmark(cookie);
@@ -145,9 +150,14 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
cookie = spl_fstrans_mark();
error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
if (error == 0) {
- VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
- VERIFY0(zpl_init_acl(ip, dir));
d_instantiate(dentry, ip);
+
+ error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+ if (error == 0)
+ error = zpl_init_acl(ip, dir);
+
+ if (error)
+ (void) zfs_remove(dir, dname(dentry), cr);
}
spl_fstrans_unmark(cookie);
@@ -191,9 +201,14 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode)
cookie = spl_fstrans_mark();
error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
if (error == 0) {
- VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
- VERIFY0(zpl_init_acl(ip, dir));
d_instantiate(dentry, ip);
+
+ error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+ if (error == 0)
+ error = zpl_init_acl(ip, dir);
+
+ if (error)
+ (void) zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
}
spl_fstrans_unmark(cookie);
@@ -318,8 +333,11 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
cookie = spl_fstrans_mark();
error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
if (error == 0) {
- VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
d_instantiate(dentry, ip);
+
+ error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
+ if (error)
+ (void) zfs_remove(dir, dname(dentry), cr);
}
spl_fstrans_unmark(cookie);