public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] xfs: a couple getbmap cleanups
@ 2009-02-24 13:38 Christoph Hellwig
  2009-03-16  6:30 ` Christoph Hellwig
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Christoph Hellwig @ 2009-02-24 13:38 UTC (permalink / raw)
  To: xfs

 - reshuffle various conditionals for data vs attr fork to make the code
   more readable
 - do fine-grainded goto-based error handling
 - exit early from conditionals instead of keeping a long else branch
   around
 - allow kmem_alloc to fail

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: xfs/fs/xfs/xfs_bmap.c
===================================================================
--- xfs.orig/fs/xfs/xfs_bmap.c	2009-02-23 18:08:35.352924726 +0100
+++ xfs/fs/xfs/xfs_bmap.c	2009-02-23 18:23:49.527051836 +0100
@@ -5857,7 +5857,7 @@ xfs_getbmap(
 	void			*arg)		/* formatter arg */
 {
 	__int64_t		bmvend;		/* last block requested */
-	int			error;		/* return value */
+	int			error = 0;	/* return value */
 	__int64_t		fixlen;		/* length for -1 case */
 	int			i;		/* extent number */
 	int			lock;		/* lock state */
@@ -5876,30 +5876,8 @@ xfs_getbmap(
 
 	mp = ip->i_mount;
 	iflags = bmv->bmv_iflags;
-
 	whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
 
-	/*	If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
-	 *	generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
-	 *	bit is set for the file, generate a read event in order
-	 *	that the DMAPI application may do its thing before we return
-	 *	the extents.  Usually this means restoring user file data to
-	 *	regions of the file that look like holes.
-	 *
-	 *	The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
-	 *	BMV_IF_NO_DMAPI_READ so that read events are generated.
-	 *	If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
-	 *	could misinterpret holes in a DMAPI file as true holes,
-	 *	when in fact they may represent offline user data.
-	 */
-	if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
-	    DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
-	    whichfork == XFS_DATA_FORK) {
-		error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
-		if (error)
-			return XFS_ERROR(error);
-	}
-
 	if (whichfork == XFS_ATTR_FORK) {
 		if (XFS_IFORK_Q(ip)) {
 			if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
@@ -5913,11 +5891,37 @@ xfs_getbmap(
 					 ip->i_mount);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
-	} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
-		   ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
-		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
-		return XFS_ERROR(EINVAL);
-	if (whichfork == XFS_DATA_FORK) {
+
+		prealloced = 0;
+		fixlen = 1LL << 32;
+	} else {
+		/*
+		 * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
+		 * not generate a DMAPI read event.  Otherwise, if the
+		 * DM_EVENT_READ bit is set for the file, generate a read
+		 * event in order that the DMAPI application may do its thing
+		 * before we return the extents.  Usually this means restoring
+		 * user file data to regions of the file that look like holes.
+		 *
+		 * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
+		 * BMV_IF_NO_DMAPI_READ so that read events are generated.
+		 * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
+		 * could misinterpret holes in a DMAPI file as true holes,
+		 * when in fact they may represent offline user data.
+		 */
+		if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
+		    !(iflags & BMV_IF_NO_DMAPI_READ)) {
+			error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
+					      0, 0, 0, NULL);
+			if (error)
+				return XFS_ERROR(error);
+		}
+
+		if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
+		    ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
+		    ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
+			return XFS_ERROR(EINVAL);
+
 		if (xfs_get_extsz_hint(ip) ||
 		    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
 			prealloced = 1;
@@ -5926,42 +5930,34 @@ xfs_getbmap(
 			prealloced = 0;
 			fixlen = ip->i_size;
 		}
-	} else {
-		prealloced = 0;
-		fixlen = 1LL << 32;
 	}
 
 	if (bmv->bmv_length == -1) {
 		fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
-		bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
-					(__int64_t)0);
-	} else if (bmv->bmv_length < 0)
-		return XFS_ERROR(EINVAL);
-	if (bmv->bmv_length == 0) {
+		bmv->bmv_length =
+			max_t(__int64_t, fixlen - bmv->bmv_offset, 0);
+	} else if (bmv->bmv_length == 0) {
 		bmv->bmv_entries = 0;
 		return 0;
+	} else if (bmv->bmv_length < 0) {
+		return XFS_ERROR(EINVAL);
 	}
+
 	nex = bmv->bmv_count - 1;
 	if (nex <= 0)
 		return XFS_ERROR(EINVAL);
 	bmvend = bmv->bmv_offset + bmv->bmv_length;
 
 	xfs_ilock(ip, XFS_IOLOCK_SHARED);
-
-	if (((iflags & BMV_IF_DELALLOC) == 0) &&
-	    (whichfork == XFS_DATA_FORK) &&
-	    (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
-		/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
-		error = xfs_flush_pages(ip, (xfs_off_t)0,
-					       -1, 0, FI_REMAPF);
-		if (error) {
-			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-		return error;
+	if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
+		if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) {
+			error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF);
+			if (error)
+				goto out_unlock_iolock;
 		}
-	}
 
-	ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
-	       ip->i_delayed_blks == 0);
+		ASSERT(ip->i_delayed_blks == 0);
+	}
 
 	lock = xfs_ilock_map_shared(ip);
 
@@ -5972,23 +5968,24 @@ xfs_getbmap(
 	if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
 		nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
 
-	bmapi_flags = xfs_bmapi_aflag(whichfork) |
-			((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
+	bmapi_flags = xfs_bmapi_aflag(whichfork);
+	if (!(iflags & BMV_IF_PREALLOC))
+		bmapi_flags |= XFS_BMAPI_IGSTATE;
 
 	/*
 	 * Allocate enough space to handle "subnex" maps at a time.
 	 */
 	subnex = 16;
-	map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
+	map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL);
+	if (!map)
+		goto out_unlock_ilock;
 
 	bmv->bmv_entries = 0;
 
-	if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
-		if (((iflags & BMV_IF_DELALLOC) == 0) ||
-		    whichfork == XFS_ATTR_FORK) {
-			error = 0;
-			goto unlock_and_return;
-		}
+	if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 &&
+	    (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) {
+		error = 0;
+		goto out_free_map;
 	}
 
 	nexleft = nex;
@@ -6000,10 +5997,12 @@ xfs_getbmap(
 				  bmapi_flags, NULL, 0, map, &nmap,
 				  NULL, NULL);
 		if (error)
-			goto unlock_and_return;
+			goto out_free_map;
 		ASSERT(nmap <= subnex);
 
 		for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
+			int full = 0;	/* user array is full */
+
 			out.bmv_oflags = 0;
 			if (map[i].br_state == XFS_EXT_UNWRITTEN)
 				out.bmv_oflags |= BMV_OF_PREALLOC;
@@ -6018,36 +6017,32 @@ xfs_getbmap(
 			    whichfork == XFS_ATTR_FORK) {
 				/* came to the end of attribute fork */
 				out.bmv_oflags |= BMV_OF_LAST;
-				goto unlock_and_return;
-			} else {
-				int full = 0;	/* user array is full */
-
-				if (!xfs_getbmapx_fix_eof_hole(ip, &out,
-							prealloced, bmvend,
-							map[i].br_startblock)) {
-					goto unlock_and_return;
-				}
-
-				/* format results & advance arg */
-				error = formatter(&arg, &out, &full);
-				if (error || full)
-					goto unlock_and_return;
-				nexleft--;
-				bmv->bmv_offset =
-					out.bmv_offset + out.bmv_length;
-				bmv->bmv_length = MAX((__int64_t)0,
-					(__int64_t)(bmvend - bmv->bmv_offset));
-				bmv->bmv_entries++;
+				goto out_free_map;
 			}
+
+			if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced,
+					bmvend, map[i].br_startblock))
+				goto out_free_map;
+
+			/* format results & advance arg */
+			error = formatter(&arg, &out, &full);
+			if (error || full)
+				goto out_free_map;
+			nexleft--;
+			bmv->bmv_offset =
+				out.bmv_offset + out.bmv_length;
+			bmv->bmv_length =
+				max_t(__int64_t, 0, bmvend - bmv->bmv_offset);
+			bmv->bmv_entries++;
 		}
 	} while (nmap && nexleft && bmv->bmv_length);
 
-unlock_and_return:
+ out_free_map:
+	kmem_free(map);
+ out_unlock_ilock:
 	xfs_iunlock_map_shared(ip, lock);
+ out_unlock_iolock:
 	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-
-	kmem_free(map);
-
 	return error;
 }
 

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-02-24 13:38 [PATCH 1/2] xfs: a couple getbmap cleanups Christoph Hellwig
@ 2009-03-16  6:30 ` Christoph Hellwig
  2009-03-29  7:44   ` Christoph Hellwig
  2009-04-06 23:10 ` Eric Sandeen
  2009-04-07  0:57 ` Felix Blyakher
  2 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2009-03-16  6:30 UTC (permalink / raw)
  To: xfs

ping?

On Tue, Feb 24, 2009 at 08:38:58AM -0500, Christoph Hellwig wrote:
>  - reshuffle various conditionals for data vs attr fork to make the code
>    more readable
>  - do fine-grainded goto-based error handling
>  - exit early from conditionals instead of keeping a long else branch
>    around
>  - allow kmem_alloc to fail
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Index: xfs/fs/xfs/xfs_bmap.c
> ===================================================================
> --- xfs.orig/fs/xfs/xfs_bmap.c	2009-02-23 18:08:35.352924726 +0100
> +++ xfs/fs/xfs/xfs_bmap.c	2009-02-23 18:23:49.527051836 +0100
> @@ -5857,7 +5857,7 @@ xfs_getbmap(
>  	void			*arg)		/* formatter arg */
>  {
>  	__int64_t		bmvend;		/* last block requested */
> -	int			error;		/* return value */
> +	int			error = 0;	/* return value */
>  	__int64_t		fixlen;		/* length for -1 case */
>  	int			i;		/* extent number */
>  	int			lock;		/* lock state */
> @@ -5876,30 +5876,8 @@ xfs_getbmap(
>  
>  	mp = ip->i_mount;
>  	iflags = bmv->bmv_iflags;
> -
>  	whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
>  
> -	/*	If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
> -	 *	generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
> -	 *	bit is set for the file, generate a read event in order
> -	 *	that the DMAPI application may do its thing before we return
> -	 *	the extents.  Usually this means restoring user file data to
> -	 *	regions of the file that look like holes.
> -	 *
> -	 *	The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> -	 *	BMV_IF_NO_DMAPI_READ so that read events are generated.
> -	 *	If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
> -	 *	could misinterpret holes in a DMAPI file as true holes,
> -	 *	when in fact they may represent offline user data.
> -	 */
> -	if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
> -	    DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> -	    whichfork == XFS_DATA_FORK) {
> -		error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
> -		if (error)
> -			return XFS_ERROR(error);
> -	}
> -
>  	if (whichfork == XFS_ATTR_FORK) {
>  		if (XFS_IFORK_Q(ip)) {
>  			if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
> @@ -5913,11 +5891,37 @@ xfs_getbmap(
>  					 ip->i_mount);
>  			return XFS_ERROR(EFSCORRUPTED);
>  		}
> -	} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> -		   ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> -		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> -		return XFS_ERROR(EINVAL);
> -	if (whichfork == XFS_DATA_FORK) {
> +
> +		prealloced = 0;
> +		fixlen = 1LL << 32;
> +	} else {
> +		/*
> +		 * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
> +		 * not generate a DMAPI read event.  Otherwise, if the
> +		 * DM_EVENT_READ bit is set for the file, generate a read
> +		 * event in order that the DMAPI application may do its thing
> +		 * before we return the extents.  Usually this means restoring
> +		 * user file data to regions of the file that look like holes.
> +		 *
> +		 * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> +		 * BMV_IF_NO_DMAPI_READ so that read events are generated.
> +		 * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
> +		 * could misinterpret holes in a DMAPI file as true holes,
> +		 * when in fact they may represent offline user data.
> +		 */
> +		if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> +		    !(iflags & BMV_IF_NO_DMAPI_READ)) {
> +			error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
> +					      0, 0, 0, NULL);
> +			if (error)
> +				return XFS_ERROR(error);
> +		}
> +
> +		if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> +		    ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> +		    ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> +			return XFS_ERROR(EINVAL);
> +
>  		if (xfs_get_extsz_hint(ip) ||
>  		    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
>  			prealloced = 1;
> @@ -5926,42 +5930,34 @@ xfs_getbmap(
>  			prealloced = 0;
>  			fixlen = ip->i_size;
>  		}
> -	} else {
> -		prealloced = 0;
> -		fixlen = 1LL << 32;
>  	}
>  
>  	if (bmv->bmv_length == -1) {
>  		fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
> -		bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
> -					(__int64_t)0);
> -	} else if (bmv->bmv_length < 0)
> -		return XFS_ERROR(EINVAL);
> -	if (bmv->bmv_length == 0) {
> +		bmv->bmv_length =
> +			max_t(__int64_t, fixlen - bmv->bmv_offset, 0);
> +	} else if (bmv->bmv_length == 0) {
>  		bmv->bmv_entries = 0;
>  		return 0;
> +	} else if (bmv->bmv_length < 0) {
> +		return XFS_ERROR(EINVAL);
>  	}
> +
>  	nex = bmv->bmv_count - 1;
>  	if (nex <= 0)
>  		return XFS_ERROR(EINVAL);
>  	bmvend = bmv->bmv_offset + bmv->bmv_length;
>  
>  	xfs_ilock(ip, XFS_IOLOCK_SHARED);
> -
> -	if (((iflags & BMV_IF_DELALLOC) == 0) &&
> -	    (whichfork == XFS_DATA_FORK) &&
> -	    (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
> -		/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
> -		error = xfs_flush_pages(ip, (xfs_off_t)0,
> -					       -1, 0, FI_REMAPF);
> -		if (error) {
> -			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> -		return error;
> +	if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
> +		if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) {
> +			error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF);
> +			if (error)
> +				goto out_unlock_iolock;
>  		}
> -	}
>  
> -	ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
> -	       ip->i_delayed_blks == 0);
> +		ASSERT(ip->i_delayed_blks == 0);
> +	}
>  
>  	lock = xfs_ilock_map_shared(ip);
>  
> @@ -5972,23 +5968,24 @@ xfs_getbmap(
>  	if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
>  		nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
>  
> -	bmapi_flags = xfs_bmapi_aflag(whichfork) |
> -			((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
> +	bmapi_flags = xfs_bmapi_aflag(whichfork);
> +	if (!(iflags & BMV_IF_PREALLOC))
> +		bmapi_flags |= XFS_BMAPI_IGSTATE;
>  
>  	/*
>  	 * Allocate enough space to handle "subnex" maps at a time.
>  	 */
>  	subnex = 16;
> -	map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
> +	map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL);
> +	if (!map)
> +		goto out_unlock_ilock;
>  
>  	bmv->bmv_entries = 0;
>  
> -	if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
> -		if (((iflags & BMV_IF_DELALLOC) == 0) ||
> -		    whichfork == XFS_ATTR_FORK) {
> -			error = 0;
> -			goto unlock_and_return;
> -		}
> +	if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 &&
> +	    (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) {
> +		error = 0;
> +		goto out_free_map;
>  	}
>  
>  	nexleft = nex;
> @@ -6000,10 +5997,12 @@ xfs_getbmap(
>  				  bmapi_flags, NULL, 0, map, &nmap,
>  				  NULL, NULL);
>  		if (error)
> -			goto unlock_and_return;
> +			goto out_free_map;
>  		ASSERT(nmap <= subnex);
>  
>  		for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
> +			int full = 0;	/* user array is full */
> +
>  			out.bmv_oflags = 0;
>  			if (map[i].br_state == XFS_EXT_UNWRITTEN)
>  				out.bmv_oflags |= BMV_OF_PREALLOC;
> @@ -6018,36 +6017,32 @@ xfs_getbmap(
>  			    whichfork == XFS_ATTR_FORK) {
>  				/* came to the end of attribute fork */
>  				out.bmv_oflags |= BMV_OF_LAST;
> -				goto unlock_and_return;
> -			} else {
> -				int full = 0;	/* user array is full */
> -
> -				if (!xfs_getbmapx_fix_eof_hole(ip, &out,
> -							prealloced, bmvend,
> -							map[i].br_startblock)) {
> -					goto unlock_and_return;
> -				}
> -
> -				/* format results & advance arg */
> -				error = formatter(&arg, &out, &full);
> -				if (error || full)
> -					goto unlock_and_return;
> -				nexleft--;
> -				bmv->bmv_offset =
> -					out.bmv_offset + out.bmv_length;
> -				bmv->bmv_length = MAX((__int64_t)0,
> -					(__int64_t)(bmvend - bmv->bmv_offset));
> -				bmv->bmv_entries++;
> +				goto out_free_map;
>  			}
> +
> +			if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced,
> +					bmvend, map[i].br_startblock))
> +				goto out_free_map;
> +
> +			/* format results & advance arg */
> +			error = formatter(&arg, &out, &full);
> +			if (error || full)
> +				goto out_free_map;
> +			nexleft--;
> +			bmv->bmv_offset =
> +				out.bmv_offset + out.bmv_length;
> +			bmv->bmv_length =
> +				max_t(__int64_t, 0, bmvend - bmv->bmv_offset);
> +			bmv->bmv_entries++;
>  		}
>  	} while (nmap && nexleft && bmv->bmv_length);
>  
> -unlock_and_return:
> + out_free_map:
> +	kmem_free(map);
> + out_unlock_ilock:
>  	xfs_iunlock_map_shared(ip, lock);
> + out_unlock_iolock:
>  	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> -
> -	kmem_free(map);
> -
>  	return error;
>  }
>  
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
---end quoted text---

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-03-16  6:30 ` Christoph Hellwig
@ 2009-03-29  7:44   ` Christoph Hellwig
  0 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2009-03-29  7:44 UTC (permalink / raw)
  To: xfs

ping^2?

On Mon, Mar 16, 2009 at 02:30:53AM -0400, Christoph Hellwig wrote:
> ping?
> 
> On Tue, Feb 24, 2009 at 08:38:58AM -0500, Christoph Hellwig wrote:
> >  - reshuffle various conditionals for data vs attr fork to make the code
> >    more readable
> >  - do fine-grainded goto-based error handling
> >  - exit early from conditionals instead of keeping a long else branch
> >    around
> >  - allow kmem_alloc to fail
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > 
> > Index: xfs/fs/xfs/xfs_bmap.c
> > ===================================================================
> > --- xfs.orig/fs/xfs/xfs_bmap.c	2009-02-23 18:08:35.352924726 +0100
> > +++ xfs/fs/xfs/xfs_bmap.c	2009-02-23 18:23:49.527051836 +0100
> > @@ -5857,7 +5857,7 @@ xfs_getbmap(
> >  	void			*arg)		/* formatter arg */
> >  {
> >  	__int64_t		bmvend;		/* last block requested */
> > -	int			error;		/* return value */
> > +	int			error = 0;	/* return value */
> >  	__int64_t		fixlen;		/* length for -1 case */
> >  	int			i;		/* extent number */
> >  	int			lock;		/* lock state */
> > @@ -5876,30 +5876,8 @@ xfs_getbmap(
> >  
> >  	mp = ip->i_mount;
> >  	iflags = bmv->bmv_iflags;
> > -
> >  	whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
> >  
> > -	/*	If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
> > -	 *	generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
> > -	 *	bit is set for the file, generate a read event in order
> > -	 *	that the DMAPI application may do its thing before we return
> > -	 *	the extents.  Usually this means restoring user file data to
> > -	 *	regions of the file that look like holes.
> > -	 *
> > -	 *	The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> > -	 *	BMV_IF_NO_DMAPI_READ so that read events are generated.
> > -	 *	If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
> > -	 *	could misinterpret holes in a DMAPI file as true holes,
> > -	 *	when in fact they may represent offline user data.
> > -	 */
> > -	if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
> > -	    DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> > -	    whichfork == XFS_DATA_FORK) {
> > -		error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
> > -		if (error)
> > -			return XFS_ERROR(error);
> > -	}
> > -
> >  	if (whichfork == XFS_ATTR_FORK) {
> >  		if (XFS_IFORK_Q(ip)) {
> >  			if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
> > @@ -5913,11 +5891,37 @@ xfs_getbmap(
> >  					 ip->i_mount);
> >  			return XFS_ERROR(EFSCORRUPTED);
> >  		}
> > -	} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> > -		   ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> > -		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> > -		return XFS_ERROR(EINVAL);
> > -	if (whichfork == XFS_DATA_FORK) {
> > +
> > +		prealloced = 0;
> > +		fixlen = 1LL << 32;
> > +	} else {
> > +		/*
> > +		 * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
> > +		 * not generate a DMAPI read event.  Otherwise, if the
> > +		 * DM_EVENT_READ bit is set for the file, generate a read
> > +		 * event in order that the DMAPI application may do its thing
> > +		 * before we return the extents.  Usually this means restoring
> > +		 * user file data to regions of the file that look like holes.
> > +		 *
> > +		 * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> > +		 * BMV_IF_NO_DMAPI_READ so that read events are generated.
> > +		 * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
> > +		 * could misinterpret holes in a DMAPI file as true holes,
> > +		 * when in fact they may represent offline user data.
> > +		 */
> > +		if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> > +		    !(iflags & BMV_IF_NO_DMAPI_READ)) {
> > +			error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
> > +					      0, 0, 0, NULL);
> > +			if (error)
> > +				return XFS_ERROR(error);
> > +		}
> > +
> > +		if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> > +		    ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> > +		    ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> > +			return XFS_ERROR(EINVAL);
> > +
> >  		if (xfs_get_extsz_hint(ip) ||
> >  		    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
> >  			prealloced = 1;
> > @@ -5926,42 +5930,34 @@ xfs_getbmap(
> >  			prealloced = 0;
> >  			fixlen = ip->i_size;
> >  		}
> > -	} else {
> > -		prealloced = 0;
> > -		fixlen = 1LL << 32;
> >  	}
> >  
> >  	if (bmv->bmv_length == -1) {
> >  		fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
> > -		bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
> > -					(__int64_t)0);
> > -	} else if (bmv->bmv_length < 0)
> > -		return XFS_ERROR(EINVAL);
> > -	if (bmv->bmv_length == 0) {
> > +		bmv->bmv_length =
> > +			max_t(__int64_t, fixlen - bmv->bmv_offset, 0);
> > +	} else if (bmv->bmv_length == 0) {
> >  		bmv->bmv_entries = 0;
> >  		return 0;
> > +	} else if (bmv->bmv_length < 0) {
> > +		return XFS_ERROR(EINVAL);
> >  	}
> > +
> >  	nex = bmv->bmv_count - 1;
> >  	if (nex <= 0)
> >  		return XFS_ERROR(EINVAL);
> >  	bmvend = bmv->bmv_offset + bmv->bmv_length;
> >  
> >  	xfs_ilock(ip, XFS_IOLOCK_SHARED);
> > -
> > -	if (((iflags & BMV_IF_DELALLOC) == 0) &&
> > -	    (whichfork == XFS_DATA_FORK) &&
> > -	    (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
> > -		/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
> > -		error = xfs_flush_pages(ip, (xfs_off_t)0,
> > -					       -1, 0, FI_REMAPF);
> > -		if (error) {
> > -			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> > -		return error;
> > +	if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
> > +		if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) {
> > +			error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF);
> > +			if (error)
> > +				goto out_unlock_iolock;
> >  		}
> > -	}
> >  
> > -	ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
> > -	       ip->i_delayed_blks == 0);
> > +		ASSERT(ip->i_delayed_blks == 0);
> > +	}
> >  
> >  	lock = xfs_ilock_map_shared(ip);
> >  
> > @@ -5972,23 +5968,24 @@ xfs_getbmap(
> >  	if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
> >  		nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
> >  
> > -	bmapi_flags = xfs_bmapi_aflag(whichfork) |
> > -			((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
> > +	bmapi_flags = xfs_bmapi_aflag(whichfork);
> > +	if (!(iflags & BMV_IF_PREALLOC))
> > +		bmapi_flags |= XFS_BMAPI_IGSTATE;
> >  
> >  	/*
> >  	 * Allocate enough space to handle "subnex" maps at a time.
> >  	 */
> >  	subnex = 16;
> > -	map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
> > +	map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL);
> > +	if (!map)
> > +		goto out_unlock_ilock;
> >  
> >  	bmv->bmv_entries = 0;
> >  
> > -	if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
> > -		if (((iflags & BMV_IF_DELALLOC) == 0) ||
> > -		    whichfork == XFS_ATTR_FORK) {
> > -			error = 0;
> > -			goto unlock_and_return;
> > -		}
> > +	if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 &&
> > +	    (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) {
> > +		error = 0;
> > +		goto out_free_map;
> >  	}
> >  
> >  	nexleft = nex;
> > @@ -6000,10 +5997,12 @@ xfs_getbmap(
> >  				  bmapi_flags, NULL, 0, map, &nmap,
> >  				  NULL, NULL);
> >  		if (error)
> > -			goto unlock_and_return;
> > +			goto out_free_map;
> >  		ASSERT(nmap <= subnex);
> >  
> >  		for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
> > +			int full = 0;	/* user array is full */
> > +
> >  			out.bmv_oflags = 0;
> >  			if (map[i].br_state == XFS_EXT_UNWRITTEN)
> >  				out.bmv_oflags |= BMV_OF_PREALLOC;
> > @@ -6018,36 +6017,32 @@ xfs_getbmap(
> >  			    whichfork == XFS_ATTR_FORK) {
> >  				/* came to the end of attribute fork */
> >  				out.bmv_oflags |= BMV_OF_LAST;
> > -				goto unlock_and_return;
> > -			} else {
> > -				int full = 0;	/* user array is full */
> > -
> > -				if (!xfs_getbmapx_fix_eof_hole(ip, &out,
> > -							prealloced, bmvend,
> > -							map[i].br_startblock)) {
> > -					goto unlock_and_return;
> > -				}
> > -
> > -				/* format results & advance arg */
> > -				error = formatter(&arg, &out, &full);
> > -				if (error || full)
> > -					goto unlock_and_return;
> > -				nexleft--;
> > -				bmv->bmv_offset =
> > -					out.bmv_offset + out.bmv_length;
> > -				bmv->bmv_length = MAX((__int64_t)0,
> > -					(__int64_t)(bmvend - bmv->bmv_offset));
> > -				bmv->bmv_entries++;
> > +				goto out_free_map;
> >  			}
> > +
> > +			if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced,
> > +					bmvend, map[i].br_startblock))
> > +				goto out_free_map;
> > +
> > +			/* format results & advance arg */
> > +			error = formatter(&arg, &out, &full);
> > +			if (error || full)
> > +				goto out_free_map;
> > +			nexleft--;
> > +			bmv->bmv_offset =
> > +				out.bmv_offset + out.bmv_length;
> > +			bmv->bmv_length =
> > +				max_t(__int64_t, 0, bmvend - bmv->bmv_offset);
> > +			bmv->bmv_entries++;
> >  		}
> >  	} while (nmap && nexleft && bmv->bmv_length);
> >  
> > -unlock_and_return:
> > + out_free_map:
> > +	kmem_free(map);
> > + out_unlock_ilock:
> >  	xfs_iunlock_map_shared(ip, lock);
> > + out_unlock_iolock:
> >  	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> > -
> > -	kmem_free(map);
> > -
> >  	return error;
> >  }
> >  
> > 
> > _______________________________________________
> > xfs mailing list
> > xfs@oss.sgi.com
> > http://oss.sgi.com/mailman/listinfo/xfs
> ---end quoted text---
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
---end quoted text---

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-02-24 13:38 [PATCH 1/2] xfs: a couple getbmap cleanups Christoph Hellwig
  2009-03-16  6:30 ` Christoph Hellwig
