[PATCH] add pread operation to vfs layer

Cole, Timothy D. t.cole at ngc.com
Wed Dec 17 16:10:39 GMT 2003

> -----Original Message-----
> From: Stefan Metzmacher [mailto:metze at metzemix.de]
> Sent: Wednesday, December 17, 2003 0:56
> To: James Peach
> Cc: Cole, Timothy D.; samba-technical
> Subject: Re: [PATCH] add pread operation to vfs layer
> It's ugly to test if a function pointer has a specefic value.
> What is when e.g. a  database  opaque  vfs module overloads 
> the pread fn 
> with
> example_pread(vfs_handle_struct *handle,files_struct *f, ...)
> {
>          errno =ENOSYS;
>           return -1;
> }
> (This is what such a module should do)
> So just try SMB_VFS_PREAD and if it fails with ENOSYS try read.
> So no if def's are needed

Ahh... that is a good point.  Probably for systems without pread/pwrite, we
should simply provide sys_pread/sys_pwrite stubs that do nothing more than
fail with ENOSYS.

> if 
> (((readret=SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos))==-1)&&errno==ENOSYS)
>     readret = SMB_VFS_READ(fsp,fsp->fd,data,n);
> }

The problem is that you still need to handle seeking appropriately in that
case.  i.e. that would have to be

if (((readret=SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos))==-1)&&errno==ENOSYS) {
	SMB_OFF_T saved_pos;
	saved_pos = fsp->pos;
	if (fsp->pos != pos) {
		readret = SMB_VFS_LSEEK(fsp,fsp->fd,pos,0);
	if (readret != -1) {
		readret = SMB_VFS_READ(fsp,fsp->fd,data,n);
	if (saved_pos != fsp_pos &&
SMB_VFS_LSEEK(fsp,fsp->fd,saved_pos,0)==-1)) {
		readret = -1;

At least in that case you could leverage the existing files_struct::pos and
save yourself a few lseeks in some cases.  Whether fsp->pos will equal pos
(or saved_pos after the read), often enough to make it worthwhile testing
for them as I've done here is a separate question -- most likely not.

Jeremy raised a good point earlier though -- has anyone verified that using
pread is actually faster on other systems like e.g. Linux?

I know that on Linux the implementations of regular read() and pread() are
very nearly identical -- both call the same pread()-esque (Linux-)VFS op.

>From userspace, pread() still might have an advantage for implementing
pread-ish SMB calls though (are there any?), as extra system calls for the
requisite SMB_VFS_LSEEK()s could never be free (though, compared to some
systems system calls on Linux can still be obscenely cheap).

More information about the samba-technical mailing list