From 2f404a4152dad81d5397987ea6d50b177ab0e814 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Sat, 25 Jun 2005 16:15:36 +0100 Subject: [PATCH] --- yaml --- r: 4876 b: refs/heads/master c: 9f993fe4634b39ca4404ba278053b03f360ec08a h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/ntfs/ChangeLog | 4 ++++ trunk/fs/ntfs/aops.c | 16 ++++++++++++---- trunk/fs/ntfs/layout.h | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index d5c8766fc88b..512295f4b504 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3f2faef00c6af17542ea8672ed7d09367222b2d0 +refs/heads/master: 9f993fe4634b39ca4404ba278053b03f360ec08a diff --git a/trunk/fs/ntfs/ChangeLog b/trunk/fs/ntfs/ChangeLog index 08c8c04b0216..59ecca4297bb 100644 --- a/trunk/fs/ntfs/ChangeLog +++ b/trunk/fs/ntfs/ChangeLog @@ -121,6 +121,10 @@ ToDo/Notes: - Stamp the transaction log ($UsnJrnl), aka user space journal, if it is active on the volume and we are mounting read-write or remounting from read-only to read-write. + - 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. 2.1.22 - Many bug and race fixes and error handling improvements. diff --git a/trunk/fs/ntfs/aops.c b/trunk/fs/ntfs/aops.c index 24c46c200337..3f43bfe6184e 100644 --- a/trunk/fs/ntfs/aops.c +++ b/trunk/fs/ntfs/aops.c @@ -264,7 +264,8 @@ static int ntfs_read_block(struct page *page) goto lock_retry_remap; rl = NULL; lcn = err; - } + } else if (!rl) + up_read(&ni->runlist.lock); /* Hard error, zero out region. */ bh->b_blocknr = -1; SetPageError(page); @@ -690,7 +691,8 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) goto lock_retry_remap; rl = NULL; lcn = err; - } + } else if (!rl) + up_read(&ni->runlist.lock); /* Failed to map the buffer, even after retrying. */ bh->b_blocknr = -1; ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " @@ -965,8 +967,11 @@ static int ntfs_write_mst_block(struct page *page, if (err2 == -ENOMEM) page_is_dirty = TRUE; lcn = err2; - } else + } else { err2 = -EIO; + if (!rl) + up_read(&ni->runlist.lock); + } /* Hard error. Abort writing this record. */ if (!err || err == -ENOMEM) err = err2; @@ -1660,6 +1665,8 @@ static int ntfs_prepare_nonresident_write(struct page *page, "not supported yet. " "Sorry."); err = -EOPNOTSUPP; + if (!rl) + up_read(&ni->runlist.lock); goto err_out; } else if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { @@ -1674,7 +1681,8 @@ static int ntfs_prepare_nonresident_write(struct page *page, goto lock_retry_remap; rl = NULL; lcn = err; - } + } else if (!rl) + up_read(&ni->runlist.lock); /* * Failed to map the buffer, even after * retrying. diff --git a/trunk/fs/ntfs/layout.h b/trunk/fs/ntfs/layout.h index 03c3e8612e7c..609ad1728ce4 100644 --- a/trunk/fs/ntfs/layout.h +++ b/trunk/fs/ntfs/layout.h @@ -936,7 +936,7 @@ typedef struct { /* 56*/ le64 quota_charged; /* Byte size of the charge to the quota for all streams of the file. Note: Is zero if quotas are disabled. */ - /* 64*/ USN usn; /* Last update sequence number + /* 64*/ leUSN usn; /* Last update sequence number of the file. This is a direct index into the transaction log file ($UsnJrnl). It is zero if the usn journal is disabled or this file has