@ 2009-04-06 23:10 ` Eric Sandeen
  2009-04-07  0:57 ` Felix Blyakher
  2 siblings, 0 replies; 10+ messages in thread
From: Eric Sandeen @ 2009-04-06 23:10 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs

Christoph Hellwig wrote:
>  - reshuffle various conditionals for data vs attr fork to make the code
>    more readable
>  - do fine-grainded goto-based error handling
>  - exit early from conditionals instead of keeping a long else branch
>    around
>  - allow kmem_alloc to fail
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: Eric Sandeen <sandeen@sandeen.net>

> Index: xfs/fs/xfs/xfs_bmap.c
> ===================================================================
> --- xfs.orig/fs/xfs/xfs_bmap.c	2009-02-23 18:08:35.352924726 +0100
> +++ xfs/fs/xfs/xfs_bmap.c	2009-02-23 18:23:49.527051836 +0100
> @@ -5857,7 +5857,7 @@ xfs_getbmap(
>  	void			*arg)		/* formatter arg */
>  {
>  	__int64_t		bmvend;		/* last block requested */
> -	int			error;		/* return value */
> +	int			error = 0;	/* return value */
>  	__int64_t		fixlen;		/* length for -1 case */
>  	int			i;		/* extent number */
>  	int			lock;		/* lock state */
> @@ -5876,30 +5876,8 @@ xfs_getbmap(
>  
>  	mp = ip->i_mount;
>  	iflags = bmv->bmv_iflags;
> -
>  	whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
>  
> -	/*	If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
> -	 *	generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
> -	 *	bit is set for the file, generate a read event in order
> -	 *	that the DMAPI application may do its thing before we return
> -	 *	the extents.  Usually this means restoring user file data to
> -	 *	regions of the file that look like holes.
> -	 *
> -	 *	The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> -	 *	BMV_IF_NO_DMAPI_READ so that read events are generated.
> -	 *	If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
> -	 *	could misinterpret holes in a DMAPI file as true holes,
> -	 *	when in fact they may represent offline user data.
> -	 */
> -	if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
> -	    DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> -	    whichfork == XFS_DATA_FORK) {
> -		error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
> -		if (error)
> -			return XFS_ERROR(error);
> -	}
> -
>  	if (whichfork == XFS_ATTR_FORK) {
>  		if (XFS_IFORK_Q(ip)) {
>  			if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
> @@ -5913,11 +5891,37 @@ xfs_getbmap(
>  					 ip->i_mount);
>  			return XFS_ERROR(EFSCORRUPTED);
>  		}
> -	} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> -		   ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> -		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> -		return XFS_ERROR(EINVAL);
> -	if (whichfork == XFS_DATA_FORK) {
> +
> +		prealloced = 0;
> +		fixlen = 1LL << 32;
> +	} else {
> +		/*
> +		 * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
> +		 * not generate a DMAPI read event.  Otherwise, if the
> +		 * DM_EVENT_READ bit is set for the file, generate a read
> +		 * event in order that the DMAPI application may do its thing
> +		 * before we return the extents.  Usually this means restoring
> +		 * user file data to regions of the file that look like holes.
> +		 *
> +		 * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> +		 * BMV_IF_NO_DMAPI_READ so that read events are generated.
> +		 * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
> +		 * could misinterpret holes in a DMAPI file as true holes,
> +		 * when in fact they may represent offline user data.
> +		 */
> +		if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> +		    !(iflags & BMV_IF_NO_DMAPI_READ)) {
> +			error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
> +					      0, 0, 0, NULL);
> +			if (error)
> +				return XFS_ERROR(error);
> +		}
> +
> +		if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> +		    ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> +		    ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> +			return XFS_ERROR(EINVAL);
> +
>  		if (xfs_get_extsz_hint(ip) ||
>  		    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
>  			prealloced = 1;
> @@ -5926,42 +5930,34 @@ xfs_getbmap(
>  			prealloced = 0;
>  			fixlen = ip->i_size;
>  		}
> -	} else {
> -		prealloced = 0;
> -		fixlen = 1LL << 32;
>  	}
>  
>  	if (bmv->bmv_length == -1) {
>  		fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
> -		bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
> -					(__int64_t)0);
> -	} else if (bmv->bmv_length < 0)
> -		return XFS_ERROR(EINVAL);
> -	if (bmv->bmv_length == 0) {
> +		bmv->bmv_length =
> +			max_t(__int64_t, fixlen - bmv->bmv_offset, 0);
> +	} else if (bmv->bmv_length == 0) {
>  		bmv->bmv_entries = 0;
>  		return 0;
> +	} else if (bmv->bmv_length < 0) {
> +		return XFS_ERROR(EINVAL);
>  	}
> +
>  	nex = bmv->bmv_count - 1;
>  	if (nex <= 0)
>  		return XFS_ERROR(EINVAL);
>  	bmvend = bmv->bmv_offset + bmv->bmv_length;
>  
>  	xfs_ilock(ip, XFS_IOLOCK_SHARED);
> -
> -	if (((iflags & BMV_IF_DELALLOC) == 0) &&
> -	    (whichfork == XFS_DATA_FORK) &&
> -	    (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
> -		/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
> -		error = xfs_flush_pages(ip, (xfs_off_t)0,
> -					       -1, 0, FI_REMAPF);
> -		if (error) {
> -			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> -		return error;
> +	if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
> +		if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) {
> +			error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF);
> +			if (error)
> +				goto out_unlock_iolock;
>  		}
> -	}
>  
> -	ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
> -	       ip->i_delayed_blks == 0);
> +		ASSERT(ip->i_delayed_blks == 0);
> +	}
>  
>  	lock = xfs_ilock_map_shared(ip);
>  
> @@ -5972,23 +5968,24 @@ xfs_getbmap(
>  	if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
>  		nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
>  
> -	bmapi_flags = xfs_bmapi_aflag(whichfork) |
> -			((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
> +	bmapi_flags = xfs_bmapi_aflag(whichfork);
> +	if (!(iflags & BMV_IF_PREALLOC))
> +		bmapi_flags |= XFS_BMAPI_IGSTATE;
>  
>  	/*
>  	 * Allocate enough space to handle "subnex" maps at a time.
>  	 */
>  	subnex = 16;
> -	map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
> +	map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL);
> +	if (!map)
> +		goto out_unlock_ilock;
>  
>  	bmv->bmv_entries = 0;
>  
> -	if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
> -		if (((iflags & BMV_IF_DELALLOC) == 0) ||
> -		    whichfork == XFS_ATTR_FORK) {
> -			error = 0;
> -			goto unlock_and_return;
> -		}
> +	if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 &&
> +	    (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) {
> +		error = 0;
> +		goto out_free_map;
>  	}
>  
>  	nexleft = nex;
> @@ -6000,10 +5997,12 @@ xfs_getbmap(
>  				  bmapi_flags, NULL, 0, map, &nmap,
>  				  NULL, NULL);
>  		if (error)
> -			goto unlock_and_return;
> +			goto out_free_map;
>  		ASSERT(nmap <= subnex);
>  
>  		for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
> +			int full = 0;	/* user array is full */
> +
>  			out.bmv_oflags = 0;
>  			if (map[i].br_state == XFS_EXT_UNWRITTEN)
>  				out.bmv_oflags |= BMV_OF_PREALLOC;
> @@ -6018,36 +6017,32 @@ xfs_getbmap(
>  			    whichfork == XFS_ATTR_FORK) {
>  				/* came to the end of attribute fork */
>  				out.bmv_oflags |= BMV_OF_LAST;
> -				goto unlock_and_return;
> -			} else {
> -				int full = 0;	/* user array is full */
> -
> -				if (!xfs_getbmapx_fix_eof_hole(ip, &out,
> -							prealloced, bmvend,
> -							map[i].br_startblock)) {
> -					goto unlock_and_return;
> -				}
> -
> -				/* format results & advance arg */
> -				error = formatter(&arg, &out, &full);
> -				if (error || full)
> -					goto unlock_and_return;
> -				nexleft--;
> -				bmv->bmv_offset =
> -					out.bmv_offset + out.bmv_length;
> -				bmv->bmv_length = MAX((__int64_t)0,
> -					(__int64_t)(bmvend - bmv->bmv_offset));
> -				bmv->bmv_entries++;
> +				goto out_free_map;
>  			}
> +
> +			if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced,
> +					bmvend, map[i].br_startblock))
> +				goto out_free_map;
> +
> +			/* format results & advance arg */
> +			error = formatter(&arg, &out, &full);
> +			if (error || full)
> +				goto out_free_map;
> +			nexleft--;
> +			bmv->bmv_offset =
> +				out.bmv_offset + out.bmv_length;
> +			bmv->bmv_length =
> +				max_t(__int64_t, 0, bmvend - bmv->bmv_offset);
> +			bmv->bmv_entries++;
>  		}
>  	} while (nmap && nexleft && bmv->bmv_length);
>  
> -unlock_and_return:
> + out_free_map:
> +	kmem_free(map);
> + out_unlock_ilock:
>  	xfs_iunlock_map_shared(ip, lock);
> + out_unlock_iolock:
>  	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> -
> -	kmem_free(map);
> -
>  	return error;
>  }
>  
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
> 

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-02-24 13:38 [PATCH 1/2] xfs: a couple getbmap cleanups Christoph Hellwig
  2009-03-16  6:30 ` Christoph Hellwig
  2009-04-06 23:10 ` Eric Sandeen
