public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Introduce SEEK_DATA/SEEK_HOLE support v9
@ 2012-05-10 13:29 Jeff Liu
  2012-05-10 19:51 ` Mark Tinguely
  0 siblings, 1 reply; 5+ messages in thread
From: Jeff Liu @ 2012-05-10 13:29 UTC (permalink / raw)
  To: xfs; +Cc: Christoph Hellwig, Ben Myers, Mark Tinguely, Chris Mason

Hello,

This is the revised patch according to Mark's comments.
Is it possible to get it to accept if there are no other issues,
so that I can continue to work on the unwritten part based on that.

Thanks,
-Jeff

Signed-off-by: Jie Liu <jeff.liu@oracle.com>

---
 fs/xfs/xfs_file.c |  143 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 142 insertions(+), 1 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 54a67dd..b6ddc6f 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1007,8 +1007,149 @@ xfs_vm_page_mkwrite(
 	return block_page_mkwrite(vma, vmf, xfs_get_blocks);
 }
 
+STATIC loff_t
+xfs_seek_data(
+	struct file		*file,
+	loff_t			start,
+	u32			type)
+{
+	struct inode		*inode = file->f_mapping->host;
+	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_mount	*mp = ip->i_mount;
+	struct xfs_bmbt_irec	map[2];
+	int			nmap = 2;
+	loff_t			uninitialized_var(offset);
+	xfs_fsize_t		isize;
+	xfs_fileoff_t		fsbno;
+	xfs_filblks_t		end;
+	uint			lock;
+	int			error;
+
+	lock = xfs_ilock_map_shared(ip);
+
+	isize = i_size_read(inode);
+	if (start >= isize) {
+		error = ENXIO;
+		goto out_unlock;
+	}
+
+	fsbno = XFS_B_TO_FSBT(mp, start);
+
+	/*
+	 * Try to read extents from the first block indicated
+	 * by fsbno to the end block of the file.
+	 */
+	end = XFS_B_TO_FSB(mp, isize);
+
+	error = xfs_bmapi_read(ip, fsbno, end - fsbno, map, &nmap,
+			       XFS_BMAPI_ENTIRE);
+	if (error)
+		goto out_unlock;
+
+	/*
+	 * Treat unwritten extent as data extent since it might
+	 * contains dirty data in page cache.
+	 */
+	if (map[0].br_startblock != HOLESTARTBLOCK) {
+		offset = max_t(loff_t, start,
+			       XFS_FSB_TO_B(mp, map[0].br_startoff));
+	} else {
+		if (nmap == 1) {
+			error = ENXIO;
+			goto out_unlock;
+		}
+
+		offset = max_t(loff_t, start,
+			       XFS_FSB_TO_B(mp, map[1].br_startoff));
+	}
+
+	if (offset != file->f_pos)
+		file->f_pos = offset;
+
+out_unlock:
+	xfs_iunlock_map_shared(ip, lock);
+
+	if (error)
+		return -error;
+	return offset;
+}
+
+STATIC loff_t
+xfs_seek_hole(
+	struct file		*file,
+	loff_t			start,
+	u32			type)
+{
+	struct inode		*inode = file->f_mapping->host;
+	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_mount	*mp = ip->i_mount;
+	loff_t			uninitialized_var(offset);
+	loff_t			holeoff;
+	xfs_fsize_t		isize;
+	xfs_fileoff_t		fsbno;
+	uint			lock;
+	int			error;
+
+	if (XFS_FORCED_SHUTDOWN(mp))
+		return -XFS_ERROR(EIO);
+
+	lock = xfs_ilock_map_shared(ip);
+
+	isize = i_size_read(inode);
+	if (start >= isize) {
+		error = ENXIO;
+		goto out_unlock;
+	}
+
+	fsbno = XFS_B_TO_FSBT(mp, start);
+	error = xfs_bmap_first_unused(NULL, ip, 1, &fsbno, XFS_DATA_FORK);
+	if (error)
+		goto out_unlock;
+
+	holeoff = XFS_FSB_TO_B(mp, fsbno);
+	if (holeoff <= start)
+		offset = start;
+	else {
+		/*
+		 * xfs_bmap_first_unused() could return a value bigger than
+		 * isize if there are no more holes past the supplied offset.
+		 */
+		offset = min_t(loff_t, holeoff, isize);
+	}
+
+	if (offset != file->f_pos)
+		file->f_pos = offset;
+
+out_unlock:
+	xfs_iunlock_map_shared(ip, lock);
+
+	if (error)
+		return -error;
+	return offset;
+}
+
+STATIC loff_t
+xfs_file_llseek(
+	struct file	*file,
+	loff_t		offset,
+	int		origin)
+{
+	switch (origin) {
+	case SEEK_END:
+	case SEEK_CUR:
+	case SEEK_SET:
+		return generic_file_llseek(file, offset, origin);
+	case SEEK_DATA:
+		return xfs_seek_data(file, offset, origin);
+	case SEEK_HOLE:
+		return xfs_seek_hole(file, offset, origin);
+	default:
+		return -EINVAL;
+	}
+}
+
 const struct file_operations xfs_file_operations = {
-	.llseek		= generic_file_llseek,
+	.llseek		= xfs_file_llseek,
 	.read		= do_sync_read,
 	.write		= do_sync_write,
 	.aio_read	= xfs_file_aio_read,
-- 
1.7.9

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

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

* Re: [PATCH] Introduce SEEK_DATA/SEEK_HOLE support v9
  2012-05-10 13:29 [PATCH] Introduce SEEK_DATA/SEEK_HOLE support v9 Jeff Liu
@ 2012-05-10 19:51 ` Mark Tinguely
  2012-05-10 20:08   ` Ben Myers
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Tinguely @ 2012-05-10 19:51 UTC (permalink / raw)
  To: jeff.liu; +Cc: Ben Myers, xfs

On 05/10/12 08:29, Jeff Liu wrote:
> Hello,
>
> This is the revised patch according to Mark's comments.
> Is it possible to get it to accept if there are no other issues,
> so that I can continue to work on the unwritten part based on that.
>
> Thanks,
> -Jeff
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
>
> ---

> +
> +STATIC loff_t
> +xfs_seek_hole(
> +	struct file		*file,
> +	loff_t			start,
> +	u32			type)
> +{
> +	struct inode		*inode = file->f_mapping->host;
> +	struct xfs_inode	*ip = XFS_I(inode);
> +	struct xfs_mount	*mp = ip->i_mount;
> +	loff_t			uninitialized_var(offset);
> +	loff_t			holeoff;
> +	xfs_fsize_t		isize;
> +	xfs_fileoff_t		fsbno;
> +	uint			lock;
> +	int			error;
> +
> +	if (XFS_FORCED_SHUTDOWN(mp))
> +		return -XFS_ERROR(EIO);

I think xfs_bmapi_read() returns just a XFS_ERROR(EIO), not negative.
Ben can fix up if you agree.

Other than that it is a great feature to in XFS.

Reviewed-by: Mark Tinguely <tinguely@sgi.com>

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

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

* Re: [PATCH] Introduce SEEK_DATA/SEEK_HOLE support v9
  2012-05-10 20:08   ` Ben Myers
