summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2015-04-23 10:09:19 -0700
committerBrian Behlendorf <[email protected]>2015-04-24 09:54:22 -0700
commita438ff0e85c36c2e31873b3a46d85e5e3593fab9 (patch)
tree62b1df1bd9e58e265cff5d510b4d26f07982aa0f
parent614e598c88446df9a6e2b59ba8ad0919628935b8 (diff)
Extend PF_FSTRANS critical regions
Additional testing has shown that the region covered by PF_FSTRANS needs to be extended to cover the zpl_xattr_security_init() and init_acl() functions. The zpl_mark_dirty() function can also recurse and therefore must always be protected. Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Signed-off-by: Richard Yao <[email protected]> Closes #3331
-rw-r--r--module/zfs/zpl_inode.c12
-rw-r--r--module/zfs/zpl_super.c8
2 files changed, 14 insertions, 6 deletions
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index fc6231b88..d72271459 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -106,13 +106,13 @@ 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);
- spl_fstrans_unmark(cookie);
if (error == 0) {
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
VERIFY0(zpl_init_acl(ip, dir));
d_instantiate(dentry, ip);
}
+ spl_fstrans_unmark(cookie);
kmem_free(vap, sizeof (vattr_t));
crfree(cr);
ASSERT3S(error, <=, 0);
@@ -144,13 +144,13 @@ 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);
- spl_fstrans_unmark(cookie);
if (error == 0) {
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
VERIFY0(zpl_init_acl(ip, dir));
d_instantiate(dentry, ip);
}
+ spl_fstrans_unmark(cookie);
kmem_free(vap, sizeof (vattr_t));
crfree(cr);
ASSERT3S(error, <=, 0);
@@ -190,13 +190,13 @@ 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);
- spl_fstrans_unmark(cookie);
if (error == 0) {
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
VERIFY0(zpl_init_acl(ip, dir));
d_instantiate(dentry, ip);
}
+ spl_fstrans_unmark(cookie);
kmem_free(vap, sizeof (vattr_t));
crfree(cr);
ASSERT3S(error, <=, 0);
@@ -273,10 +273,10 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
cookie = spl_fstrans_mark();
error = -zfs_setattr(ip, vap, 0, cr);
- spl_fstrans_unmark(cookie);
if (!error && (ia->ia_valid & ATTR_MODE))
error = zpl_chmod_acl(ip);
+ spl_fstrans_unmark(cookie);
kmem_free(vap, sizeof (vattr_t));
crfree(cr);
ASSERT3S(error, <=, 0);
@@ -317,12 +317,12 @@ 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);
- spl_fstrans_unmark(cookie);
if (error == 0) {
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
d_instantiate(dentry, ip);
}
+ spl_fstrans_unmark(cookie);
kmem_free(vap, sizeof (vattr_t));
crfree(cr);
ASSERT3S(error, <=, 0);
@@ -391,7 +391,6 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
cookie = spl_fstrans_mark();
error = -zfs_link(dir, ip, dname(dentry), cr);
- spl_fstrans_unmark(cookie);
if (error) {
iput(ip);
goto out;
@@ -399,6 +398,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
d_instantiate(dentry, ip);
out:
+ spl_fstrans_unmark(cookie);
crfree(cr);
ASSERT3S(error, <=, 0);
diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c
index 62fcc6cd8..a8d26ec1c 100644
--- a/module/zfs/zpl_super.c
+++ b/module/zfs/zpl_super.c
@@ -57,13 +57,21 @@ zpl_inode_destroy(struct inode *ip)
static void
zpl_dirty_inode(struct inode *ip, int flags)
{
+ fstrans_cookie_t cookie;
+
+ cookie = spl_fstrans_mark();
zfs_dirty_inode(ip, flags);
+ spl_fstrans_unmark(cookie);
}
#else
static void
zpl_dirty_inode(struct inode *ip)
{
+ fstrans_cookie_t cookie;
+
+ cookie = spl_fstrans_mark();
zfs_dirty_inode(ip, 0);
+ spl_fstrans_unmark(cookie);
}
#endif /* HAVE_DIRTY_INODE_WITH_FLAGS */