@ 2009-04-07  0:57 ` Felix Blyakher
  2009-04-09 17:11   ` Christoph Hellwig
  2 siblings, 1 reply; 10+ messages in thread
From: Felix Blyakher @ 2009-04-07  0:57 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs


On Feb 24, 2009, at 7:38 AM, Christoph Hellwig wrote:

> - reshuffle various conditionals for data vs attr fork to make the  
> code
>   more readable
> - do fine-grainded goto-based error handling
> - exit early from conditionals instead of keeping a long else branch
>   around
> - allow kmem_alloc to fail
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
>
> Index: xfs/fs/xfs/xfs_bmap.c
> ===================================================================
> --- xfs.orig/fs/xfs/xfs_bmap.c	2009-02-23 18:08:35.352924726 +0100
> +++ xfs/fs/xfs/xfs_bmap.c	2009-02-23 18:23:49.527051836 +0100
> @@ -5857,7 +5857,7 @@ xfs_getbmap(
> 	void			*arg)		/* formatter arg */
> {
> 	__int64_t		bmvend;		/* last block requested */
> -	int			error;		/* return value */
> +	int			error = 0;	/* return value */
> 	__int64_t		fixlen;		/* length for -1 case */
> 	int			i;		/* extent number */
> 	int			lock;		/* lock state */
> @@ -5876,30 +5876,8 @@ xfs_getbmap(
>
> 	mp = ip->i_mount;
> 	iflags = bmv->bmv_iflags;
> -
> 	whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
>
> -	/*	If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
> -	 *	generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
> -	 *	bit is set for the file, generate a read event in order
> -	 *	that the DMAPI application may do its thing before we return
> -	 *	the extents.  Usually this means restoring user file data to
> -	 *	regions of the file that look like holes.
> -	 *
> -	 *	The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> -	 *	BMV_IF_NO_DMAPI_READ so that read events are generated.
> -	 *	If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
> -	 *	could misinterpret holes in a DMAPI file as true holes,
> -	 *	when in fact they may represent offline user data.
> -	 */
> -	if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
> -	    DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> -	    whichfork == XFS_DATA_FORK) {
> -		error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
> -		if (error)
> -			return XFS_ERROR(error);
> -	}
> -
> 	if (whichfork == XFS_ATTR_FORK) {
> 		if (XFS_IFORK_Q(ip)) {
> 			if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
> @@ -5913,11 +5891,37 @@ xfs_getbmap(
> 					 ip->i_mount);
> 			return XFS_ERROR(EFSCORRUPTED);
> 		}
> -	} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> -		   ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> -		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> -		return XFS_ERROR(EINVAL);
> -	if (whichfork == XFS_DATA_FORK) {
> +
> +		prealloced = 0;
> +		fixlen = 1LL << 32;
> +	} else {
> +		/*
> +		 * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
> +		 * not generate a DMAPI read event.  Otherwise, if the
> +		 * DM_EVENT_READ bit is set for the file, generate a read
> +		 * event in order that the DMAPI application may do its thing
> +		 * before we return the extents.  Usually this means restoring
> +		 * user file data to regions of the file that look like holes.
> +		 *
> +		 * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
> +		 * BMV_IF_NO_DMAPI_READ so that read events are generated.
> +		 * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
> +		 * could misinterpret holes in a DMAPI file as true holes,
> +		 * when in fact they may represent offline user data.
> +		 */
> +		if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
> +		    !(iflags & BMV_IF_NO_DMAPI_READ)) {
> +			error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
> +					      0, 0, 0, NULL);
> +			if (error)
> +				return XFS_ERROR(error);
> +		}
> +
> +		if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> +		    ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
> +		    ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
> +			return XFS_ERROR(EINVAL);
> +
> 		if (xfs_get_extsz_hint(ip) ||
> 		    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
> 			prealloced = 1;
> @@ -5926,42 +5930,34 @@ xfs_getbmap(
> 			prealloced = 0;
> 			fixlen = ip->i_size;
> 		}
> -	} else {
> -		prealloced = 0;
> -		fixlen = 1LL << 32;
> 	}
>
> 	if (bmv->bmv_length == -1) {
> 		fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
> -		bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
> -					(__int64_t)0);
> -	} else if (bmv->bmv_length < 0)
> -		return XFS_ERROR(EINVAL);
> -	if (bmv->bmv_length == 0) {
> +		bmv->bmv_length =
> +			max_t(__int64_t, fixlen - bmv->bmv_offset, 0);
> +	} else if (bmv->bmv_length == 0) {
> 		bmv->bmv_entries = 0;
> 		return 0;
> +	} else if (bmv->bmv_length < 0) {
> +		return XFS_ERROR(EINVAL);
> 	}
> +
> 	nex = bmv->bmv_count - 1;
> 	if (nex <= 0)
> 		return XFS_ERROR(EINVAL);
> 	bmvend = bmv->bmv_offset + bmv->bmv_length;
>
> 	xfs_ilock(ip, XFS_IOLOCK_SHARED);
> -
> -	if (((iflags & BMV_IF_DELALLOC) == 0) &&
> -	    (whichfork == XFS_DATA_FORK) &&
> -	    (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
> -		/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
> -		error = xfs_flush_pages(ip, (xfs_off_t)0,
> -					       -1, 0, FI_REMAPF);
> -		if (error) {
> -			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> -		return error;
> +	if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
> +		if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) {
> +			error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF);
> +			if (error)
> +				goto out_unlock_iolock;
> 		}
> -	}
>
> -	ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
> -	       ip->i_delayed_blks == 0);
> +		ASSERT(ip->i_delayed_blks == 0);
> +	}
>
> 	lock = xfs_ilock_map_shared(ip);
>
> @@ -5972,23 +5968,24 @@ xfs_getbmap(
> 	if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
> 		nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
>
> -	bmapi_flags = xfs_bmapi_aflag(whichfork) |
> -			((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
> +	bmapi_flags = xfs_bmapi_aflag(whichfork);
> +	if (!(iflags & BMV_IF_PREALLOC))
> +		bmapi_flags |= XFS_BMAPI_IGSTATE;
>
> 	/*
> 	 * Allocate enough space to handle "subnex" maps at a time.
> 	 */
> 	subnex = 16;
> -	map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
> +	map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL);
> +	if (!map)
> +		goto out_unlock_ilock;

Shouldn't we set error to ENOMEM here?
Should the callers be taught to handle ENOMEM now?

Felix

>
>
> 	bmv->bmv_entries = 0;
>
> -	if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
> -		if (((iflags & BMV_IF_DELALLOC) == 0) ||
> -		    whichfork == XFS_ATTR_FORK) {
> -			error = 0;
> -			goto unlock_and_return;
> -		}
> +	if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 &&
> +	    (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) {
> +		error = 0;
> +		goto out_free_map;
> 	}
>
> 	nexleft = nex;
> @@ -6000,10 +5997,12 @@ xfs_getbmap(
> 				  bmapi_flags, NULL, 0, map, &nmap,
> 				  NULL, NULL);
> 		if (error)
> -			goto unlock_and_return;
> +			goto out_free_map;
> 		ASSERT(nmap <= subnex);
>
> 		for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
> +			int full = 0;	/* user array is full */
> +
> 			out.bmv_oflags = 0;
> 			if (map[i].br_state == XFS_EXT_UNWRITTEN)
> 				out.bmv_oflags |= BMV_OF_PREALLOC;
> @@ -6018,36 +6017,32 @@ xfs_getbmap(
> 			    whichfork == XFS_ATTR_FORK) {
> 				/* came to the end of attribute fork */
> 				out.bmv_oflags |= BMV_OF_LAST;
> -				goto unlock_and_return;
> -			} else {
> -				int full = 0;	/* user array is full */
> -
> -				if (!xfs_getbmapx_fix_eof_hole(ip, &out,
> -							prealloced, bmvend,
> -							map[i].br_startblock)) {
> -					goto unlock_and_return;
> -				}
> -
> -				/* format results & advance arg */
> -				error = formatter(&arg, &out, &full);
> -				if (error || full)
> -					goto unlock_and_return;
> -				nexleft--;
> -				bmv->bmv_offset =
> -					out.bmv_offset + out.bmv_length;
> -				bmv->bmv_length = MAX((__int64_t)0,
> -					(__int64_t)(bmvend - bmv->bmv_offset));
> -				bmv->bmv_entries++;
> +				goto out_free_map;
> 			}
> +
> +			if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced,
> +					bmvend, map[i].br_startblock))
> +				goto out_free_map;
> +
> +			/* format results & advance arg */
> +			error = formatter(&arg, &out, &full);
> +			if (error || full)
> +				goto out_free_map;
> +			nexleft--;
> +			bmv->bmv_offset =
> +				out.bmv_offset + out.bmv_length;
> +			bmv->bmv_length =
> +				max_t(__int64_t, 0, bmvend - bmv->bmv_offset);
> +			bmv->bmv_entries++;
> 		}
> 	} while (nmap && nexleft && bmv->bmv_length);
>
> -unlock_and_return:
> + out_free_map:
> +	kmem_free(map);
> + out_unlock_ilock:
> 	xfs_iunlock_map_shared(ip, lock);
> + out_unlock_iolock:
> 	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> -
> -	kmem_free(map);
> -
> 	return error;
> }
>
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-04-07  0:57 ` Felix Blyakher
@ 2009-04-09 17:11   ` Christoph Hellwig
  2009-04-29 14:40     ` Felix Blyakher
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2009-04-09 17:11 UTC (permalink / raw)
  To: Felix Blyakher; +Cc: Christoph Hellwig, xfs

On Mon, Apr 06, 2009 at 07:57:48PM -0500, Felix Blyakher wrote:
> Shouldn't we set error to ENOMEM here?

Yes, good catch.

> Should the callers be taught to handle ENOMEM now?

The kernel callchain handles it, and in userspace the only caller
(xfs_io) will handled it by printing an out of memory message.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-04-09 17:11   ` Christoph Hellwig
@ 2009-04-29 14:40     ` Felix Blyakher
  2009-04-29 14:50       ` Christoph Hellwig
  0 siblings, 1 reply; 10+ messages in thread
From: Felix Blyakher @ 2009-04-29 14:40 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs


On Apr 9, 2009, at 12:11 PM, Christoph Hellwig wrote:

> On Mon, Apr 06, 2009 at 07:57:48PM -0500, Felix Blyakher wrote:
>> Shouldn't we set error to ENOMEM here?
>
> Yes, good catch.

Christoph, do you want to repost this patch with that change?

Thanks,
Felix

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-04-29 14:40     ` Felix Blyakher
@ 2009-04-29 14:50       ` Christoph Hellwig
  2009-04-29 15:02         ` Felix Blyakher
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2009-04-29 14:50 UTC (permalink / raw)
  To: Felix Blyakher; +Cc: Christoph Hellwig, xfs

[-- Attachment #1: Type: text/plain, Size: 426 bytes --]

On Wed, Apr 29, 2009 at 09:40:40AM -0500, Felix Blyakher wrote:
>
> On Apr 9, 2009, at 12:11 PM, Christoph Hellwig wrote:
>
>> On Mon, Apr 06, 2009 at 07:57:48PM -0500, Felix Blyakher wrote:
>>> Shouldn't we set error to ENOMEM here?
>>
>> Yes, good catch.
>
> Christoph, do you want to repost this patch with that change?

Yeah, I added it long ago.  Below is the updated version.  I've been
running xfsqa on it quite a bit.

[-- Attachment #2: xfs-getbmap-cleanups --]
[-- Type: text/plain, Size: 8182 bytes --]

Subject: xfs: a couple getbmap cleanups  
From: Christoph Hellwig <hch@lst.de>

 - reshuffle various conditionals for data vs attr fork to make the code
   more readable
 - do fine-grainded goto-based error handling
 - exit early from conditionals instead of keeping a long else branch around
 - allow kmem_alloc to fail 

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Eric Sandeen <sandeen@sandeen.net>

Index: xfs/fs/xfs/xfs_bmap.c
===================================================================
--- xfs.orig/fs/xfs/xfs_bmap.c	2009-04-06 18:39:17.952445045 +0200
+++ xfs/fs/xfs/xfs_bmap.c	2009-04-09 19:07:46.764452348 +0200
@@ -5880,7 +5880,7 @@ xfs_getbmap(
 	void			*arg)		/* formatter arg */
 {
 	__int64_t		bmvend;		/* last block requested */
-	int			error;		/* return value */
+	int			error = 0;	/* return value */
 	__int64_t		fixlen;		/* length for -1 case */
 	int			i;		/* extent number */
 	int			lock;		/* lock state */
@@ -5899,30 +5899,8 @@ xfs_getbmap(
 
 	mp = ip->i_mount;
 	iflags = bmv->bmv_iflags;
-
 	whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
 
-	/*	If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
-	 *	generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
-	 *	bit is set for the file, generate a read event in order
-	 *	that the DMAPI application may do its thing before we return
-	 *	the extents.  Usually this means restoring user file data to
-	 *	regions of the file that look like holes.
-	 *
-	 *	The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
-	 *	BMV_IF_NO_DMAPI_READ so that read events are generated.
-	 *	If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
-	 *	could misinterpret holes in a DMAPI file as true holes,
-	 *	when in fact they may represent offline user data.
-	 */
-	if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
-	    DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
-	    whichfork == XFS_DATA_FORK) {
-		error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
-		if (error)
-			return XFS_ERROR(error);
-	}
-
 	if (whichfork == XFS_ATTR_FORK) {
 		if (XFS_IFORK_Q(ip)) {
 			if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
@@ -5936,11 +5914,37 @@ xfs_getbmap(
 					 ip->i_mount);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
-	} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
-		   ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
-		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
-		return XFS_ERROR(EINVAL);
-	if (whichfork == XFS_DATA_FORK) {
+
+		prealloced = 0;
+		fixlen = 1LL << 32;
+	} else {
+		/*
+		 * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
+		 * not generate a DMAPI read event.  Otherwise, if the
+		 * DM_EVENT_READ bit is set for the file, generate a read
+		 * event in order that the DMAPI application may do its thing
+		 * before we return the extents.  Usually this means restoring
+		 * user file data to regions of the file that look like holes.
+		 *
+		 * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
+		 * BMV_IF_NO_DMAPI_READ so that read events are generated.
+		 * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
+		 * could misinterpret holes in a DMAPI file as true holes,
+		 * when in fact they may represent offline user data.
+		 */
+		if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
+		    !(iflags & BMV_IF_NO_DMAPI_READ)) {
+			error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
+					      0, 0, 0, NULL);
+			if (error)
+				return XFS_ERROR(error);
+		}
+
+		if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
+		    ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
+		    ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
+			return XFS_ERROR(EINVAL);
+
 		if (xfs_get_extsz_hint(ip) ||
 		    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
 			prealloced = 1;
@@ -5949,42 +5953,34 @@ xfs_getbmap(
 			prealloced = 0;
 			fixlen = ip->i_size;
 		}
-	} else {
-		prealloced = 0;
-		fixlen = 1LL << 32;
 	}
 
 	if (bmv->bmv_length == -1) {
 		fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
-		bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
-					(__int64_t)0);
-	} else if (bmv->bmv_length < 0)
-		return XFS_ERROR(EINVAL);
-	if (bmv->bmv_length == 0) {
+		bmv->bmv_length =
+			max_t(__int64_t, fixlen - bmv->bmv_offset, 0);
+	} else if (bmv->bmv_length == 0) {
 		bmv->bmv_entries = 0;
 		return 0;
+	} else if (bmv->bmv_length < 0) {
+		return XFS_ERROR(EINVAL);
 	}
+
 	nex = bmv->bmv_count - 1;
 	if (nex <= 0)
 		return XFS_ERROR(EINVAL);
 	bmvend = bmv->bmv_offset + bmv->bmv_length;
 
 	xfs_ilock(ip, XFS_IOLOCK_SHARED);
-
-	if (((iflags & BMV_IF_DELALLOC) == 0) &&
-	    (whichfork == XFS_DATA_FORK) &&
-	    (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
-		/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
-		error = xfs_flush_pages(ip, (xfs_off_t)0,
-					       -1, 0, FI_REMAPF);
-		if (error) {
-			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-		return error;
+	if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
+		if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) {
+			error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF);
+			if (error)
+				goto out_unlock_iolock;
 		}
-	}
 
-	ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
-	       ip->i_delayed_blks == 0);
+		ASSERT(ip->i_delayed_blks == 0);
+	}
 
 	lock = xfs_ilock_map_shared(ip);
 
@@ -5995,23 +5991,25 @@ xfs_getbmap(
 	if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
 		nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
 
-	bmapi_flags = xfs_bmapi_aflag(whichfork) |
-			((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
+	bmapi_flags = xfs_bmapi_aflag(whichfork);
+	if (!(iflags & BMV_IF_PREALLOC))
+		bmapi_flags |= XFS_BMAPI_IGSTATE;
 
 	/*
 	 * Allocate enough space to handle "subnex" maps at a time.
 	 */
+	error = ENOMEM;
 	subnex = 16;
-	map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
+	map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL);
+	if (!map)
+		goto out_unlock_ilock;
 
 	bmv->bmv_entries = 0;
 
-	if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
-		if (((iflags & BMV_IF_DELALLOC) == 0) ||
-		    whichfork == XFS_ATTR_FORK) {
-			error = 0;
-			goto unlock_and_return;
-		}
+	if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 &&
+	    (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) {
+		error = 0;
+		goto out_free_map;
 	}
 
 	nexleft = nex;
@@ -6023,10 +6021,12 @@ xfs_getbmap(
 				  bmapi_flags, NULL, 0, map, &nmap,
 				  NULL, NULL);
 		if (error)
-			goto unlock_and_return;
+			goto out_free_map;
 		ASSERT(nmap <= subnex);
 
 		for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
+			int full = 0;	/* user array is full */
+
 			out.bmv_oflags = 0;
 			if (map[i].br_state == XFS_EXT_UNWRITTEN)
 				out.bmv_oflags |= BMV_OF_PREALLOC;
@@ -6041,36 +6041,32 @@ xfs_getbmap(
 			    whichfork == XFS_ATTR_FORK) {
 				/* came to the end of attribute fork */
 				out.bmv_oflags |= BMV_OF_LAST;
-				goto unlock_and_return;
-			} else {
-				int full = 0;	/* user array is full */
-
-				if (!xfs_getbmapx_fix_eof_hole(ip, &out,
-							prealloced, bmvend,
-							map[i].br_startblock)) {
-					goto unlock_and_return;
-				}
-
-				/* format results & advance arg */
-				error = formatter(&arg, &out, &full);
-				if (error || full)
-					goto unlock_and_return;
-				nexleft--;
-				bmv->bmv_offset =
-					out.bmv_offset + out.bmv_length;
-				bmv->bmv_length = MAX((__int64_t)0,
-					(__int64_t)(bmvend - bmv->bmv_offset));
-				bmv->bmv_entries++;
+				goto out_free_map;
 			}
+
+			if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced,
+					bmvend, map[i].br_startblock))
+				goto out_free_map;
+
+			/* format results & advance arg */
+			error = formatter(&arg, &out, &full);
+			if (error || full)
+				goto out_free_map;
+			nexleft--;
+			bmv->bmv_offset =
+				out.bmv_offset + out.bmv_length;
+			bmv->bmv_length =
+				max_t(__int64_t, 0, bmvend - bmv->bmv_offset);
+			bmv->bmv_entries++;
 		}
 	} while (nmap && nexleft && bmv->bmv_length);
 
-unlock_and_return:
+ out_free_map:
+	kmem_free(map);
+ out_unlock_ilock:
 	xfs_iunlock_map_shared(ip, lock);
+ out_unlock_iolock:
 	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-
-	kmem_free(map);
-
 	return error;
 }
 

[-- Attachment #3: Type: text/plain, Size: 121 bytes --]

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-04-29 14:50       ` Christoph Hellwig
@ 2009-04-29 15:02         ` Felix Blyakher
  2009-04-29 15:04           ` Christoph Hellwig
  0 siblings, 1 reply; 10+ messages in thread
