Background
==========
Linus suggested printing the full path of file instead of printing
the components as '%pd'.
Typically, there is no need for printk specifiers to take any real locks
(ie mount_lock or rename_lock). So I introduce a new helper d_path_fast
which is similar to d_path except it doesn't take any seqlock/spinlock.
This series is based on Al Viro's d_path cleanup patches [1] which
lifted the inner lockless loop into a new helper.
Link: https://lkml.org/lkml/2021/5/18/1260 [1]
Test
====
The cases I tested:
1. print '%pD' with full path of ext4 file
2. mount a ext4 filesystem upon a ext4 filesystem, and print the file
with '%pD'
3. all test_print selftests, including the new '%14pD' '%-14pD'
4. kasnprintf
Changelog
=========
v5:
- remove the RFC tag
- refine the commit msg/comments(by Petr, Andy)
- make using_scratch_space a new parameter of the test case
v4:
- don't support spec.precision anymore for '%pD'
- add Rasmus's patch into this series
v3:
- implement new d_path_unsafe to use [buf, end] instead of stack space for
filling bytes (by Matthew)
- add new test cases for '%pD'
- drop patch "hmcdrv: remove the redundant directory path" before removing rfc.
v2:
- implement new d_path_fast based on Al Viro's patches
- add check_pointer check (by Petr)
- change the max full path size to 256 in stack space
v1: https://lkml.org/lkml/2021/5/8/122
Jia He (3):
fs: introduce helper d_path_unsafe()
lib/vsprintf.c: make '%pD' print the full path of file
lib/test_printf.c: add test cases for '%pD'
Rasmus Villemoes (1):
lib/test_printf.c: split write-beyond-buffer check in two
Documentation/core-api/printk-formats.rst | 5 +-
fs/d_path.c | 104 +++++++++++++++++++++-
include/linux/dcache.h | 1 +
lib/test_printf.c | 54 ++++++++---
lib/vsprintf.c | 40 ++++++++-
5 files changed, 184 insertions(+), 20 deletions(-)
--
2.17.1
This helper is similar to d_path() except that it doesn't take any
seqlock/spinlock. It is typical for debugging purposes. Besides,
an additional return value *prenpend_len* is used to get the full
path length of the dentry, ingoring the tail '\0'.
the full path length = end - buf - prepend_length - 1
Previously it will skip the prepend_name() loop at once in
__prepen_path() when the buffer length is not enough or even negative.
prepend_name_with_len() will get the full length of dentry name
together with the parent recursively regardless of the buffer length.
If someone invokes snprintf() with small but positive space,
prepend_name_with_len() moves and copies the string partially.
More than that, kasprintf() will pass NULL _buf_ and _end_ as the
parameters. Hence return at the very beginning with false in this case.
Suggested-by: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Jia He <redacted>
---
fs/d_path.c | 104 +++++++++++++++++++++++++++++++++++++++--
include/linux/dcache.h | 1 +
2 files changed, 101 insertions(+), 4 deletions(-)
@@ -68,9 +67,84 @@ static bool prepend_name(struct prepend_buffer *p, const struct qstr *name)returntrue;}+/**+*prepend_name_with_len-prependapathnameinfrontofcurrentbuffer+*pointerwithlimitedorig_buflen.+*@p:prependbufferwhichcontainsbufferpointerandallocatedlength+*@name:namestringandlengthqstrstructure+*@orig_buflenoriginallengthofthebuffer.+*+*Withtheoriginallengthofthebuffer(p.ptrischangable),thedentry+*namestringwillbefilledintotheprependingbuffer.Giventheorginal+*lengthmightbelessthannamestring,thedentrynamecanbemovedor+*truncated.+*+*LoadacquireisneededtomakesurethatweseethatterminatingNUL,+*whichissimilartoprepend_name().+*/+staticboolprepend_name_with_len(structprepend_buffer*p,+conststructqstr*name,intorig_buflen)+{+constchar*dname=smp_load_acquire(&name->name);/* ^^^ */+intdlen=READ_ONCE(name->len);+char*s;+intlast_len=p->len;++p->len-=dlen+1;++if(unlikely(!p->buf))+returnfalse;++if(orig_buflen<=0)+returnfalse;++/*+*Thefirsttimeweoverflowthebuffer.Thenfillthestring+*partiallyfromthebeginning+*/+if(unlikely(p->len<0)){+intbuflen=strlen(p->buf);++/* memcpy src */+s=p->buf;++/* Still have small space to fill partially */+if(last_len>0){+p->buf-=last_len;+buflen+=last_len;+}++if(buflen>dlen+1){+/* Dentry name can be fully filled */+memmove(p->buf+dlen+1,s,buflen-dlen-1);+p->buf[0]='/';+memcpy(p->buf+1,dname,dlen);+}elseif(buflen>0){+/* Can be partially filled, and drop last dentry */+p->buf[0]='/';+memcpy(p->buf+1,dname,buflen-1);+}++returnfalse;+}++s=p->buf-=dlen+1;+*s++='/';+while(dlen--){+charc=*dname++;++if(!c)+break;+*s++=c;+}+returntrue;+}+staticint__prepend_path(conststructdentry*dentry,conststructmount*mnt,conststructpath*root,structprepend_buffer*p){+intorig_buflen=p->len;+while(dentry!=root->dentry||&mnt->mnt!=root->mnt){conststructdentry*parent=READ_ONCE(dentry->d_parent);
@@ -97,8 +171,7 @@ static int __prepend_path(const struct dentry *dentry, const struct mount *mnt,return3;prefetch(parent);-if(!prepend_name(p,&dentry->d_name))-break;+prepend_name_with_len(p,&dentry->d_name,orig_buflen);dentry=parent;}return0;
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-06-22 14:36:52
On Tue, Jun 22, 2021 at 10:06:31PM +0800, Jia He wrote:
This helper is similar to d_path() except that it doesn't take any
seqlock/spinlock. It is typical for debugging purposes. Besides,
an additional return value *prenpend_len* is used to get the full
path length of the dentry, ingoring the tail '\0'.
the full path length = end - buf - prepend_length - 1
Missed period at the end of sentence.
Previously it will skip the prepend_name() loop at once in
__prepen_path() when the buffer length is not enough or even negative.
prepend_name_with_len() will get the full length of dentry name
together with the parent recursively regardless of the buffer length.
If someone invokes snprintf() with small but positive space,
prepend_name_with_len() moves and copies the string partially.
More than that, kasprintf() will pass NULL _buf_ and _end_ as the
parameters. Hence return at the very beginning with false in this case.
These two paragraphs are talking about printf() interface, while patch has
nothing to do with it. Please, rephrase in a way that it doesn't refer to the
particular callers. Better to mention them in the corresponding printf()
patch(es).
...
* prepend_name - prepend a pathname in front of current buffer pointer
- * @buffer: buffer pointer
- * @buflen: allocated length of the buffer
+ * @p: prepend buffer which contains buffer pointer and allocated length
* @name: name string and length qstr structure
Indentation issue btw, can be fixed in the same patch.
*
* With RCU path tracing, it may race with d_move(). Use READ_ONCE() to
Shouldn't this be a separate change with corresponding Fixes tag?
...
+/**
+ * d_path_unsafe - return the full path of a dentry without taking
+ * any seqlock/spinlock. This helper is typical for debugging purposes.
Seems you ignored my comment, or forget to test, or compile test with kernel
doc validator enabled doesn't show any issues. If it's the latter, we have to
fix kernel doc validator.
TL;DR: describe parameters as well.
From: Justin He <hidden> Date: 2021-06-23 02:03:07
Hi Andy
-----Original Message-----
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:37 PM
To: Justin He <redacted>
Cc: Petr Mladek <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>;
Sergey Senozhatsky [off-list ref]; Rasmus Villemoes
[off-list ref]; Jonathan Corbet [off-list ref]; Alexander
Viro [off-list ref]; Linus Torvalds <torvalds@linux-
foundation.org>; Peter Zijlstra (Intel) [off-list ref]; Eric
Biggers [off-list ref]; Ahmed S. Darwish [off-list ref];
linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
fsdevel@vger.kernel.org; Matthew Wilcox [off-list ref]; Christoph
Hellwig [off-list ref]; nd [off-list ref]
Subject: Re: [PATCH v5 1/4] fs: introduce helper d_path_unsafe()
On Tue, Jun 22, 2021 at 10:06:31PM +0800, Jia He wrote:
quoted
This helper is similar to d_path() except that it doesn't take any
seqlock/spinlock. It is typical for debugging purposes. Besides,
an additional return value *prenpend_len* is used to get the full
path length of the dentry, ingoring the tail '\0'.
the full path length = end - buf - prepend_length - 1
Missed period at the end of sentence.
Okay
quoted
Previously it will skip the prepend_name() loop at once in
__prepen_path() when the buffer length is not enough or even negative.
prepend_name_with_len() will get the full length of dentry name
together with the parent recursively regardless of the buffer length.
quoted
If someone invokes snprintf() with small but positive space,
prepend_name_with_len() moves and copies the string partially.
More than that, kasprintf() will pass NULL _buf_ and _end_ as the
parameters. Hence return at the very beginning with false in this case.
These two paragraphs are talking about printf() interface, while patch has
nothing to do with it. Please, rephrase in a way that it doesn't refer to
the
particular callers. Better to mention them in the corresponding printf()
patch(es).
Okay
...
quoted
* prepend_name - prepend a pathname in front of current buffer pointer
- * @buffer: buffer pointer
- * @buflen: allocated length of the buffer
+ * @p: prepend buffer which contains buffer pointer and allocated length
quoted
* @name: name string and length qstr structure
Indentation issue btw, can be fixed in the same patch.
Okay
quoted
*
* With RCU path tracing, it may race with d_move(). Use READ_ONCE() to
Shouldn't this be a separate change with corresponding Fixes tag?
Sorry, I don't quite understand here.
What do you want to fix?
...
quoted
+/**
+ * d_path_unsafe - return the full path of a dentry without taking
+ * any seqlock/spinlock. This helper is typical for debugging purposes.
Seems you ignored my comment, or forget to test, or compile test with
kernel
doc validator enabled doesn't show any issues. If it's the latter, we have
to
fix kernel doc validator.
TL;DR: describe parameters as well.
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-06-23 09:07:23
On Wed, Jun 23, 2021 at 02:02:45AM +0000, Justin He wrote:
quoted
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:37 PM
On Tue, Jun 22, 2021 at 10:06:31PM +0800, Jia He wrote:
...
quoted
quoted
* prepend_name - prepend a pathname in front of current buffer pointer
- * @buffer: buffer pointer
- * @buflen: allocated length of the buffer
+ * @p: prepend buffer which contains buffer pointer and allocated length
quoted
* @name: name string and length qstr structure
Indentation issue btw, can be fixed in the same patch.
Okay
quoted
quoted
*
* With RCU path tracing, it may race with d_move(). Use READ_ONCE() to
Shouldn't this be a separate change with corresponding Fixes tag?
Sorry, I don't quite understand here.
What do you want to fix?
Kernel doc. The Fixes tag should correspond to the changes that missed the
update of kernel doc.
--
With Best Regards,
Andy Shevchenko
From: Justin He <hidden> Date: 2021-06-24 02:35:23
Hi Andy
-----Original Message-----
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Wednesday, June 23, 2021 5:07 PM
To: Justin He <redacted>
Cc: Petr Mladek <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>;
Sergey Senozhatsky [off-list ref]; Rasmus Villemoes
[off-list ref]; Jonathan Corbet [off-list ref]; Alexander
Viro [off-list ref]; Linus Torvalds <torvalds@linux-
foundation.org>; Peter Zijlstra (Intel) [off-list ref]; Eric
Biggers [off-list ref]; Ahmed S. Darwish [off-list ref];
linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
fsdevel@vger.kernel.org; Matthew Wilcox [off-list ref]; Christoph
Hellwig [off-list ref]; nd [off-list ref]
Subject: Re: [PATCH v5 1/4] fs: introduce helper d_path_unsafe()
On Wed, Jun 23, 2021 at 02:02:45AM +0000, Justin He wrote:
quoted
quoted
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:37 PM
On Tue, Jun 22, 2021 at 10:06:31PM +0800, Jia He wrote:
...
quoted
quoted
quoted
* prepend_name - prepend a pathname in front of current buffer
pointer
quoted
quoted
quoted
- * @buffer: buffer pointer
- * @buflen: allocated length of the buffer
+ * @p: prepend buffer which contains buffer pointer and allocated
length
quoted
quoted
quoted
* @name: name string and length qstr structure
Indentation issue btw, can be fixed in the same patch.
Okay
quoted
quoted
*
* With RCU path tracing, it may race with d_move(). Use READ_ONCE()
to
quoted
quoted
Shouldn't this be a separate change with corresponding Fixes tag?
Sorry, I don't quite understand here.
What do you want to fix?
Kernel doc. The Fixes tag should correspond to the changes that missed the
update of kernel doc.
From: Petr Mladek <pmladek@suse.com> Date: 2021-06-24 09:26:57
On Tue 2021-06-22 17:36:39, Andy Shevchenko wrote:
On Tue, Jun 22, 2021 at 10:06:31PM +0800, Jia He wrote:
quoted
This helper is similar to d_path() except that it doesn't take any
seqlock/spinlock. It is typical for debugging purposes. Besides,
an additional return value *prenpend_len* is used to get the full
path length of the dentry, ingoring the tail '\0'.
the full path length = end - buf - prepend_length - 1
Missed period at the end of sentence.
quoted
Previously it will skip the prepend_name() loop at once in
__prepen_path() when the buffer length is not enough or even negative.
prepend_name_with_len() will get the full length of dentry name
together with the parent recursively regardless of the buffer length.
quoted
If someone invokes snprintf() with small but positive space,
prepend_name_with_len() moves and copies the string partially.
More than that, kasprintf() will pass NULL _buf_ and _end_ as the
parameters. Hence return at the very beginning with false in this case.
These two paragraphs are talking about printf() interface, while patch has
nothing to do with it. Please, rephrase in a way that it doesn't refer to the
particular callers. Better to mention them in the corresponding printf()
patch(es).
The two paragraphs are actually repeated in the 2nd
patch. Unfortunately, they do not make sense there either because they
comment code that is modified in this patch.
We could describe it here a generic way. For example:
prepend_name_with_len() moves and copies the path when the given
buffer is not big enough. It cuts off the end of the path.
It returns immediately when there is no buffer at all.
Best Regards,
Petr
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-06-24 10:48:17
On Thu, Jun 24, 2021 at 11:26:53AM +0200, Petr Mladek wrote:
On Tue 2021-06-22 17:36:39, Andy Shevchenko wrote:
quoted
On Tue, Jun 22, 2021 at 10:06:31PM +0800, Jia He wrote:
quoted
This helper is similar to d_path() except that it doesn't take any
seqlock/spinlock. It is typical for debugging purposes. Besides,
an additional return value *prenpend_len* is used to get the full
path length of the dentry, ingoring the tail '\0'.
the full path length = end - buf - prepend_length - 1
Missed period at the end of sentence.
quoted
Previously it will skip the prepend_name() loop at once in
__prepen_path() when the buffer length is not enough or even negative.
prepend_name_with_len() will get the full length of dentry name
together with the parent recursively regardless of the buffer length.
quoted
If someone invokes snprintf() with small but positive space,
prepend_name_with_len() moves and copies the string partially.
More than that, kasprintf() will pass NULL _buf_ and _end_ as the
parameters. Hence return at the very beginning with false in this case.
These two paragraphs are talking about printf() interface, while patch has
nothing to do with it. Please, rephrase in a way that it doesn't refer to the
particular callers. Better to mention them in the corresponding printf()
patch(es).
The two paragraphs are actually repeated in the 2nd
patch. Unfortunately, they do not make sense there either because they
comment code that is modified in this patch.
We could describe it here a generic way. For example:
prepend_name_with_len() moves and copies the path when the given
buffer is not big enough. It cuts off the end of the path.
It returns immediately when there is no buffer at all.
Yes, that's my point, but sorry if I made it unclear.
--
With Best Regards,
Andy Shevchenko
Previously, the specifier '%pD' is for printing dentry name of struct
file. It may not be perfect (by default it only prints one component.)
As suggested by Linus [1]:
A dentry has a parent, but at the same time, a dentry really does
inherently have "one name" (and given just the dentry pointers, you
can't show mount-related parenthood, so in many ways the "show just
one name" makes sense for "%pd" in ways it doesn't necessarily for
"%pD"). But while a dentry arguably has that "one primary component",
a _file_ is certainly not exclusively about that last component.
Hence change the behavior of '%pD' to print the full path of that file.
Precision is never going to be used with %p (or any of its kernel
extensions) if -Wformat is turned on.
Link: https://lore.kernel.org/lkml/CAHk-=wimsMqGdzik187YWLb-ru+iktb4MYbMQG1rnZ81dXYFVg@mail.gmail.com/ [1]
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jia He <redacted>
---
Documentation/core-api/printk-formats.rst | 5 +--
lib/vsprintf.c | 40 ++++++++++++++++++++---
2 files changed, 39 insertions(+), 6 deletions(-)
@@ -408,12 +408,13 @@ dentry names :: %pd{,2,3,4}- %pD{,2,3,4}+ %pD For printing dentry name; if we race with :c:func:`d_move`, the name might be a mix of old and new ones, but it won't oops. %pd dentry is a safer equivalent of %s dentry->d_name.name we used to use, %pd<n> prints ``n``-last components. %pD does the same thing for struct file.+last components. %pD prints full file path together with mount-related+parenthood. Passed by reference.
@@ -920,13 +921,44 @@ char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_sp}staticnoinline_for_stack-char*file_dentry_name(char*buf,char*end,conststructfile*f,+char*file_d_path_name(char*buf,char*end,conststructfile*f,structprintf_specspec,constchar*fmt){+conststructpath*path;+char*p;+intprepend_len,widen_len,dpath_len;+if(check_pointer(&buf,end,f,spec))returnbuf;-returndentry_name(buf,end,f->f_path.dentry,spec,fmt);+path=&f->f_path;+if(check_pointer(&buf,end,path,spec))+returnbuf;++p=d_path_unsafe(path,buf,end-buf,&prepend_len);++/* Calculate the full d_path length, ignoring the tail '\0' */+dpath_len=end-buf-prepend_len-1;++widen_len=max_t(int,dpath_len,spec.field_width);++/* Case 1: Already started past the buffer. Just forward @buf. */+if(buf>=end)+returnbuf+widen_len;++/*+*Case2:Theentireremainingspaceofthebufferfilledby+*thetruncatedpath.Stillneedtogetmovedrightwhen+*thefilledwidthisgreatherthanthefullpathlength.+*/+if(prepend_len<0)+returnwiden_string(buf+dpath_len,dpath_len,end,spec);++/*+*Case3:Thefullpathisprintedattheendofthebuffer.+*Printitattherightlocationinthesamebuffer.+*/+returnstring_nocheck(buf,end,p,spec);}#ifdef CONFIG_BLOCKstaticnoinline_for_stack
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-06-22 14:40:04
On Tue, Jun 22, 2021 at 10:06:32PM +0800, Jia He wrote:
Previously, the specifier '%pD' is for printing dentry name of struct
file. It may not be perfect (by default it only prints one component.)
As suggested by Linus [1]:
Citing is better looked when you shift right it by two white spaces.
A dentry has a parent, but at the same time, a dentry really does
inherently have "one name" (and given just the dentry pointers, you
can't show mount-related parenthood, so in many ways the "show just
one name" makes sense for "%pd" in ways it doesn't necessarily for
"%pD"). But while a dentry arguably has that "one primary component",
a _file_ is certainly not exclusively about that last component.
Hence change the behavior of '%pD' to print the full path of that file.
Precision is never going to be used with %p (or any of its kernel
extensions) if -Wformat is turned on.
From: Justin He <hidden> Date: 2021-06-23 03:15:07
Hi Andy
-----Original Message-----
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:40 PM
To: Justin He <redacted>
Cc: Petr Mladek <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>;
Sergey Senozhatsky [off-list ref]; Rasmus Villemoes
[off-list ref]; Jonathan Corbet [off-list ref]; Alexander
Viro [off-list ref]; Linus Torvalds <torvalds@linux-
foundation.org>; Peter Zijlstra (Intel) [off-list ref]; Eric
Biggers [off-list ref]; Ahmed S. Darwish [off-list ref];
linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
fsdevel@vger.kernel.org; Matthew Wilcox [off-list ref]; Christoph
Hellwig [off-list ref]; nd [off-list ref]
Subject: Re: [PATCH v5 2/4] lib/vsprintf.c: make '%pD' print the full path
of file
On Tue, Jun 22, 2021 at 10:06:32PM +0800, Jia He wrote:
quoted
Previously, the specifier '%pD' is for printing dentry name of struct
file. It may not be perfect (by default it only prints one component.)
As suggested by Linus [1]:
Citing is better looked when you shift right it by two white spaces.
Okay, I plan to cite it with "> "
quoted
A dentry has a parent, but at the same time, a dentry really does
inherently have "one name" (and given just the dentry pointers, you
can't show mount-related parenthood, so in many ways the "show just
one name" makes sense for "%pd" in ways it doesn't necessarily for
"%pD"). But while a dentry arguably has that "one primary component",
a _file_ is certainly not exclusively about that last component.
Hence change the behavior of '%pD' to print the full path of that file.
Precision is never going to be used with %p (or any of its kernel
extensions) if -Wformat is turned on.
From: Petr Mladek <pmladek@suse.com> Date: 2021-06-24 08:47:01
On Wed 2021-06-23 03:14:33, Justin He wrote:
Hi Andy
quoted
-----Original Message-----
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:40 PM
To: Justin He <redacted>
Cc: Petr Mladek <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>;
Sergey Senozhatsky [off-list ref]; Rasmus Villemoes
[off-list ref]; Jonathan Corbet [off-list ref]; Alexander
Viro [off-list ref]; Linus Torvalds <torvalds@linux-
foundation.org>; Peter Zijlstra (Intel) [off-list ref]; Eric
Biggers [off-list ref]; Ahmed S. Darwish [off-list ref];
linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
fsdevel@vger.kernel.org; Matthew Wilcox [off-list ref]; Christoph
Hellwig [off-list ref]; nd [off-list ref]
Subject: Re: [PATCH v5 2/4] lib/vsprintf.c: make '%pD' print the full path
of file
On Tue, Jun 22, 2021 at 10:06:32PM +0800, Jia He wrote:
quoted
Previously, the specifier '%pD' is for printing dentry name of struct
file. It may not be perfect (by default it only prints one component.)
As suggested by Linus [1]:
Citing is better looked when you shift right it by two white spaces.
Okay, I plan to cite it with "> "
My understanding is that Andy suggested to omit '>' and prefix it by
plain two spaces " ". It would look better to me as well.
Best Regards,
Petr
From: Justin He <hidden> Date: 2021-06-24 09:01:51
Hi Petr
-----Original Message-----
From: Petr Mladek <pmladek@suse.com>
Sent: Thursday, June 24, 2021 4:47 PM
To: Justin He <redacted>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>; Steven Rostedt
[off-list ref]; Sergey Senozhatsky [off-list ref];
Rasmus Villemoes [off-list ref]; Jonathan Corbet
[off-list ref]; Alexander Viro [off-list ref]; Linus Torvalds
[off-list ref]; Peter Zijlstra (Intel)
[off-list ref]; Eric Biggers [off-list ref]; Ahmed S.
Darwish [off-list ref]; linux-doc@vger.kernel.org; linux-
kernel@vger.kernel.org; linux-fsdevel@vger.kernel.org; Matthew Wilcox
[off-list ref]; Christoph Hellwig [off-list ref]; nd
[off-list ref]
Subject: Re: [PATCH v5 2/4] lib/vsprintf.c: make '%pD' print the full path
of file
On Wed 2021-06-23 03:14:33, Justin He wrote:
quoted
Hi Andy
quoted
-----Original Message-----
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:40 PM
To: Justin He <redacted>
Cc: Petr Mladek <pmladek@suse.com>; Steven Rostedt
[off-list ref];
quoted
quoted
Sergey Senozhatsky [off-list ref]; Rasmus Villemoes
[off-list ref]; Jonathan Corbet [off-list ref]; Alexander
Viro [off-list ref]; Linus Torvalds <torvalds@linux-
foundation.org>; Peter Zijlstra (Intel) [off-list ref]; Eric
Biggers [off-list ref]; Ahmed S. Darwish
[off-list ref];
quoted
quoted
linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
fsdevel@vger.kernel.org; Matthew Wilcox [off-list ref];
Christoph
quoted
quoted
Hellwig [off-list ref]; nd [off-list ref]
Subject: Re: [PATCH v5 2/4] lib/vsprintf.c: make '%pD' print the full
path
quoted
quoted
of file
On Tue, Jun 22, 2021 at 10:06:32PM +0800, Jia He wrote:
quoted
Previously, the specifier '%pD' is for printing dentry name of struct
file. It may not be perfect (by default it only prints one component.)
As suggested by Linus [1]:
Citing is better looked when you shift right it by two white spaces.
Okay, I plan to cite it with "> "
My understanding is that Andy suggested to omit '>' and prefix it by
plain two spaces " ". It would look better to me as well.
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Before each invocation of vsnprintf(), do_test() memsets the entire
allocated buffer to a sentinel value. That buffer includes leading and
trailing padding which is never included in the buffer area handed to
vsnprintf (spaces merely for clarity):
pad test_buffer pad
**** **************** ****
Then vsnprintf() is invoked with a bufsize argument <=
BUF_SIZE. Suppose bufsize=10, then we'd have e.g.
|pad | test_buffer |pad |
**** pizza0 **** ****** ****
A B C D E
where vsnprintf() was given the area from B to D.
It is obviously a bug for vsnprintf to touch anything between A and B
or between D and E. The former is checked for as one would expect. But
for the latter, we are actually a little stricter in that we check the
area between C and E.
Split that check in two, providing a clearer error message in case it
was a genuine buffer overrun and not merely a write within the
provided buffer, but after the end of the generated string.
So far, no part of the vsnprintf() implementation has had any use for
using the whole buffer as scratch space, but it's not unreasonable to
allow that, as long as the result is properly nul-terminated and the
return value is the right one. However, it is somewhat unusual, and
most %<something> won't need this, so keep the [C,D] check, but make
it easy for a later patch to make that part opt-out for certain tests.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Tested-by: Jia He <redacted>
Signed-off-by: Jia He <redacted>
Reviewed-by: Petr Mladek <pmladek@suse.com>
---
lib/test_printf.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
After the behaviour of specifier '%pD' is changed to print the full path
of struct file, the related test cases are also updated.
Given the full path string of '%pD' is prepended from the end of the scratch
buffer, the check of "wrote beyond the nul-terminator" should be skipped
for '%pD'.
Parameterize the new using_scratch_space in __test, do_test to skip the
test case mentioned above,
Signed-off-by: Jia He <redacted>
---
lib/test_printf.c | 49 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 39 insertions(+), 10 deletions(-)
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-06-22 14:41:45
On Tue, Jun 22, 2021 at 10:06:34PM +0800, Jia He wrote:
After the behaviour of specifier '%pD' is changed to print the full path
of struct file, the related test cases are also updated.
Given the full path string of '%pD' is prepended from the end of the scratch
buffer, the check of "wrote beyond the nul-terminator" should be skipped
for '%pD'.
Parameterize the new using_scratch_space in __test, do_test to skip the
After the behaviour of specifier '%pD' is changed to print the full path
of struct file, the related test cases are also updated.
Given the full path string of '%pD' is prepended from the end of the scratch
buffer, the check of "wrote beyond the nul-terminator" should be skipped
for '%pD'.
Parameterize the new using_scratch_space in __test, do_test to skip the
test case mentioned above,
I actually prefer the first suggestion of just having a file-global bool.
If and when we get other checks that need to be done selectively [e.g.
"snprintf into a too short buffer produces a prefix of the full string",
which also came up during this discussion but was ultimately kept]
depending on the %<whatever> being exercised, we can add a "u32 nocheck"
with a bunch of bits saying what to elide.
Not insisting either way, just my $0.02.
Rasmus
From: Justin He <hidden> Date: 2021-06-23 03:28:13
Hi Rasmus
-----Original Message-----
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Sent: Wednesday, June 23, 2021 4:52 AM
To: Justin He <redacted>; Petr Mladek <pmladek@suse.com>; Steven
Rostedt [off-list ref]; Sergey Senozhatsky
[off-list ref]; Andy Shevchenko
[off-list ref]; Jonathan Corbet [off-list ref];
Alexander Viro [off-list ref]; Linus Torvalds <torvalds@linux-
foundation.org>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>; Eric Biggers
[off-list ref]; Ahmed S. Darwish [off-list ref]; linux-
doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
fsdevel@vger.kernel.org; Matthew Wilcox [off-list ref]; Christoph
Hellwig [off-list ref]; nd [off-list ref]
Subject: Re: [PATCH v5 4/4] lib/test_printf.c: add test cases for '%pD'
On 22/06/2021 16.06, Jia He wrote:
quoted
After the behaviour of specifier '%pD' is changed to print the full path
of struct file, the related test cases are also updated.
Given the full path string of '%pD' is prepended from the end of the
scratch
quoted
buffer, the check of "wrote beyond the nul-terminator" should be skipped
for '%pD'.
Parameterize the new using_scratch_space in __test, do_test to skip the
test case mentioned above,
I actually prefer the first suggestion of just having a file-global bool.
Yes, this is my previous proposal, but seems it is not satisfying 😉.
--
Cheers,
Justin (Jia He)
If and when we get other checks that need to be done selectively [e.g.
"snprintf into a too short buffer produces a prefix of the full string",
which also came up during this discussion but was ultimately kept]
depending on the %<whatever> being exercised, we can add a "u32 nocheck"
with a bunch of bits saying what to elide.
Not insisting either way, just my $0.02.
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-06-22 14:43:35
On Tue, Jun 22, 2021 at 10:06:30PM +0800, Jia He wrote:
Background
==========
Linus suggested printing the full path of file instead of printing
the components as '%pd'.
Typically, there is no need for printk specifiers to take any real locks
(ie mount_lock or rename_lock). So I introduce a new helper d_path_fast
which is similar to d_path except it doesn't take any seqlock/spinlock.
This series is based on Al Viro's d_path cleanup patches [1] which
lifted the inner lockless loop into a new helper.
Link: https://lkml.org/lkml/2021/5/18/1260 [1]
Test
====
The cases I tested:
1. print '%pD' with full path of ext4 file
2. mount a ext4 filesystem upon a ext4 filesystem, and print the file
with '%pD'
3. all test_print selftests, including the new '%14pD' '%-14pD'
4. kasnprintf
I believe you are talking about kasprintf().
Changelog
=========
v5:
- remove the RFC tag
JFYI, when we drop RFC we usually start the series from v1.
- refine the commit msg/comments(by Petr, Andy)
- make using_scratch_space a new parameter of the test case
Thanks for the update, I have found few minor things, please address them and
feel free to add
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
v4:
- don't support spec.precision anymore for '%pD'
- add Rasmus's patch into this series
v3:
- implement new d_path_unsafe to use [buf, end] instead of stack space for
filling bytes (by Matthew)
- add new test cases for '%pD'
- drop patch "hmcdrv: remove the redundant directory path" before removing rfc.
v2:
- implement new d_path_fast based on Al Viro's patches
- add check_pointer check (by Petr)
- change the max full path size to 256 in stack space
v1: https://lkml.org/lkml/2021/5/8/122
Jia He (3):
fs: introduce helper d_path_unsafe()
lib/vsprintf.c: make '%pD' print the full path of file
lib/test_printf.c: add test cases for '%pD'
Rasmus Villemoes (1):
lib/test_printf.c: split write-beyond-buffer check in two
Documentation/core-api/printk-formats.rst | 5 +-
fs/d_path.c | 104 +++++++++++++++++++++-
include/linux/dcache.h | 1 +
lib/test_printf.c | 54 ++++++++---
lib/vsprintf.c | 40 ++++++++-
5 files changed, 184 insertions(+), 20 deletions(-)
--
2.17.1
From: Justin He <hidden> Date: 2021-06-23 04:13:39
Hi Andy
-----Original Message-----
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:43 PM
To: Justin He <redacted>
Cc: Petr Mladek <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>;
Sergey Senozhatsky [off-list ref]; Rasmus Villemoes
[off-list ref]; Jonathan Corbet [off-list ref]; Alexander
Viro [off-list ref]; Linus Torvalds <torvalds@linux-
foundation.org>; Peter Zijlstra (Intel) [off-list ref]; Eric
Biggers [off-list ref]; Ahmed S. Darwish [off-list ref];
linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
fsdevel@vger.kernel.org; Matthew Wilcox [off-list ref]; Christoph
Hellwig [off-list ref]; nd [off-list ref]
Subject: Re: [PATCH v5 0/4] make '%pD' print the full path of file
On Tue, Jun 22, 2021 at 10:06:30PM +0800, Jia He wrote:
quoted
Background
==========
Linus suggested printing the full path of file instead of printing
the components as '%pd'.
Typically, there is no need for printk specifiers to take any real locks
(ie mount_lock or rename_lock). So I introduce a new helper d_path_fast
which is similar to d_path except it doesn't take any seqlock/spinlock.
This series is based on Al Viro's d_path cleanup patches [1] which
lifted the inner lockless loop into a new helper.
Link: https://lkml.org/lkml/2021/5/18/1260 [1]
Test
====
The cases I tested:
1. print '%pD' with full path of ext4 file
2. mount a ext4 filesystem upon a ext4 filesystem, and print the file
with '%pD'
3. all test_print selftests, including the new '%14pD' '%-14pD'
quoted
4. kasnprintf
I believe you are talking about kasprintf().
quoted
Changelog
=========
v5:
- remove the RFC tag
JFYI, when we drop RFC we usually start the series from v1.
quoted
- refine the commit msg/comments(by Petr, Andy)
- make using_scratch_space a new parameter of the test case
Thanks for the update, I have found few minor things, please address them
and
feel free to add
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
I assume I can add your R-b to patch 4/4 "add test cases for '%pD'" instead of
whole series, right?
--
Cheers,
Justin (Jia He)
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-06-23 09:12:53
On Wed, Jun 23, 2021 at 04:13:03AM +0000, Justin He wrote:
quoted
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Sent: Tuesday, June 22, 2021 10:43 PM
On Tue, Jun 22, 2021 at 10:06:30PM +0800, Jia He wrote:
...
quoted
quoted
v5:
- remove the RFC tag
JFYI, when we drop RFC we usually start the series from v1.
quoted
- refine the commit msg/comments(by Petr, Andy)
- make using_scratch_space a new parameter of the test case
Thanks for the update, I have found few minor things, please address them
and
feel free to add
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
I assume I can add your R-b to patch 4/4 "add test cases for '%pD'" instead of
whole series, right?
It was against cover letter, means to cover the whole series, but since you do
not address my comments, do not apply to the patches we have not settled down
on.
--
With Best Regards,
Andy Shevchenko