diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-06-25 11:15:36 -0400 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-06-25 11:15:36 -0400 |
commit | 9f993fe4634b39ca4404ba278053b03f360ec08a (patch) | |
tree | 36e62a3d384fa9c313cacd73b7aea086d7f74e82 /fs/ntfs/aops.c | |
parent | 3f2faef00c6af17542ea8672ed7d09367222b2d0 (diff) |
NTFS: Fix a bug in address space operations error recovery code paths where
if the runlist was not mapped at all and a mapping error occured we
would leave the runlist locked on exit to the function so that the
next access to the same file would try to take the lock and deadlock.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/aops.c')
-rw-r--r-- | fs/ntfs/aops.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 24c46c20033..3f43bfe6184 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c | |||
@@ -264,7 +264,8 @@ lock_retry_remap: | |||
264 | goto lock_retry_remap; | 264 | goto lock_retry_remap; |
265 | rl = NULL; | 265 | rl = NULL; |
266 | lcn = err; | 266 | lcn = err; |
267 | } | 267 | } else if (!rl) |
268 | up_read(&ni->runlist.lock); | ||
268 | /* Hard error, zero out region. */ | 269 | /* Hard error, zero out region. */ |
269 | bh->b_blocknr = -1; | 270 | bh->b_blocknr = -1; |
270 | SetPageError(page); | 271 | SetPageError(page); |
@@ -690,7 +691,8 @@ lock_retry_remap: | |||
690 | goto lock_retry_remap; | 691 | goto lock_retry_remap; |
691 | rl = NULL; | 692 | rl = NULL; |
692 | lcn = err; | 693 | lcn = err; |
693 | } | 694 | } else if (!rl) |
695 | up_read(&ni->runlist.lock); | ||
694 | /* Failed to map the buffer, even after retrying. */ | 696 | /* Failed to map the buffer, even after retrying. */ |
695 | bh->b_blocknr = -1; | 697 | bh->b_blocknr = -1; |
696 | ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " | 698 | ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " |
@@ -965,8 +967,11 @@ lock_retry_remap: | |||
965 | if (err2 == -ENOMEM) | 967 | if (err2 == -ENOMEM) |
966 | page_is_dirty = TRUE; | 968 | page_is_dirty = TRUE; |
967 | lcn = err2; | 969 | lcn = err2; |
968 | } else | 970 | } else { |
969 | err2 = -EIO; | 971 | err2 = -EIO; |
972 | if (!rl) | ||
973 | up_read(&ni->runlist.lock); | ||
974 | } | ||
970 | /* Hard error. Abort writing this record. */ | 975 | /* Hard error. Abort writing this record. */ |
971 | if (!err || err == -ENOMEM) | 976 | if (!err || err == -ENOMEM) |
972 | err = err2; | 977 | err = err2; |
@@ -1660,6 +1665,8 @@ lock_retry_remap: | |||
1660 | "not supported yet. " | 1665 | "not supported yet. " |
1661 | "Sorry."); | 1666 | "Sorry."); |
1662 | err = -EOPNOTSUPP; | 1667 | err = -EOPNOTSUPP; |
1668 | if (!rl) | ||
1669 | up_read(&ni->runlist.lock); | ||
1663 | goto err_out; | 1670 | goto err_out; |
1664 | } else if (!is_retry && | 1671 | } else if (!is_retry && |
1665 | lcn == LCN_RL_NOT_MAPPED) { | 1672 | lcn == LCN_RL_NOT_MAPPED) { |
@@ -1674,7 +1681,8 @@ lock_retry_remap: | |||
1674 | goto lock_retry_remap; | 1681 | goto lock_retry_remap; |
1675 | rl = NULL; | 1682 | rl = NULL; |
1676 | lcn = err; | 1683 | lcn = err; |
1677 | } | 1684 | } else if (!rl) |
1685 | up_read(&ni->runlist.lock); | ||
1678 | /* | 1686 | /* |
1679 | * Failed to map the buffer, even after | 1687 | * Failed to map the buffer, even after |
1680 | * retrying. | 1688 | * retrying. |