From: Felix Blyakher @ 2009-04-29 15:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs


On Apr 29, 2009, at 9:50 AM, Christoph Hellwig wrote:

> On Wed, Apr 29, 2009 at 09:40:40AM -0500, Felix Blyakher wrote:
>>
>> On Apr 9, 2009, at 12:11 PM, Christoph Hellwig wrote:
>>
>>> On Mon, Apr 06, 2009 at 07:57:48PM -0500, Felix Blyakher wrote:
>>>> Shouldn't we set error to ENOMEM here?
>>>
>>> Yes, good catch.
>>
>> Christoph, do you want to repost this patch with that change?
>
> Yeah, I added it long ago.

I must have missed your updated patch.

> Below is the updated version.  I've been
> running xfsqa on it quite a bit.

Applied to the tree.
Thanks,
Felix

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] xfs: a couple getbmap cleanups
  2009-04-29 15:02         ` Felix Blyakher
@ 2009-04-29 15:04           ` Christoph Hellwig
  0 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2009-04-29 15:04 UTC (permalink / raw)
  To: Felix Blyakher; +Cc: Christoph Hellwig, xfs

On Wed, Apr 29, 2009 at 10:02:11AM -0500, Felix Blyakher wrote:
>> Yeah, I added it long ago.
>
> I must have missed your updated patch.

Not sure I actually sent it out, but it's been tested in my local tree
at least :)

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-04-29 15:04 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-24 13:38 [PATCH 1/2] xfs: a couple getbmap cleanups Christoph Hellwig
2009-03-16  6:30 ` Christoph Hellwig
2009-03-29  7:44   ` Christoph Hellwig
2009-04-06 23:10 ` Eric Sandeen
2009-04-07  0:57 ` Felix Blyakher
2009-04-09 17:11   ` Christoph Hellwig
2009-04-29 14:40     ` Felix Blyakher
2009-04-29 14:50       ` Christoph Hellwig
2009-04-29 15:02         ` Felix Blyakher
2009-04-29 15:04           ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox