summary refs log tree commit diff
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
authorNathan Scott <nathans@sgi.com>2005-05-05 13:33:20 -0700
committerChristoph Hellwig <hch@melbourne.sgi.com>2005-05-05 13:33:20 -0700
commit24e17b5fb99d4d1b47fe0847a3a801e36d431ff6 (patch)
tree0ac181b6ddc64a04fe55aa79efceecc6e4d90451 /fs/xfs/xfs_iomap.c
parent775bf6c99a4ebde13bdb8dfa528ed241483b49ef (diff)
downloadlinux-24e17b5fb99d4d1b47fe0847a3a801e36d431ff6.tar.gz
[XFS] Use the right offset when ensuring a delayed allocate conversion has covered the offset originally requested. Can cause data corruption when multiple processes are performing writeout on different areas of the same file. Quite difficult to hit though.
SGI Modid: xfs-linux:xfs-kern:22377a

Signed-off-by: Nathan Scott <nathans@sgi.com>
Signed-off-by: Christoph Hellwig <hch@sgi.com>
.
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3826e8f0e28a..b291a2b53579 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -308,7 +308,8 @@ phase2:
 			break;
 		}
 
-		error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps);
+		error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count,
+						 &imap, &nimaps);
 		break;
 	case BMAPI_UNWRITTEN:
 		lockmode = 0;
@@ -746,6 +747,8 @@ write_map:
 int
 xfs_iomap_write_allocate(
 	xfs_inode_t	*ip,
+	loff_t		offset,
+	size_t		count,
 	xfs_bmbt_irec_t *map,
 	int		*retmap)
 {
@@ -770,9 +773,9 @@ xfs_iomap_write_allocate(
 	if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
 		return XFS_ERROR(error);
 
-	offset_fsb = map->br_startoff;
+	offset_fsb = XFS_B_TO_FSBT(mp, offset);
 	count_fsb = map->br_blockcount;
-	map_start_fsb = offset_fsb;
+	map_start_fsb = map->br_startoff;
 
 	XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
 
@@ -868,9 +871,9 @@ xfs_iomap_write_allocate(
 					imap[i].br_startoff,
 				        imap[i].br_blockcount,imap[i].br_state);
                         }
-			if ((map->br_startoff >= imap[i].br_startoff) &&
-			    (map->br_startoff < (imap[i].br_startoff +
-						 imap[i].br_blockcount))) {
+			if ((offset_fsb >= imap[i].br_startoff) &&
+			    (offset_fsb < (imap[i].br_startoff +
+					   imap[i].br_blockcount))) {
 				*map = imap[i];
 				*retmap = 1;
 				XFS_STATS_INC(xs_xstrat_quick);
@@ -883,9 +886,8 @@ xfs_iomap_write_allocate(
 		 * file, just surrounding data, try again.
 		 */
 		nimaps--;
-		offset_fsb = imap[nimaps].br_startoff +
-			     imap[nimaps].br_blockcount;
-		map_start_fsb = offset_fsb;
+		map_start_fsb = imap[nimaps].br_startoff +
+				imap[nimaps].br_blockcount;
 	}
 
 trans_cancel: