diff options
author | Joel Becker <joel.becker@oracle.com> | 2010-05-10 14:56:52 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-05-10 14:56:52 -0400 |
commit | 547ba7c8efe43c2cabb38782e23572a6179dd1c1 (patch) | |
tree | 66343f838e25938a0c41662716d6eca6eaf6d5cb /fs/ocfs2/namei.c | |
parent | e4b963f10e9026c83419b5c25b93a0350413cf16 (diff) |
ocfs2: Block signals for mkdir/link/symlink/O_CREAT.
Once file or link creation gets going, it can't be interrupted by a
signal. They're not idempotent.
This blocks signals in ocfs2_mknod(), ocfs2_link(), and ocfs2_symlink()
once we start actually changing things. ocfs2_mknod() covers mknod(),
creat(), mkdir(), and open(O_CREAT).
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 21d4a33d0f0e..607084b349d4 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -239,6 +239,8 @@ static int ocfs2_mknod(struct inode *dir, | |||
239 | }; | 239 | }; |
240 | int did_quota_inode = 0; | 240 | int did_quota_inode = 0; |
241 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 241 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
242 | sigset_t oldset; | ||
243 | int did_block_signals = 0; | ||
242 | 244 | ||
243 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, | 245 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, |
244 | (unsigned long)dev, dentry->d_name.len, | 246 | (unsigned long)dev, dentry->d_name.len, |
@@ -350,6 +352,10 @@ static int ocfs2_mknod(struct inode *dir, | |||
350 | goto leave; | 352 | goto leave; |
351 | } | 353 | } |
352 | 354 | ||
355 | /* Starting to change things, restart is no longer possible. */ | ||
356 | ocfs2_block_signals(&oldset); | ||
357 | did_block_signals = 1; | ||
358 | |||
353 | status = dquot_alloc_inode(inode); | 359 | status = dquot_alloc_inode(inode); |
354 | if (status) | 360 | if (status) |
355 | goto leave; | 361 | goto leave; |
@@ -430,6 +436,8 @@ leave: | |||
430 | ocfs2_commit_trans(osb, handle); | 436 | ocfs2_commit_trans(osb, handle); |
431 | 437 | ||
432 | ocfs2_inode_unlock(dir, 1); | 438 | ocfs2_inode_unlock(dir, 1); |
439 | if (did_block_signals) | ||
440 | ocfs2_unblock_signals(&oldset); | ||
433 | 441 | ||
434 | if (status == -ENOSPC) | 442 | if (status == -ENOSPC) |
435 | mlog(0, "Disk is full\n"); | 443 | mlog(0, "Disk is full\n"); |
@@ -618,6 +626,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
618 | struct ocfs2_dinode *fe = NULL; | 626 | struct ocfs2_dinode *fe = NULL; |
619 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 627 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
620 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 628 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
629 | sigset_t oldset; | ||
621 | 630 | ||
622 | mlog_entry("(inode=%lu, old='%.*s' new='%.*s')\n", inode->i_ino, | 631 | mlog_entry("(inode=%lu, old='%.*s' new='%.*s')\n", inode->i_ino, |
623 | old_dentry->d_name.len, old_dentry->d_name.name, | 632 | old_dentry->d_name.len, old_dentry->d_name.name, |
@@ -674,6 +683,9 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
674 | goto out_unlock_inode; | 683 | goto out_unlock_inode; |
675 | } | 684 | } |
676 | 685 | ||
686 | /* Starting to change things, restart is no longer possible. */ | ||
687 | ocfs2_block_signals(&oldset); | ||
688 | |||
677 | err = ocfs2_journal_access_di(handle, INODE_CACHE(inode), fe_bh, | 689 | err = ocfs2_journal_access_di(handle, INODE_CACHE(inode), fe_bh, |
678 | OCFS2_JOURNAL_ACCESS_WRITE); | 690 | OCFS2_JOURNAL_ACCESS_WRITE); |
679 | if (err < 0) { | 691 | if (err < 0) { |
@@ -710,6 +722,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
710 | 722 | ||
711 | out_commit: | 723 | out_commit: |
712 | ocfs2_commit_trans(osb, handle); | 724 | ocfs2_commit_trans(osb, handle); |
725 | ocfs2_unblock_signals(&oldset); | ||
713 | out_unlock_inode: | 726 | out_unlock_inode: |
714 | ocfs2_inode_unlock(inode, 1); | 727 | ocfs2_inode_unlock(inode, 1); |
715 | 728 | ||
@@ -1568,6 +1581,8 @@ static int ocfs2_symlink(struct inode *dir, | |||
1568 | }; | 1581 | }; |
1569 | int did_quota = 0, did_quota_inode = 0; | 1582 | int did_quota = 0, did_quota_inode = 0; |
1570 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 1583 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
1584 | sigset_t oldset; | ||
1585 | int did_block_signals = 0; | ||
1571 | 1586 | ||
1572 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, | 1587 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, |
1573 | dentry, symname, dentry->d_name.len, dentry->d_name.name); | 1588 | dentry, symname, dentry->d_name.len, dentry->d_name.name); |
@@ -1663,6 +1678,10 @@ static int ocfs2_symlink(struct inode *dir, | |||
1663 | goto bail; | 1678 | goto bail; |
1664 | } | 1679 | } |
1665 | 1680 | ||
1681 | /* Starting to change things, restart is no longer possible. */ | ||
1682 | ocfs2_block_signals(&oldset); | ||
1683 | did_block_signals = 1; | ||
1684 | |||
1666 | status = dquot_alloc_inode(inode); | 1685 | status = dquot_alloc_inode(inode); |
1667 | if (status) | 1686 | if (status) |
1668 | goto bail; | 1687 | goto bail; |
@@ -1766,6 +1785,8 @@ bail: | |||
1766 | ocfs2_commit_trans(osb, handle); | 1785 | ocfs2_commit_trans(osb, handle); |
1767 | 1786 | ||
1768 | ocfs2_inode_unlock(dir, 1); | 1787 | ocfs2_inode_unlock(dir, 1); |
1788 | if (did_block_signals) | ||
1789 | ocfs2_unblock_signals(&oldset); | ||
1769 | 1790 | ||
1770 | brelse(new_fe_bh); | 1791 | brelse(new_fe_bh); |
1771 | brelse(parent_fe_bh); | 1792 | brelse(parent_fe_bh); |