bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/4] sha1sum: use AF_ALG when available


From: Tim Rühsen
Subject: Re: [PATCH 1/4] sha1sum: use AF_ALG when available
Date: Mon, 23 Apr 2018 23:22:04 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

On 23.04.2018 18:52, Matteo Croce wrote:
> On Mon, Apr 23, 2018 at 5:07 PM, Tim Rühsen <address@hidden> wrote:
>> On 04/23/2018 01:17 PM, Matteo Croce wrote:
>>> +#include <config.h>
>>> +
>>> +#include "af_alg.h"
>>> +
>>> +/* from linux/include/linux/fs.h: (INT_MAX & PAGE_MASK) */
>>> +#define MAX_RW_COUNT 0x7FFFF000
>>> +#define BLOCKSIZE 32768
>>> +
>>> +int
>>> +afalg_stream (FILE * stream, void *resblock, const char *alg, int hashlen)
>>> +{
>>> +  struct sockaddr_alg salg = {
>>> +    .salg_family = AF_ALG,
>>> +    .salg_type = "hash",
>>> +  };
>>> +  int ret, cfd, ofd;
>>> +  static char buf[BLOCKSIZE];
>>> +  ssize_t size;
>>> +  struct stat st;
>>> +
>>> +  strcpy((char *)salg.salg_name, alg);
>> Better consider for size of salg.salg_name here.
>>
> Right. Will check it in v2.
>
>>> +  cfd = socket (AF_ALG, SOCK_SEQPACKET, 0);
>>> +  if (cfd < 0)
>>> +      return -EAFNOSUPPORT;
>> What about moving salg initialization here ?
>>
> I think that contextual initialization it's a good trick to fill it
> with zeroes avoiding a memset later.
> What are the advantage of initializing the structure later? The effort
> should be minimal in case of no AF_ALG support.
You are right with the minimal overhead for a single call, but you can
never be sure about corner use cases.
The contextual init is good (though I remember gcc clears all the memory
anyways - so no benefit by no using memset),
and you can also use it after the first code line (C99, which th
econstruct already is).

>>> +  ret = bind (cfd, (struct sockaddr *) &salg, sizeof (salg));
>>> +  if (ret < 0)
>>> +    {
>>> +      ret = -EAFNOSUPPORT;
>>> +      goto out_cfd;
>>> +    }
>>> +
>>> +  ofd = accept (cfd, NULL, 0);
>>> +  if (ofd < 0)
>>> +    {
>>> +      ret = -EAFNOSUPPORT;
>>> +      goto out_ofd;
>>> +    }
>>> +
>>> +  /* if file is a regular file, attempt sendfile() to pipe the data */
>>> +  if (!fstat(fileno(stream), &st) && S_ISREG(st.st_mode) &&
>>> +      st.st_size <= MAX_RW_COUNT)
>> Is it possible to skip that MAX_RW_COUNT check on recent glibc ?
>> From 'man sendfile':
>> "
>> The original Linux sendfile() system call was not designed to handle
>> large file offsets.  Consequently, Linux 2.4 added
>> sendfile64(), with a wider type for the offset argument.  The glibc
>> sendfile()  wrapper  function  transparently  deals
>> with the kernel differences.
>> "
>>
> The advantage of sendfile64() over sendfile() is only that the offset
> in the input file can be bigger.
> I've tried it and it seems that MAX_RW_COUNT is an hard limit on every system:
>
> $ strace -e read dd if=/dev/zero of=/dev/null bs=3G count=1
> read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> 3221225472) = 2147479552
> 0+1 records in
> 0+1 records out
> 2147479552 bytes (2.1 GB, 2.0 GiB) copied, 0.221906 s, 9.7 GB/s

Thanks for testing - I didn't read the man page thoroughly (or
misunderstood it).
> As reported in the manpage too:
>
> "sendfile() will transfer at most 0x7ffff000 (2,147,479,552) bytes,
> returning the number of bytes actually transferred.  (This is true on
> both 32-bit and 64-bit systems.)"
>
>>> +    {
>>> +      if (sendfile(ofd, fileno(stream), NULL, st.st_size) == -1)
>> From 'man sendfile':
>> "
>> Note  that  a  successful  call  to
>> sendfile()  may  write fewer bytes than requested; the caller should be
>> prepared to retry the call if there were unsent
>> bytes.  See also NOTES.
>> "
>>
>>> +        ret = -EIO;
>>> +      else
>>> +        ret = 0;
>>> +    } else {
>>> +      /* sendfile() not possible, do a classic read-write loop */
>>> +      while ((size = fread (buf, 1, sizeof (buf), stream)))
>>> +        {
>>> +          if (send (ofd, buf, size, size == sizeof (buf) ? MSG_MORE : 0) 
>>> == -1)
>>> +            {
>>> +              ret = -EIO;
>>> +              goto out_ofd;
>>> +            }
>>> +        }
>>> +  }
> I might be wrong here, but looking at the kernel code of the
> sendfile64(), which actually calls do_splice_direct() that calls
> splice_direct_to_actor(),
> it can happen only with nonblocking sockets. I didn't managed to
> trigger such behaviour myself, but more testing is welcome.
>
>> Regards, Tim
>>
> Regards,
Regards, Tim




reply via email to

[Prev in Thread] Current Thread [Next in Thread]