summaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/extents.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@tuxera.com>2010-10-01 05:46:31 +0200
committerChristoph Hellwig <hch@lst.de>2010-10-01 05:46:31 +0200
commit7fcc99f4f2ddb1c39abc05fbb9b32f05b03c7f8f (patch)
treeb07045981f17d855f89f1ef59579e330d8ffce20 /fs/hfsplus/extents.c
parenthfsplus: protect readdir against removals from open_dir_list (diff)
downloadlinux-7fcc99f4f2ddb1c39abc05fbb9b32f05b03c7f8f.tar.xz
linux-7fcc99f4f2ddb1c39abc05fbb9b32f05b03c7f8f.zip
hfsplus: add missing extent locking in hfsplus_write_inode
Most of the extent handling code already does proper SMP locking, but hfsplus_write_inode was calling into hfsplus_ext_write_extent without taking the extents_lock. Fix this by splitting hfsplus_ext_write_extent into an internal helper that expects the lock, and a public interface that first acquires it. Also add a few locking asserts and document the locking rules in hfsplus_fs.h. Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Diffstat (limited to 'fs/hfsplus/extents.c')
-rw-r--r--fs/hfsplus/extents.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index b1017eaa4fdc..0c9cb1820a52 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -88,6 +88,8 @@ static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
int res;
+ WARN_ON(!mutex_is_locked(&hip->extents_lock));
+
hfsplus_ext_build_key(fd->search_key, inode->i_ino, hip->cached_start,
HFSPLUS_IS_RSRC(inode) ?
HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
@@ -108,7 +110,7 @@ static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data
}
}
-void hfsplus_ext_write_extent(struct inode *inode)
+static void hfsplus_ext_write_extent_locked(struct inode *inode)
{
if (HFSPLUS_I(inode)->flags & HFSPLUS_FLG_EXT_DIRTY) {
struct hfs_find_data fd;
@@ -119,6 +121,13 @@ void hfsplus_ext_write_extent(struct inode *inode)
}
}
+void hfsplus_ext_write_extent(struct inode *inode)
+{
+ mutex_lock(&HFSPLUS_I(inode)->extents_lock);
+ hfsplus_ext_write_extent_locked(inode);
+ mutex_unlock(&HFSPLUS_I(inode)->extents_lock);
+}
+
static inline int __hfsplus_ext_read_extent(struct hfs_find_data *fd,
struct hfsplus_extent *extent,
u32 cnid, u32 block, u8 type)
@@ -144,6 +153,8 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct in
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
int res;
+ WARN_ON(!mutex_is_locked(&hip->extents_lock));
+
if (hip->flags & HFSPLUS_FLG_EXT_DIRTY)
__hfsplus_ext_write_extent(inode, fd);
@@ -433,7 +444,7 @@ out:
insert_extent:
dprint(DBG_EXTENT, "insert new extent\n");
- hfsplus_ext_write_extent(inode);
+ hfsplus_ext_write_extent_locked(inode);
memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec));
hip->cached_extents[0].start_block = cpu_to_be32(start);