lib/string.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
Use min() and drop the limit variable to simplify sized_strscpy().
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
lib/string.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/lib/string.c b/lib/string.c
index b632c71df1a5..1f9297e9776a 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/limits.h>
#include <linux/linkage.h>
+#include <linux/minmax.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/types.h>
@@ -125,11 +126,8 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count)
* If src is unaligned, don't cross a page boundary,
* since we don't know if the next page is mapped.
*/
- if ((long)src & (sizeof(long) - 1)) {
- size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
- if (limit < max)
- max = limit;
- }
+ if ((long)src & (sizeof(long) - 1))
+ max = min(PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)), max);
#else
/* If src or dest is unaligned, don't do word-at-a-time. */
if (((long) dest | (long) src) & (sizeof(long) - 1))
On Thu, 14 May 2026 18:56:03 +0200 Thorsten Blum <thorsten.blum@linux.dev> wrote:
> Use min() and drop the limit variable to simplify sized_strscpy().
Why is this code so messy. Never seen so many typecasts per inch.
> @@ -125,11 +126,8 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count)
> * If src is unaligned, don't cross a page boundary,
> * since we don't know if the next page is mapped.
> */
> - if ((long)src & (sizeof(long) - 1)) {
> - size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
> - if (limit < max)
> - max = limit;
> - }
> + if ((long)src & (sizeof(long) - 1))
That looks like IS_ALIGNED()?
> + max = min(PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)), max);
That looks like a dog's breakfast.
And a bit like ALIGN_DOWN. Not quite, but I'm sure we have helpers for
whatever this is doing.
> #else
> /* If src or dest is unaligned, don't do word-at-a-time. */
> if (((long) dest | (long) src) & (sizeof(long) - 1))
gargh.
Oh well, not your fault. I'll grab the patch, thanks.
On Thu, May 14, 2026 at 7:56 PM Thorsten Blum <thorsten.blum@linux.dev> wrote:
>
> Use min() and drop the limit variable to simplify sized_strscpy().
...
> - if ((long)src & (sizeof(long) - 1)) {
> - size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
> - if (limit < max)
> - max = limit;
> - }
> + if ((long)src & (sizeof(long) - 1))
> + max = min(PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)), max);
Side note: Isn't simply
max = min(PAGE_SIZE - offset_in_page(src), max);
? (One will need to include linux/mm.h for this, though.)
Moreover there are plenty of duplications to count the size in the
first page and even the similar min() as in
fs/iomap/buffered-io.c:869
arch/s390/kvm/gaccess.c:976
and many more...
Perhaps a new macro with a good (famous last words!) naming?
--
With Best Regards,
Andy Shevchenko
On Fri, May 15, 2026 at 09:45:08AM +0300, Andy Shevchenko wrote:
> On Thu, May 14, 2026 at 7:56 PM Thorsten Blum <thorsten.blum@linux.dev> wrote:
> >
> > Use min() and drop the limit variable to simplify sized_strscpy().
>
> ...
>
> > - if ((long)src & (sizeof(long) - 1)) {
> > - size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
> > - if (limit < max)
> > - max = limit;
> > - }
> > + if ((long)src & (sizeof(long) - 1))
> > + max = min(PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)), max);
>
> Side note: Isn't simply
> max = min(PAGE_SIZE - offset_in_page(src), max);
>
> ? (One will need to include linux/mm.h for this, though.)
I thought about it, but wasn't sure if pulling in all of linux/mm.h into
lib/string.c is worth it.
> Moreover there are plenty of duplications to count the size in the
> first page and even the similar min() as in
> fs/iomap/buffered-io.c:869
> arch/s390/kvm/gaccess.c:976
> and many more...
>
> Perhaps a new macro with a good (famous last words!) naming?
How about adding
#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
#define bytes_to_page_end(p) (PAGE_SIZE - offset_in_page(p))
to a new header, e.g. include/linux/page_helpers.h? There are about 50+
direct replacements and possibly more.
On Fri, 15 May 2026 17:09:02 +0200 Thorsten Blum <thorsten.blum@linux.dev> wrote: > On Fri, May 15, 2026 at 09:45:08AM +0300, Andy Shevchenko wrote: . > How about adding > > #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) > #define bytes_to_page_end(p) (PAGE_SIZE - offset_in_page(p)) > > to a new header, e.g. include/linux/page_helpers.h? There are about 50+ > direct replacements and possibly more. > Why not put them in vdso/page.h just after PAGE_MASK. -- David
On Fri, May 15, 2026 at 05:09:02PM +0200, Thorsten Blum wrote:
> On Fri, May 15, 2026 at 09:45:08AM +0300, Andy Shevchenko wrote:
> > On Thu, May 14, 2026 at 7:56 PM Thorsten Blum <thorsten.blum@linux.dev> wrote:
...
> > > - if ((long)src & (sizeof(long) - 1)) {
> > > - size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
> > > - if (limit < max)
> > > - max = limit;
> > > - }
> > > + if ((long)src & (sizeof(long) - 1))
> > > + max = min(PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)), max);
> >
> > Side note: Isn't simply
> > max = min(PAGE_SIZE - offset_in_page(src), max);
> >
> > ? (One will need to include linux/mm.h for this, though.)
>
> I thought about it, but wasn't sure if pulling in all of linux/mm.h into
> lib/string.c is worth it.
>
> > Moreover there are plenty of duplications to count the size in the
> > first page and even the similar min() as in
> > fs/iomap/buffered-io.c:869
> > arch/s390/kvm/gaccess.c:976
> > and many more...
> >
> > Perhaps a new macro with a good (famous last words!) naming?
>
> How about adding
>
> #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
> #define bytes_to_page_end(p) (PAGE_SIZE - offset_in_page(p))
>
> to a new header, e.g. include/linux/page_helpers.h? There are about 50+
> direct replacements and possibly more.
I checked existing linux/page*.h and have no better naming, so all looks
like a good idea to me. Because there are more (existing!) users of mm.h
just for offset_in_page().
--
With Best Regards,
Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.