diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-22 13:26:47 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | bcbfce8abd5f8d3f84eab60a9df1ec147f81c34f (patch) | |
tree | fe3ce6b6acf66d7cb9278cc47e2d4985e8ca70cf /fs/btrfs/disk-io.c | |
parent | e1c4b7451e22f5b0a9fbccfa560ee7b80c35b8cd (diff) | |
download | lwn-bcbfce8abd5f8d3f84eab60a9df1ec147f81c34f.tar.gz lwn-bcbfce8abd5f8d3f84eab60a9df1ec147f81c34f.zip |
Btrfs: Fix the unplug_io_fn to grab a consistent copy of page->mapping
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 19c258d2c7e2..1281c393c7e6 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -936,14 +936,25 @@ void btrfs_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) struct inode *inode; struct extent_map_tree *em_tree; struct extent_map *em; + struct address_space *mapping; u64 offset; + /* the generic O_DIRECT read code does this */ if (!page) { __unplug_io_fn(bdi, page); return; } - inode = page->mapping->host; + /* + * page->mapping may change at any time. Get a consistent copy + * and use that for everything below + */ + smp_mb(); + mapping = page->mapping; + if (!mapping) + return; + + inode = mapping->host; offset = page_offset(page); em_tree = &BTRFS_I(inode)->extent_tree; |