xfs
[Top] [All Lists]

Re: SEEK_DATA/SEEK_HOLE support

To: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Subject: Re: SEEK_DATA/SEEK_HOLE support
From: Jeff Liu <jeff.liu@xxxxxxxxxx>
Date: Mon, 03 Oct 2011 00:06:37 +0800
Cc: xfs@xxxxxxxxxxx
In-reply-to: <20111002154259.GA14543@xxxxxxxxxxxxx>
Organization: Oracle
References: <4E887D7F.2010306@xxxxxxxxxx> <20111002154259.GA14543@xxxxxxxxxxxxx>
Reply-to: jeff.liu@xxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.18) Gecko/20110617 Thunderbird/3.1.11
Hi Christoph,

Thanks for your prompt response!
On 10/02/2011 11:42 PM, Christoph Hellwig wrote:

> On Sun, Oct 02, 2011 at 11:04:31PM +0800, Jeff Liu wrote:
>> Dear developer,
>>
>> Does anyone already worked on SEEK_DATA/SEEK_HOLE for XFS? I'd like to
>> implement it if not. :)
> 
> Dave mentioned he had a basic implementation, he might have some code
> that you can improve on.
> 
> Did we get consensus about the the semantics of them for unwritten
> extents?  If we want them to be exact in the fact of unwritten extents
> that is going to be the most work, e.g. if we find an unwritten extent
> we'll then have to do a pagecache lookup and check if pages are dirty
> and in that case not treat them as a hole.

IMHO, to avoid data loss in some user application like cp(1), for
unwritten extents, we always need to check the pages status.  Just as
you mentioned above, return the map offset if pages are dirty for
SEEK_DATA, or a hole found.


-Jeff

> 
> The rest of the implementation should be easy, e.g. doing something like
> the following pseudo-code which missed all the proper error codes and
> conversions from the lseek arguments to filesystem blocks and the
> required locking around it:
> 
> 
> seek_hole()
> {
>       xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got,
>                       &prev);
> 
>       for (;;) {
>               if (eof) {
>                       /* past the file, nothing do here */
>                       return;
>               }
> 
>               if (got.br_startoff > bno)
>                       /* found hole, return it */
>                       return;
>               }
> 
>               if (++lastx == ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) {
>                       /* reached EOF */
>                       return;
>               }
>               xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
>       }
> }
> 
> seek_data()
> {
>       xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got,
>                       &prev);
> 
>       for (;;) {
>               if (eof) {
>                       /* past the file, nothing do here */
>                       return;
>               }
> 
>               /* next data extent */
>               return got.br_startoff < bno ? bno : got.br_startof;
>       }
> }
> 
>       


<Prev in Thread] Current Thread [Next in Thread>