@ 2012-05-10 20:07     ` Mark Tinguely
  2012-05-10 20:28     ` Mark Tinguely
  1 sibling, 0 replies; 5+ messages in thread
From: Mark Tinguely @ 2012-05-10 20:07 UTC (permalink / raw)
  To: Ben Myers; +Cc: jeff.liu, xfs

On 05/10/12 15:08, Ben Myers wrote:
> On Thu, May 10, 2012 at 02:51:15PM -0500, Mark Tinguely wrote:
>> On 05/10/12 08:29, Jeff Liu wrote:
>>> Hello,
>>>
>>> This is the revised patch according to Mark's comments.
>>> Is it possible to get it to accept if there are no other issues,
>>> so that I can continue to work on the unwritten part based on that.
>>>
>>> Thanks,
>>> -Jeff
>>>
>>> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
>>>
>>> ---
>>
>>> +
>>> +STATIC loff_t
>>> +xfs_seek_hole(
>>> +	struct file		*file,
>>> +	loff_t			start,
>>> +	u32			type)
>>> +{
>>> +	struct inode		*inode = file->f_mapping->host;
>>> +	struct xfs_inode	*ip = XFS_I(inode);
>>> +	struct xfs_mount	*mp = ip->i_mount;
>>> +	loff_t			uninitialized_var(offset);
>>> +	loff_t			holeoff;
>>> +	xfs_fsize_t		isize;
>>> +	xfs_fileoff_t		fsbno;
>>> +	uint			lock;
>>> +	int			error;
>>> +
>>> +	if (XFS_FORCED_SHUTDOWN(mp))
>>> +		return -XFS_ERROR(EIO);
>>
>> I think xfs_bmapi_read() returns just a XFS_ERROR(EIO), not negative.
>> Ben can fix up if you agree.
>
> Looks like error is negated at the bottom of the function and is not a problem.
>

Yes, but xfs_seek_data() also negates at the error at the end of the 
routine. They should be consistent.

--Mark.

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

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

* Re: [PATCH] Introduce SEEK_DATA/SEEK_HOLE support v9
  2012-05-10 19:51 ` Mark Tinguely
@ 2012-05-10 20:08   ` Ben Myers
  2012-05-10 20:07     ` Mark Tinguely
  2012-05-10 20:28     ` Mark Tinguely
  0 siblings, 2 replies; 5+ messages in thread
From: Ben Myers @ 2012-05-10 20:08 UTC (permalink / raw)
  To: Mark Tinguely; +Cc: jeff.liu, xfs

On Thu, May 10, 2012 at 02:51:15PM -0500, Mark Tinguely wrote:
> On 05/10/12 08:29, Jeff Liu wrote:
> >Hello,
> >
> >This is the revised patch according to Mark's comments.
> >Is it possible to get it to accept if there are no other issues,
> >so that I can continue to work on the unwritten part based on that.
> >
> >Thanks,
> >-Jeff
> >
> >Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> >
> >---
> 
> >+
> >+STATIC loff_t
> >+xfs_seek_hole(
> >+	struct file		*file,
> >+	loff_t			start,
> >+	u32			type)
> >+{
> >+	struct inode		*inode = file->f_mapping->host;
> >+	struct xfs_inode	*ip = XFS_I(inode);
> >+	struct xfs_mount	*mp = ip->i_mount;
> >+	loff_t			uninitialized_var(offset);
> >+	loff_t			holeoff;
> >+	xfs_fsize_t		isize;
> >+	xfs_fileoff_t		fsbno;
> >+	uint			lock;
> >+	int			error;
> >+
> >+	if (XFS_FORCED_SHUTDOWN(mp))
> >+		return -XFS_ERROR(EIO);
> 
> I think xfs_bmapi_read() returns just a XFS_ERROR(EIO), not negative.
> Ben can fix up if you agree.

Looks like error is negated at the bottom of the function and is not a problem.

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

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

* Re: [PATCH] Introduce SEEK_DATA/SEEK_HOLE support v9
  2012-05-10 20:08   ` Ben Myers
  2012-05-10 20:07     ` Mark Tinguely
@ 2012-05-10 20:28     ` Mark Tinguely
  1 sibling, 0 replies; 5+ messages in thread
From: Mark Tinguely @ 2012-05-10 20:28 UTC (permalink / raw)
  To: Ben Myers; +Cc: jeff.liu, xfs-oss

On 05/10/12 15:08, Ben Myers wrote:
> On Thu, May 10, 2012 at 02:51:15PM -0500, Mark Tinguely wrote:
>> On 05/10/12 08:29, Jeff Liu wrote:
>>> Hello,
>>>
>>> This is the revised patch according to Mark's comments.
>>> Is it possible to get it to accept if there are no other issues,
>>> so that I can continue to work on the unwritten part based on that.
>>>
>>> Thanks,
>>> -Jeff
>>>
>>> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
>>>
>>> ---
>>
>>> +
>>> +STATIC loff_t
>>> +xfs_seek_hole(
>>> +	struct file		*file,
>>> +	loff_t			start,
>>> +	u32			type)
>>> +{
>>> +	struct inode		*inode = file->f_mapping->host;
>>> +	struct xfs_inode	*ip = XFS_I(inode);
>>> +	struct xfs_mount	*mp = ip->i_mount;
>>> +	loff_t			uninitialized_var(offset);
>>> +	loff_t			holeoff;
>>> +	xfs_fsize_t		isize;
>>> +	xfs_fileoff_t		fsbno;
>>> +	uint			lock;
>>> +	int			error;
>>> +
>>> +	if (XFS_FORCED_SHUTDOWN(mp))
>>> +		return -XFS_ERROR(EIO);
>>
>> I think xfs_bmapi_read() returns just a XFS_ERROR(EIO), not negative.
>> Ben can fix up if you agree.
>
> Looks like error is negated at the bottom of the function and is not a problem.

oooooooh, it is a *return* not a *goto* because we are above the lock.

sorry for the noise.

Mark Tinguely.

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

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

end of thread, other threads:[~2012-05-10 20:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-10 13:29 [PATCH] Introduce SEEK_DATA/SEEK_HOLE support v9 Jeff Liu
2012-05-10 19:51 ` Mark Tinguely
2012-05-10 20:08   ` Ben Myers
2012-05-10 20:07     ` Mark Tinguely
2012-05-10 20:28     ` Mark Tinguely

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