Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Dec 2011 15:43:13 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        arch@freebsd.org
Subject:   Re: Changing lseek() to KNOTE on the vnode when seeking on a file
Message-ID:  <201112141543.14130.jhb@freebsd.org>
In-Reply-To: <20111214165830.GG50300@deviant.kiev.zoral.com.ua>
References:  <201112141141.41168.jhb@freebsd.org> <20111214165830.GG50300@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday, December 14, 2011 11:58:30 am Kostik Belousov wrote:
> On Wed, Dec 14, 2011 at 11:41:41AM -0500, John Baldwin wrote:
> > A co-worker ran into an issue with using an EVFILT_READ kevent on a regular 
> > file recently.  Specifically, in the manpage it says:
> > 
> >      EVFILT_READ    Takes a descriptor as the identifier, and returns whenever
> >                     there is data available to read.  The behavior of the fil-
> >                     ter is slightly different depending on the descriptor
> >                     type.
> > 
> >                     ...
> > 
> >                     Vnodes
> >                         Returns when the file pointer is not at the end of
> >                         file.  data contains the offset from current position
> >                         to end of file, and may be negative.
> > 
> > He was then working on a program that read to EOF, then seeked back into the
> > file.  He was expecting to get a new kevent after seeking back into the file
> > since for his file descriptor after the lseek "there is data available to 
> > read" and "the file pointer is not at the end of file".  I have a patch to fix 
> > this by doing a KNOTE() on a vnode after a successful seek.  I checked OS X 
> > and it looks like they added this to their lseek() in Snow Leopard
> > (http://fxr.watson.org/fxr/source/bsd/vfs/vfs_syscalls.c?v=xnu-1699.24.8#L4182).
> > 
> > The one patch to fix this is below along with a test.  Note that unlike OS X
> > I did not add a new NOTE_NONE for this case.  OS X has logic in their VFS
> > filter operations that make special assumptions about a hint value of 0, so
> > they had to add NOTE_NONE as a hack.  We do not have the same special 
> > assumptions about a hint of 0, so we can just use "0".  Without this fix the
> > test below complains about missing events for the "after seek" and "after 
> > third read" cases.
> 
> Just curious - wouldn't it generate a spurious event if lseek is
> performed with zero offset, e.g. SEEK_CUR with offset 0 ?

Yes, it would, though if you aren't specifying EV_CLEAR and haven't gotten to
EOF yet, then it would already be pending anyway.  In the case of EV_CLEAR
this could cause a new event to fire, yes.  However, judging by OS X's
implementation of lseek(), they would do the same.  Also, you won't get an
event if you are at EOF and merely seek back to EOF.  I suppose we could
check for the case where the new offset == the old one, but I'm not sure it
is a common enough case in conjunction with use of kevents() to really
warrant that?  Note you can already get spurious events on an EVFILT_READ
filter if some other process creates a new link to the file, or does a
chown, chmod, etc.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112141543.14130.jhb>