Re: SG_BIG_BUFF, glibc 2.1 weirdness ...

Douglas Gilbert (dgilbert@interlog.com)
Thu, 02 Sep 1999 11:05:39 -0400

abel deuring wrote:
>
> Hi Andreas!
>
> [snip, discussion about SG_BIG_BUFF in Linux]
>
> > > + ioctl(fd, SG_SET_RESERVED_SIZE, &ioctl_val);
> > > + if (0 == ioctl(fd, SG_GET_RESERVED_SIZE, &ioctl_val))
> > > + sanei_scsi_max_request_size = ioctl_val;
> >
> > What exactly happens when the set fails ? Downgrade to maximum possible
> > value, or keep default ?
>
> Don't ask me -- the idea of the get call is to retrieve the actual
> buffer size. We should ask Douglas for the exact behaviour. (BTW, it
> seems that an "else" for the "get" call is missing: if it fails,
> sanei_scsi_open should return an error.)

The SG_SET_RESERVED_SIZE ioctl() fails in only a few
"special cases":
- the reserved buffer is currently in use (EBUSY)
- user doesn't have write permission on device (EACCESS)
- bad pointer given as 3rd argument to ioctl()

Otherwise it will try and obtain the requested amount of
memory for the "reserved buffer" and if that fails, halve
the requested amount and try again. When the requested
amount drops below PAGE_SIZE (4KB on i386) it gives up
and sets the reserved buffer size to 0. If the ioctl()
gets past the above 3 "special cases" then it returns 0.

So with this type of algorithm, it becomes important to call
SG_GET_RESERVED_SIZE after the "SET" to see how much was
actually allocated. Perhaps this should be made clearer in
my documentation.

Note that even if the reserved buffer size is 0 (or lower
than requested) it may still be possible to do a write()
without a ENOMEM if there is enough memory about when the
write() is executed. On the other hand, there is only one
reserved buffer per file descriptor so when it is taken
(eg during command queuing) then ENOMEM errors are possible
from subsequent queued write()s.

Doug Gilbert

--
Source code, list archive, and docs: http://www.mostang.com/sane/
To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com