All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFCv2 0/3] make '%pD' print full path for file
@ 2021-05-28 11:39 Jia He
  2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
                   ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Jia He @ 2021-05-28 11:39 UTC (permalink / raw)
  To: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik
  Cc: Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Jia He

Background
==========
Linus suggested printing full path for 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. 

[1] https://lkml.org/lkml/2021/5/18/1260

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. print file path which has more than 256 chars,"-ENAMETOOLONG" will
   be returned
4. print file path with '%32pD'
5. all test_print selftests
   
After this set, I found many lines containing '%pD[234]' should be changed
to '%pD'. I don't want to involve those subsystems in this patch series
before the helper is stable enough.
   
You can get the lines by:
$find fs/ -name \*.[ch] | xargs grep -rn "\%pD[234"

fs/overlayfs/file.c:65: pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
fs/nfs/direct.c:453:    dfprintk(FILE, "NFS: direct read(%pD2, %zd@%Ld)\n",
fs/nfs/direct.c:908:    dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
fs/nfs/write.c:1371:    dprintk("NFS:       nfs_updatepage(%pD2 %d@%lld)\n",
fs/nfs/nfs4file.c:116:  dprintk("NFS: flush(%pD2)\n", file);
fs/nfs/file.c:69:       dprintk("NFS: open file(%pD2)\n", filp);
fs/nfs/file.c:83:       dprintk("NFS: release(%pD2)\n", filp);
fs/nfs/file.c:117:      dprintk("NFS: llseek file(%pD2, %lld, %d)\n",
fs/nfs/file.c:145:      dprintk("NFS: flush(%pD2)\n", file);
fs/nfs/file.c:166:      dprintk("NFS: read(%pD2, %zu@%lu)\n",
fs/nfs/file.c:188:      dprintk("NFS: mmap(%pD2)\n", file);
fs/nfs/file.c:213:      dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
fs/nfs/file.c:328:      dfprintk(PAGECACHE, "NFS: write_begin(%pD2(%lu), %u@%lld)\n",
fs/nfs/file.c:360:      dfprintk(PAGECACHE, "NFS: write_end(%pD2(%lu), %u@%lld)\n",
fs/nfs/file.c:551:      dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%pD2(%lu), offset %lld)\n",
fs/nfs/file.c:621:      dprintk("NFS: write(%pD2, %zu@%Ld)\n",
fs/nfs/file.c:803:      dprintk("NFS: lock(%pD2, t=%x, fl=%x, r=%lld:%lld)\n",
fs/nfs/file.c:841:      dprintk("NFS: flock(%pD2, t=%x, fl=%x)\n",
fs/nfs/dir.c:111:       dfprintk(FILE, "NFS: open dir(%pD2)\n", filp);
fs/nfs/dir.c:456:                                               pr_notice("NFS: directory %pD2 contains a readdir loop."
fs/nfs/dir.c:1084:      dfprintk(FILE, "NFS: readdir(%pD2) starting at cookie %llu\n",
fs/nfs/dir.c:1158:      dfprintk(FILE, "NFS: readdir(%pD2) returns %d\n", file, res);
fs/nfs/dir.c:1166:      dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
fs/nfs/dir.c:1208:      dfprintk(FILE, "NFS: fsync dir(%pD2) datasync %d\n", filp, datasync);
fs/nfsd/nfs4state.c:2439:         seq_printf(s, "filename: \"%pD2\"", f->nf_file);
fs/exec.c:817:          pr_warn_once("process '%pD4' started with executable stack\n",
fs/iomap/direct-io.c:429:               pr_warn_ratelimited("Direct I/O collision with buffered writes! File: %pD4 Comm: %.20s\n",
fs/ioctl.c:81:          pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n",
fs/read_write.c:425:            "kernel %s not supported for file %pD4 (pid: %d comm: %.20s)\n",
fs/splice.c:754:                "splice %s not supported for file %pD4 (pid: %d comm: %.20s)\n",
fs/afs/mntpt.c:64:      _enter("%p,%p{%pD2}", inode, file, file);

Changelog:
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_fast()
  lib/vsprintf.c: make %pD print full path for file
  s390/hmcdrv: remove the redundant directory path in debug message

 Documentation/core-api/printk-formats.rst |  5 +++--
 drivers/s390/char/hmcdrv_dev.c            | 10 +++++-----
 fs/d_path.c                               | 21 +++++++++++++++++++++
 include/linux/dcache.h                    |  1 +
 lib/vsprintf.c                            | 21 +++++++++++++++++----
 5 files changed, 47 insertions(+), 11 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH RFCv2 1/3] fs: introduce helper d_path_fast()
  2021-05-28 11:39 [PATCH RFCv2 0/3] make '%pD' print full path for file Jia He
@ 2021-05-28 11:39 ` Jia He
  2021-05-28 12:37   ` kernel test robot
                     ` (3 more replies)
  2021-05-28 11:39 ` [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file Jia He
  2021-05-28 11:39 ` [PATCH RFCv2 3/3] s390/hmcdrv: remove the redundant directory path in debug message Jia He
  2 siblings, 4 replies; 28+ messages in thread
From: Jia He @ 2021-05-28 11:39 UTC (permalink / raw)
  To: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik
  Cc: Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Jia He

This helper is similar to d_path except that it doesn't take any
seqlock/spinlock. It is typical for debugging purpose.

Signed-off-by: Jia He <justin.he@arm.com>
---
 fs/d_path.c            | 21 +++++++++++++++++++++
 include/linux/dcache.h |  1 +
 2 files changed, 22 insertions(+)

diff --git a/fs/d_path.c b/fs/d_path.c
index 23a53f7b5c71..f9df68d62786 100644
--- a/fs/d_path.c
+++ b/fs/d_path.c
@@ -263,6 +263,27 @@ char *d_path(const struct path *path, char *buf, int buflen)
 }
 EXPORT_SYMBOL(d_path);
 
+/**
+ * d_path_fast - fast return the full path of a dentry without taking
+ * any seqlock/spinlock. This helper is typical for debugging purpose
+ */
+char *d_path_fast(const struct path *path, char *buf, int buflen)
+{
+	struct path root;
+	struct mount *mnt = real_mount(path->mnt);
+	DECLARE_BUFFER(b, buf, buflen);
+
+	rcu_read_lock();
+	get_fs_root_rcu(current->fs, &root);
+
+	prepend(&b, "", 1);
+	__prepend_path(path->dentry, mnt, &root, &b);
+	rcu_read_unlock();
+
+	return extract_string(&b);
+}
+EXPORT_SYMBOL(d_path_fast);
+
 /*
  * Helper function for dentry_operations.d_dname() members
  */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 9e23d33bb6f1..c4483fc887a5 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -301,6 +301,7 @@ char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
 extern char *__d_path(const struct path *, const struct path *, char *, int);
 extern char *d_absolute_path(const struct path *, char *, int);
 extern char *d_path(const struct path *, char *, int);
+extern char *d_path_fast(const struct path *, char *, int);
 extern char *dentry_path_raw(const struct dentry *, char *, int);
 extern char *dentry_path(const struct dentry *, char *, int);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 11:39 [PATCH RFCv2 0/3] make '%pD' print full path for file Jia He
  2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
@ 2021-05-28 11:39 ` Jia He
  2021-05-28 12:59   ` Matthew Wilcox
  2021-05-30 20:51   ` kernel test robot
  2021-05-28 11:39 ` [PATCH RFCv2 3/3] s390/hmcdrv: remove the redundant directory path in debug message Jia He
  2 siblings, 2 replies; 28+ messages in thread
From: Jia He @ 2021-05-28 11:39 UTC (permalink / raw)
  To: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik
  Cc: Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Jia He

We have '%pD' for printing a filename. It may not be perfect (by
default it only prints one component.)

As suggested by Linus at [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 "file_dentry_name()" simply shouldn't use "dentry_name()" at all.
Despite that shared code origin, and despite that similar letter
choice (lower-vs-upper case), a dentry and a file really are very
different from a name standpoint.

Here stack space is preferred for file_d_path_name() because it is
much safer. The stack size 256 is a compromise between stack overflow
and too short full path.

[1] https://lore.kernel.org/lkml/CAHk-=wimsMqGdzik187YWLb-ru+iktb4MYbMQG1rnZ81dXYFVg@mail.gmail.com/

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jia He <justin.he@arm.com>
---
 Documentation/core-api/printk-formats.rst |  5 +++--
 lib/vsprintf.c                            | 21 +++++++++++++++++----
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index f063a384c7c8..95ba14dc529b 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -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.
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index f0c35d9b65bf..2e5387b08d67 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -27,6 +27,7 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/kernel.h>
+#include <linux/dcache.h>
 #include <linux/kallsyms.h>
 #include <linux/math64.h>
 #include <linux/uaccess.h>
@@ -920,13 +921,25 @@ char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_sp
 }
 
 static noinline_for_stack
-char *file_dentry_name(char *buf, char *end, const struct file *f,
+char *file_d_path_name(char *buf, char *end, const struct file *f,
 			struct printf_spec spec, const char *fmt)
 {
+	const struct path *path;
+	char *p;
+	char full_path[256];
+
 	if (check_pointer(&buf, end, f, spec))
 		return buf;
 
-	return dentry_name(buf, end, f->f_path.dentry, spec, fmt);
+	path = &f->f_path;
+	if (check_pointer(&buf, end, path, spec))
+		return buf;
+
+	p = d_path_fast(path, full_path, sizeof(full_path));
+	if (IS_ERR(p))
+		return err_ptr(buf, end, p, spec);
+
+	return string_nocheck(buf, end, p, spec);
 }
 #ifdef CONFIG_BLOCK
 static noinline_for_stack
@@ -2296,7 +2309,7 @@ early_param("no_hash_pointers", no_hash_pointers_enable);
  * - 'a[pd]' For address types [p] phys_addr_t, [d] dma_addr_t and derivatives
  *           (default assumed to be phys_addr_t, passed by reference)
  * - 'd[234]' For a dentry name (optionally 2-4 last components)
- * - 'D[234]' Same as 'd' but for a struct file
+ * - 'D' For full path name of a struct file
  * - 'g' For block_device name (gendisk + partition number)
  * - 't[RT][dt][r]' For time and date as represented by:
  *      R    struct rtc_time
@@ -2395,7 +2408,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 	case 'C':
 		return clock(buf, end, ptr, spec, fmt);
 	case 'D':
-		return file_dentry_name(buf, end, ptr, spec, fmt);
+		return file_d_path_name(buf, end, ptr, spec, fmt);
 #ifdef CONFIG_BLOCK
 	case 'g':
 		return bdev_name(buf, end, ptr, spec, fmt);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH RFCv2 3/3] s390/hmcdrv: remove the redundant directory path in debug message
  2021-05-28 11:39 [PATCH RFCv2 0/3] make '%pD' print full path for file Jia He
  2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
  2021-05-28 11:39 ` [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file Jia He
@ 2021-05-28 11:39 ` Jia He
  2 siblings, 0 replies; 28+ messages in thread
From: Jia He @ 2021-05-28 11:39 UTC (permalink / raw)
  To: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik
  Cc: Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Jia He

It would be better to use full file path with '%pD' instead of hard coding.

Signed-off-by: Jia He <justin.he@arm.com>
---
 drivers/s390/char/hmcdrv_dev.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/char/hmcdrv_dev.c b/drivers/s390/char/hmcdrv_dev.c
index 20e9cd542e03..cdde75508c8a 100644
--- a/drivers/s390/char/hmcdrv_dev.c
+++ b/drivers/s390/char/hmcdrv_dev.c
@@ -137,7 +137,7 @@ static int hmcdrv_dev_open(struct inode *inode, struct file *fp)
 	if (rc)
 		module_put(THIS_MODULE);
 
-	pr_debug("open file '/dev/%pD' with return code %d\n", fp, rc);
+	pr_debug("open file '%pD' with return code %d\n", fp, rc);
 	return rc;
 }
 
@@ -146,7 +146,7 @@ static int hmcdrv_dev_open(struct inode *inode, struct file *fp)
  */
 static int hmcdrv_dev_release(struct inode *inode, struct file *fp)
 {
-	pr_debug("closing file '/dev/%pD'\n", fp);
+	pr_debug("closing file '%pD'\n", fp);
 	kfree(fp->private_data);
 	fp->private_data = NULL;
 	hmcdrv_ftp_shutdown();
@@ -231,7 +231,7 @@ static ssize_t hmcdrv_dev_read(struct file *fp, char __user *ubuf,
 	retlen = hmcdrv_dev_transfer((char *) fp->private_data,
 				     *pos, ubuf, len);
 
-	pr_debug("read from file '/dev/%pD' at %lld returns %zd/%zu\n",
+	pr_debug("read from file '%pD' at %lld returns %zd/%zu\n",
 		 fp, (long long) *pos, retlen, len);
 
 	if (retlen > 0)
@@ -248,7 +248,7 @@ static ssize_t hmcdrv_dev_write(struct file *fp, const char __user *ubuf,
 {
 	ssize_t retlen;
 
-	pr_debug("writing file '/dev/%pD' at pos. %lld with length %zd\n",
+	pr_debug("writing file '%pD' at pos. %lld with length %zd\n",
 		 fp, (long long) *pos, len);
 
 	if (!fp->private_data) { /* first expect a cmd write */
@@ -272,7 +272,7 @@ static ssize_t hmcdrv_dev_write(struct file *fp, const char __user *ubuf,
 	if (retlen > 0)
 		*pos += retlen;
 
-	pr_debug("write to file '/dev/%pD' returned %zd\n", fp, retlen);
+	pr_debug("write to file '%pD' returned %zd\n", fp, retlen);
 
 	return retlen;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 1/3] fs: introduce helper d_path_fast()
  2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
@ 2021-05-28 12:37   ` kernel test robot
  2021-05-28 12:44   ` Al Viro
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 28+ messages in thread
From: kernel test robot @ 2021-05-28 12:37 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4990 bytes --]

Hi Jia,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on linux/master]
[also build test ERROR on s390/features linus/master v5.13-rc3 next-20210528]
[cannot apply to pmladek/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jia-He/make-pD-print-full-path-for-file/20210528-194137
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git dd860052c99b1e088352bdd4fb7aef46f8d2ef47
config: i386-randconfig-m021-20210528 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/b51dc225479bec60540f41d58a12cf99ff8548d4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jia-He/make-pD-print-full-path-for-file/20210528-194137
        git checkout b51dc225479bec60540f41d58a12cf99ff8548d4
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   fs/d_path.c: In function 'd_path_fast':
>> fs/d_path.c:302:2: error: implicit declaration of function 'DECLARE_BUFFER' [-Werror=implicit-function-declaration]
     302 |  DECLARE_BUFFER(b, buf, buflen);
         |  ^~~~~~~~~~~~~~
>> fs/d_path.c:302:17: error: 'b' undeclared (first use in this function); did you mean 'mb'?
     302 |  DECLARE_BUFFER(b, buf, buflen);
         |                 ^
         |                 mb
   fs/d_path.c:302:17: note: each undeclared identifier is reported only once for each function it appears in
>> fs/d_path.c:307:14: error: passing argument 2 of 'prepend' from incompatible pointer type [-Werror=incompatible-pointer-types]
     307 |  prepend(&b, "", 1);
         |              ^~
         |              |
         |              char *
   fs/d_path.c:11:40: note: expected 'int *' but argument is of type 'char *'
      11 | static int prepend(char **buffer, int *buflen, const char *str, int namelen)
         |                                   ~~~~~^~~~~~
>> fs/d_path.c:307:18: warning: passing argument 3 of 'prepend' makes pointer from integer without a cast [-Wint-conversion]
     307 |  prepend(&b, "", 1);
         |                  ^
         |                  |
         |                  int
   fs/d_path.c:11:60: note: expected 'const char *' but argument is of type 'int'
      11 | static int prepend(char **buffer, int *buflen, const char *str, int namelen)
         |                                                ~~~~~~~~~~~~^~~
>> fs/d_path.c:307:2: error: too few arguments to function 'prepend'
     307 |  prepend(&b, "", 1);
         |  ^~~~~~~
   fs/d_path.c:11:12: note: declared here
      11 | static int prepend(char **buffer, int *buflen, const char *str, int namelen)
         |            ^~~~~~~
>> fs/d_path.c:308:2: error: implicit declaration of function '__prepend_path'; did you mean 'prepend_path'? [-Werror=implicit-function-declaration]
     308 |  __prepend_path(path->dentry, mnt, &root, &b);
         |  ^~~~~~~~~~~~~~
         |  prepend_path
>> fs/d_path.c:311:9: error: implicit declaration of function 'extract_string'; did you mean 'match_string'? [-Werror=implicit-function-declaration]
     311 |  return extract_string(&b);
         |         ^~~~~~~~~~~~~~
         |         match_string
   fs/d_path.c: At top level:
   fs/d_path.c:336:7: warning: no previous prototype for 'simple_dname' [-Wmissing-prototypes]
     336 | char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
         |       ^~~~~~~~~~~~
   fs/d_path.c: In function 'd_path_fast':
   fs/d_path.c:312:1: error: control reaches end of non-void function [-Werror=return-type]
     312 | }
         | ^
   cc1: some warnings being treated as errors


vim +/DECLARE_BUFFER +302 fs/d_path.c

   293	
   294	/**
   295	 * d_path_fast - fast return the full path of a dentry without taking
   296	 * any seqlock/spinlock. This helper is typical for debugging purpose
   297	 */
   298	char *d_path_fast(const struct path *path, char *buf, int buflen)
   299	{
   300		struct path root;
   301		struct mount *mnt = real_mount(path->mnt);
 > 302		DECLARE_BUFFER(b, buf, buflen);
   303	
   304		rcu_read_lock();
   305		get_fs_root_rcu(current->fs, &root);
   306	
 > 307		prepend(&b, "", 1);
 > 308		__prepend_path(path->dentry, mnt, &root, &b);
   309		rcu_read_unlock();
   310	
 > 311		return extract_string(&b);
   312	}
   313	EXPORT_SYMBOL(d_path_fast);
   314	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 36361 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 1/3] fs: introduce helper d_path_fast()
  2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
  2021-05-28 12:37   ` kernel test robot
@ 2021-05-28 12:44   ` Al Viro
  2021-05-28 12:51   ` Matthew Wilcox
  2021-05-28 16:02   ` kernel test robot
  3 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2021-05-28 12:44 UTC (permalink / raw)
  To: Jia He
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet, Luca Coelho,
	Kalle Valo, David S. Miller, Jakub Kicinski, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Johannes Berg, linux-doc,
	linux-kernel, linux-wireless, netdev, linux-s390

On Fri, May 28, 2021 at 07:39:49PM +0800, Jia He wrote:

> +/**
> + * d_path_fast - fast return the full path of a dentry without taking
> + * any seqlock/spinlock. This helper is typical for debugging purpose
> + */
> +char *d_path_fast(const struct path *path, char *buf, int buflen)
> +{
> +	struct path root;
> +	struct mount *mnt = real_mount(path->mnt);
> +	DECLARE_BUFFER(b, buf, buflen);
> +
> +	rcu_read_lock();
> +	get_fs_root_rcu(current->fs, &root);
> +
> +	prepend(&b, "", 1);
> +	__prepend_path(path->dentry, mnt, &root, &b);
> +	rcu_read_unlock();
> +
> +	return extract_string(&b);
> +}
> +EXPORT_SYMBOL(d_path_fast);

Umm...  I'd suggest failing if __prepend_path() returns 3 (at least)...

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 1/3] fs: introduce helper d_path_fast()
  2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
  2021-05-28 12:37   ` kernel test robot
  2021-05-28 12:44   ` Al Viro
@ 2021-05-28 12:51   ` Matthew Wilcox
  2021-05-28 14:23     ` Justin He
  2021-05-28 16:02   ` kernel test robot
  3 siblings, 1 reply; 28+ messages in thread
From: Matthew Wilcox @ 2021-05-28 12:51 UTC (permalink / raw)
  To: Jia He
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

On Fri, May 28, 2021 at 07:39:49PM +0800, Jia He wrote:
> +/**
> + * d_path_fast - fast return the full path of a dentry without taking
> + * any seqlock/spinlock. This helper is typical for debugging purpose
> + */
> +char *d_path_fast(const struct path *path, char *buf, int buflen)

I'd suggest calling it d_path_unsafe().  Otherwise people will call it
instead of d_path because who doesn't like fast?

> +{
> +	struct path root;
> +	struct mount *mnt = real_mount(path->mnt);
> +	DECLARE_BUFFER(b, buf, buflen);
> +
> +	rcu_read_lock();
> +	get_fs_root_rcu(current->fs, &root);
> +
> +	prepend(&b, "", 1);
> +	__prepend_path(path->dentry, mnt, &root, &b);
> +	rcu_read_unlock();
> +
> +	return extract_string(&b);
> +}
> +EXPORT_SYMBOL(d_path_fast);

Why export it?  What module needs this?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 11:39 ` [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file Jia He
@ 2021-05-28 12:59   ` Matthew Wilcox
  2021-05-28 14:22     ` Justin He
  2021-05-30 20:51   ` kernel test robot
  1 sibling, 1 reply; 28+ messages in thread
From: Matthew Wilcox @ 2021-05-28 12:59 UTC (permalink / raw)
  To: Jia He
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

On Fri, May 28, 2021 at 07:39:50PM +0800, Jia He wrote:
> We have '%pD' for printing a filename. It may not be perfect (by
> default it only prints one component.)
> 
> As suggested by Linus at [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 "file_dentry_name()" simply shouldn't use "dentry_name()" at all.
> Despite that shared code origin, and despite that similar letter
> choice (lower-vs-upper case), a dentry and a file really are very
> different from a name standpoint.
> 
> Here stack space is preferred for file_d_path_name() because it is
> much safer. The stack size 256 is a compromise between stack overflow
> and too short full path.

How is it "safer"?  You already have a buffer passed from the caller.
Are you saying that d_path_fast() might overrun a really small buffer
but won't overrun a 256 byte buffer?

> @@ -920,13 +921,25 @@ char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_sp
>  }
>  
>  static noinline_for_stack
> -char *file_dentry_name(char *buf, char *end, const struct file *f,
> +char *file_d_path_name(char *buf, char *end, const struct file *f,
>  			struct printf_spec spec, const char *fmt)
>  {
> +	const struct path *path;
> +	char *p;
> +	char full_path[256];
> +
>  	if (check_pointer(&buf, end, f, spec))
>  		return buf;
>  
> -	return dentry_name(buf, end, f->f_path.dentry, spec, fmt);
> +	path = &f->f_path;
> +	if (check_pointer(&buf, end, path, spec))
> +		return buf;
> +
> +	p = d_path_fast(path, full_path, sizeof(full_path));
> +	if (IS_ERR(p))
> +		return err_ptr(buf, end, p, spec);
> +
> +	return string_nocheck(buf, end, p, spec);
>  }
>  #ifdef CONFIG_BLOCK
>  static noinline_for_stack

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 12:59   ` Matthew Wilcox
@ 2021-05-28 14:22     ` Justin He
  2021-05-28 14:52       ` Matthew Wilcox
  2021-05-28 20:06       ` Rasmus Villemoes
  0 siblings, 2 replies; 28+ messages in thread
From: Justin He @ 2021-05-28 14:22 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390


Hi Matthew
> -----Original Message-----
> From: Matthew Wilcox <willy@infradead.org>
> Sent: Friday, May 28, 2021 9:00 PM
> To: Justin He <Justin.He@arm.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>; Petr Mladek
> <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>; Sergey
> Senozhatsky <senozhatsky@chromium.org>; Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>; Rasmus Villemoes
> <linux@rasmusvillemoes.dk>; Jonathan Corbet <corbet@lwn.net>; Alexander
> Viro <viro@zeniv.linux.org.uk>; Luca Coelho <luciano.coelho@intel.com>;
> Kalle Valo <kvalo@codeaurora.org>; David S. Miller <davem@davemloft.net>;
> Jakub Kicinski <kuba@kernel.org>; Heiko Carstens <hca@linux.ibm.com>;
> Vasily Gorbik <gor@linux.ibm.com>; Christian Borntraeger
> <borntraeger@de.ibm.com>; Johannes Berg <johannes.berg@intel.com>; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> wireless@vger.kernel.org; netdev@vger.kernel.org; linux-
> s390@vger.kernel.org
> Subject: Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path
> for file
>
> On Fri, May 28, 2021 at 07:39:50PM +0800, Jia He wrote:
> > We have '%pD' for printing a filename. It may not be perfect (by
> > default it only prints one component.)
> >
> > As suggested by Linus at [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 "file_dentry_name()" simply shouldn't use "dentry_name()" at all.
> > Despite that shared code origin, and despite that similar letter
> > choice (lower-vs-upper case), a dentry and a file really are very
> > different from a name standpoint.
> >
> > Here stack space is preferred for file_d_path_name() because it is
> > much safer. The stack size 256 is a compromise between stack overflow
> > and too short full path.
>
> How is it "safer"?  You already have a buffer passed from the caller.
> Are you saying that d_path_fast() might overrun a really small buffer
> but won't overrun a 256 byte buffer?
No, it won't overrun a 256 byte buf. When the full path size is larger than 256, the p->len is < 0 in prepend_name, and this overrun will be
dectected in extract_string() with "-ENAMETOOLONG".

Each printk contains 2 vsnprintf. vsnprintf() returns the required size after formatting the string.
1. vprintk_store() will invoke 1st vsnprintf() will 8 bytes space to get the reserve_size. In this case, the _buf_ could be less than _end_ by design.
2. Then it invokes 2nd printk_sprint()->vscnprintf()->vsnprintf() to really fill the space.

If we choose the stack space, it can meet above 2 cases.

If we pass the parameter like:
p = d_path_fast(path, buf, end - buf);
We need to handle the complicated logic in prepend_name()
I have tried this way in local test, the code logic is very complicated
and not so graceful.
e.g. I need to firstly go through the loop and get the full path size of
that file. And then return reserved_size for that 1st vsnprintf

Thanks for any suggestion

--
Cheers,
Justin (Jia He)

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH RFCv2 1/3] fs: introduce helper d_path_fast()
  2021-05-28 12:51   ` Matthew Wilcox
@ 2021-05-28 14:23     ` Justin He
  0 siblings, 0 replies; 28+ messages in thread
From: Justin He @ 2021-05-28 14:23 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390



> -----Original Message-----
> From: Matthew Wilcox <willy@infradead.org>
> Sent: Friday, May 28, 2021 8:52 PM
> To: Justin He <Justin.He@arm.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>; Petr Mladek
> <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>; Sergey
> Senozhatsky <senozhatsky@chromium.org>; Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>; Rasmus Villemoes
> <linux@rasmusvillemoes.dk>; Jonathan Corbet <corbet@lwn.net>; Alexander
> Viro <viro@zeniv.linux.org.uk>; Luca Coelho <luciano.coelho@intel.com>;
> Kalle Valo <kvalo@codeaurora.org>; David S. Miller <davem@davemloft.net>;
> Jakub Kicinski <kuba@kernel.org>; Heiko Carstens <hca@linux.ibm.com>;
> Vasily Gorbik <gor@linux.ibm.com>; Christian Borntraeger
> <borntraeger@de.ibm.com>; Johannes Berg <johannes.berg@intel.com>; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> wireless@vger.kernel.org; netdev@vger.kernel.org; linux-
> s390@vger.kernel.org
> Subject: Re: [PATCH RFCv2 1/3] fs: introduce helper d_path_fast()
>
> On Fri, May 28, 2021 at 07:39:49PM +0800, Jia He wrote:
> > +/**
> > + * d_path_fast - fast return the full path of a dentry without taking
> > + * any seqlock/spinlock. This helper is typical for debugging purpose
> > + */
> > +char *d_path_fast(const struct path *path, char *buf, int buflen)
>
> I'd suggest calling it d_path_unsafe().  Otherwise people will call it
> instead of d_path because who doesn't like fast?
>
Okay, thanks

> > +{
> > +   struct path root;
> > +   struct mount *mnt = real_mount(path->mnt);
> > +   DECLARE_BUFFER(b, buf, buflen);
> > +
> > +   rcu_read_lock();
> > +   get_fs_root_rcu(current->fs, &root);
> > +
> > +   prepend(&b, "", 1);
> > +   __prepend_path(path->dentry, mnt, &root, &b);
> > +   rcu_read_unlock();
> > +
> > +   return extract_string(&b);
> > +}
> > +EXPORT_SYMBOL(d_path_fast);
>
> Why export it?  What module needs this?
Okay, indeed

--
Cheers,
Justin (Jia He)


IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 14:22     ` Justin He
@ 2021-05-28 14:52       ` Matthew Wilcox
  2021-05-28 15:09         ` Justin He
  2021-05-28 20:06       ` Rasmus Villemoes
  1 sibling, 1 reply; 28+ messages in thread
From: Matthew Wilcox @ 2021-05-28 14:52 UTC (permalink / raw)
  To: Justin He
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

On Fri, May 28, 2021 at 02:22:01PM +0000, Justin He wrote:
> > On Fri, May 28, 2021 at 07:39:50PM +0800, Jia He wrote:
> > > We have '%pD' for printing a filename. It may not be perfect (by
> > > default it only prints one component.)
> > >
> > > As suggested by Linus at [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 "file_dentry_name()" simply shouldn't use "dentry_name()" at all.
> > > Despite that shared code origin, and despite that similar letter
> > > choice (lower-vs-upper case), a dentry and a file really are very
> > > different from a name standpoint.
> > >
> > > Here stack space is preferred for file_d_path_name() because it is
> > > much safer. The stack size 256 is a compromise between stack overflow
> > > and too short full path.
> >
> > How is it "safer"?  You already have a buffer passed from the caller.
> > Are you saying that d_path_fast() might overrun a really small buffer
> > but won't overrun a 256 byte buffer?
> No, it won't overrun a 256 byte buf. When the full path size is larger than 256, the p->len is < 0 in prepend_name, and this overrun will be
> dectected in extract_string() with "-ENAMETOOLONG".
> 
> Each printk contains 2 vsnprintf. vsnprintf() returns the required size after formatting the string.
> 1. vprintk_store() will invoke 1st vsnprintf() will 8 bytes space to get the reserve_size. In this case, the _buf_ could be less than _end_ by design.
> 2. Then it invokes 2nd printk_sprint()->vscnprintf()->vsnprintf() to really fill the space.

I think you need to explain _that_ in the commit log, not make some
nebulous claim of "safer".

> If we choose the stack space, it can meet above 2 cases.
> 
> If we pass the parameter like:
> p = d_path_fast(path, buf, end - buf);
> We need to handle the complicated logic in prepend_name()
> I have tried this way in local test, the code logic is very complicated
> and not so graceful.
> e.g. I need to firstly go through the loop and get the full path size of
> that file. And then return reserved_size for that 1st vsnprintf

I'm not sure why it's so complicated.  p->len records how many bytes
are needed for the entire path; can't you just return -p->len ?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 14:52       ` Matthew Wilcox
@ 2021-05-28 15:09         ` Justin He
  2021-05-28 15:22           ` Matthew Wilcox
  0 siblings, 1 reply; 28+ messages in thread
From: Justin He @ 2021-05-28 15:09 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

Hi Matthew

> -----Original Message-----
> From: Matthew Wilcox <willy@infradead.org>
> Sent: Friday, May 28, 2021 10:53 PM
> To: Justin He <Justin.He@arm.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>; Petr Mladek
> <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>; Sergey
> Senozhatsky <senozhatsky@chromium.org>; Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>; Rasmus Villemoes
> <linux@rasmusvillemoes.dk>; Jonathan Corbet <corbet@lwn.net>; Alexander
> Viro <viro@zeniv.linux.org.uk>; Luca Coelho <luciano.coelho@intel.com>;
> Kalle Valo <kvalo@codeaurora.org>; David S. Miller <davem@davemloft.net>;
> Jakub Kicinski <kuba@kernel.org>; Heiko Carstens <hca@linux.ibm.com>;
> Vasily Gorbik <gor@linux.ibm.com>; Christian Borntraeger
> <borntraeger@de.ibm.com>; Johannes Berg <johannes.berg@intel.com>; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> wireless@vger.kernel.org; netdev@vger.kernel.org; linux-
> s390@vger.kernel.org
> Subject: Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path
> for file
>
> On Fri, May 28, 2021 at 02:22:01PM +0000, Justin He wrote:
> > > On Fri, May 28, 2021 at 07:39:50PM +0800, Jia He wrote:
> > > > We have '%pD' for printing a filename. It may not be perfect (by
> > > > default it only prints one component.)
> > > >
> > > > As suggested by Linus at [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 "file_dentry_name()" simply shouldn't use "dentry_name()" at
> all.
> > > > Despite that shared code origin, and despite that similar letter
> > > > choice (lower-vs-upper case), a dentry and a file really are very
> > > > different from a name standpoint.
> > > >
> > > > Here stack space is preferred for file_d_path_name() because it is
> > > > much safer. The stack size 256 is a compromise between stack
> overflow
> > > > and too short full path.
> > >
> > > How is it "safer"?  You already have a buffer passed from the caller.
> > > Are you saying that d_path_fast() might overrun a really small buffer
> > > but won't overrun a 256 byte buffer?
> > No, it won't overrun a 256 byte buf. When the full path size is larger
> than 256, the p->len is < 0 in prepend_name, and this overrun will be
> > dectected in extract_string() with "-ENAMETOOLONG".
> >
> > Each printk contains 2 vsnprintf. vsnprintf() returns the required size
> after formatting the string.
> > 1. vprintk_store() will invoke 1st vsnprintf() will 8 bytes space to get
> the reserve_size. In this case, the _buf_ could be less than _end_ by
> design.
> > 2. Then it invokes 2nd printk_sprint()->vscnprintf()->vsnprintf() to
> really fill the space.
>
> I think you need to explain _that_ in the commit log, not make some
> nebulous claim of "safer".

Okay

>
> > If we choose the stack space, it can meet above 2 cases.
> >
> > If we pass the parameter like:
> > p = d_path_fast(path, buf, end - buf);
> > We need to handle the complicated logic in prepend_name()
> > I have tried this way in local test, the code logic is very complicated
> > and not so graceful.
> > e.g. I need to firstly go through the loop and get the full path size of
> > that file. And then return reserved_size for that 1st vsnprintf
>
> I'm not sure why it's so complicated.  p->len records how many bytes
> are needed for the entire path; can't you just return -p->len ?

prepend_name() will return at the beginning if p->len is <0 in this case,
we can't even get the correct full path size if keep __prepend_path unchanged.
We need another new helper __prepend_path_size() to get the full path size
regardless of the negative value p->len.

More than that, even the 1st vsnprintf could have _end_ > _buf_ in some case:
What if printk("%pD", filp) ? The 1st vsnprintf has positive (end-buf).

This make things more complicated.

Hope I have described it clearly as above.

--
Cheers,
Justin (Jia He)


IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 15:09         ` Justin He
@ 2021-05-28 15:22           ` Matthew Wilcox
  2021-05-31  0:39             ` Justin He
  2021-06-01 14:42             ` Justin He
  0 siblings, 2 replies; 28+ messages in thread
From: Matthew Wilcox @ 2021-05-28 15:22 UTC (permalink / raw)
  To: Justin He
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

On Fri, May 28, 2021 at 03:09:28PM +0000, Justin He wrote:
> > I'm not sure why it's so complicated.  p->len records how many bytes
> > are needed for the entire path; can't you just return -p->len ?
> 
> prepend_name() will return at the beginning if p->len is <0 in this case,
> we can't even get the correct full path size if keep __prepend_path unchanged.
> We need another new helper __prepend_path_size() to get the full path size
> regardless of the negative value p->len.

It's a little hard to follow, based on just the patches.  Is there a
git tree somewhere of Al's patches that you're based on?

Seems to me that prepend_name() is just fine because it updates p->len
before returning false:

 static bool prepend_name(struct prepend_buffer *p, const struct qstr *name)
 {
 	const char *dname = smp_load_acquire(&name->name); /* ^^^ */
 	u32 dlen = READ_ONCE(name->len);
 	char *s;

 	p->len -= dlen + 1;
 	if (unlikely(p->len < 0))
 		return false;

I think the only change you'd need to make for vsnprintf() is in
prepend_path():

-		if (!prepend_name(&b, &dentry->d_name))
-			break;
+		prepend_name(&b, &dentry->d_name);

Would that hurt anything else?

> More than that, even the 1st vsnprintf could have _end_ > _buf_ in some case:
> What if printk("%pD", filp) ? The 1st vsnprintf has positive (end-buf).

I don't understand the problem ... if p->len is positive, then you
succeeded.  if p->len is negative then -p->len is the expected return
value from vsnprintf().  No?


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 1/3] fs: introduce helper d_path_fast()
  2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
                     ` (2 preceding siblings ...)
  2021-05-28 12:51   ` Matthew Wilcox
@ 2021-05-28 16:02   ` kernel test robot
  3 siblings, 0 replies; 28+ messages in thread
From: kernel test robot @ 2021-05-28 16:02 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4328 bytes --]

Hi Jia,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on linux/master]
[also build test ERROR on s390/features linus/master v5.13-rc3 next-20210528]
[cannot apply to pmladek/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jia-He/make-pD-print-full-path-for-file/20210528-194137
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git dd860052c99b1e088352bdd4fb7aef46f8d2ef47
config: s390-randconfig-r026-20210528 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 6505c630407c5feec818f0bb1c284f9eeebf2071)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/0day-ci/linux/commit/b51dc225479bec60540f41d58a12cf99ff8548d4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jia-He/make-pD-print-full-path-for-file/20210528-194137
        git checkout b51dc225479bec60540f41d58a12cf99ff8548d4
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> fs/d_path.c:302:2: error: implicit declaration of function 'DECLARE_BUFFER' [-Werror,-Wimplicit-function-declaration]
           DECLARE_BUFFER(b, buf, buflen);
           ^
>> fs/d_path.c:302:17: error: use of undeclared identifier 'b'
           DECLARE_BUFFER(b, buf, buflen);
                          ^
   fs/d_path.c:307:11: error: use of undeclared identifier 'b'
           prepend(&b, "", 1);
                    ^
>> fs/d_path.c:308:2: error: implicit declaration of function '__prepend_path' [-Werror,-Wimplicit-function-declaration]
           __prepend_path(path->dentry, mnt, &root, &b);
           ^
   fs/d_path.c:308:2: note: did you mean 'prepend_path'?
   fs/d_path.c:75:12: note: 'prepend_path' declared here
   static int prepend_path(const struct path *path,
              ^
   fs/d_path.c:308:44: error: use of undeclared identifier 'b'
           __prepend_path(path->dentry, mnt, &root, &b);
                                                     ^
>> fs/d_path.c:311:9: error: implicit declaration of function 'extract_string' [-Werror,-Wimplicit-function-declaration]
           return extract_string(&b);
                  ^
   fs/d_path.c:311:25: error: use of undeclared identifier 'b'
           return extract_string(&b);
                                  ^
   fs/d_path.c:336:7: warning: no previous prototype for function 'simple_dname' [-Wmissing-prototypes]
   char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
         ^
   fs/d_path.c:336:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
   ^
   static 
   1 warning and 7 errors generated.


vim +/DECLARE_BUFFER +302 fs/d_path.c

   293	
   294	/**
   295	 * d_path_fast - fast return the full path of a dentry without taking
   296	 * any seqlock/spinlock. This helper is typical for debugging purpose
   297	 */
   298	char *d_path_fast(const struct path *path, char *buf, int buflen)
   299	{
   300		struct path root;
   301		struct mount *mnt = real_mount(path->mnt);
 > 302		DECLARE_BUFFER(b, buf, buflen);
   303	
   304		rcu_read_lock();
   305		get_fs_root_rcu(current->fs, &root);
   306	
   307		prepend(&b, "", 1);
 > 308		__prepend_path(path->dentry, mnt, &root, &b);
   309		rcu_read_unlock();
   310	
 > 311		return extract_string(&b);
   312	}
   313	EXPORT_SYMBOL(d_path_fast);
   314	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 17893 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 14:22     ` Justin He
  2021-05-28 14:52       ` Matthew Wilcox
@ 2021-05-28 20:06       ` Rasmus Villemoes
  2021-05-30 15:18         ` Matthew Wilcox
  1 sibling, 1 reply; 28+ messages in thread
From: Rasmus Villemoes @ 2021-05-28 20:06 UTC (permalink / raw)
  To: Justin He, Matthew Wilcox
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Jonathan Corbet, Alexander Viro, Luca Coelho,
	Kalle Valo, David S. Miller, Jakub Kicinski, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Johannes Berg, linux-doc,
	linux-kernel, linux-wireless, netdev, linux-s390

On 28/05/2021 16.22, Justin He wrote:
> 
>> From: Matthew Wilcox <willy@infradead.org>

>> How is it "safer"?  You already have a buffer passed from the caller.
>> Are you saying that d_path_fast() might overrun a really small buffer
>> but won't overrun a 256 byte buffer?
> No, it won't overrun a 256 byte buf. When the full path size is larger than 256, the p->len is < 0 in prepend_name, and this overrun will be
> dectected in extract_string() with "-ENAMETOOLONG".
> 
> Each printk contains 2 vsnprintf. vsnprintf() returns the required size after formatting the string.>
> 1. vprintk_store() will invoke 1st vsnprintf() will 8 bytes space to get the reserve_size. In this case, the _buf_ could be less than _end_ by design.
> 2. Then it invokes 2nd printk_sprint()->vscnprintf()->vsnprintf() to really fill the space.

Please do not assume that printk is the only user of vsnprintf() or the
only one that would use a given %p<foo> extension.

Also, is it clear that nothing can change underneath you in between two
calls to vsnprintf()? IOW, is it certain that the path will fit upon a
second call using the size returned from the first?

Rasmus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 20:06       ` Rasmus Villemoes
@ 2021-05-30 15:18         ` Matthew Wilcox
  2021-05-31  9:40           ` Petr Mladek
  0 siblings, 1 reply; 28+ messages in thread
From: Matthew Wilcox @ 2021-05-30 15:18 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: Justin He, Linus Torvalds, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, Andy Shevchenko, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

On Fri, May 28, 2021 at 10:06:37PM +0200, Rasmus Villemoes wrote:
> On 28/05/2021 16.22, Justin He wrote:
> > 
> >> From: Matthew Wilcox <willy@infradead.org>
> 
> >> How is it "safer"?  You already have a buffer passed from the caller.
> >> Are you saying that d_path_fast() might overrun a really small buffer
> >> but won't overrun a 256 byte buffer?
> > No, it won't overrun a 256 byte buf. When the full path size is larger than 256, the p->len is < 0 in prepend_name, and this overrun will be
> > dectected in extract_string() with "-ENAMETOOLONG".
> > 
> > Each printk contains 2 vsnprintf. vsnprintf() returns the required size after formatting the string.>
> > 1. vprintk_store() will invoke 1st vsnprintf() will 8 bytes space to get the reserve_size. In this case, the _buf_ could be less than _end_ by design.
> > 2. Then it invokes 2nd printk_sprint()->vscnprintf()->vsnprintf() to really fill the space.
> 
> Please do not assume that printk is the only user of vsnprintf() or the
> only one that would use a given %p<foo> extension.
> 
> Also, is it clear that nothing can change underneath you in between two
> calls to vsnprintf()? IOW, is it certain that the path will fit upon a
> second call using the size returned from the first?

No, but that's also true of %s.  I think vprintk_store() is foolish to
do it this way.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 11:39 ` [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file Jia He
  2021-05-28 12:59   ` Matthew Wilcox
@ 2021-05-30 20:51   ` kernel test robot
  1 sibling, 0 replies; 28+ messages in thread
From: kernel test robot @ 2021-05-30 20:51 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3611 bytes --]

Hi Jia,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on linux/master]
[also build test WARNING on s390/features linus/master v5.13-rc3 next-20210528]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jia-He/make-pD-print-full-path-for-file/20210528-194137
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git dd860052c99b1e088352bdd4fb7aef46f8d2ef47
config: x86_64-randconfig-b001-20210527 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 6505c630407c5feec818f0bb1c284f9eeebf2071)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # apt-get install iwyu # include-what-you-use
        # https://github.com/0day-ci/linux/commit/46d55769e0c29791bfb6709a1085ba8af749a71e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jia-He/make-pD-print-full-path-for-file/20210528-194137
        git checkout 46d55769e0c29791bfb6709a1085ba8af749a71e
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross C=1 CHECK=iwyu ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


iwyu warnings: (new ones prefixed by >>)
   lib/vsprintf.c:52:1: iwyu: warning: superfluous #include <asm/byteorder.h>
   lib/vsprintf.c:51:1: iwyu: warning: superfluous #include <asm/page.h>
   lib/vsprintf.c:22:1: iwyu: warning: superfluous #include <linux/clk.h>
>> lib/vsprintf.c:35:1: iwyu: warning: superfluous #include <linux/dcache.h>
   lib/vsprintf.c:25:1: iwyu: warning: superfluous #include <linux/module.h>
   lib/vsprintf.c:37:1: iwyu: warning: superfluous #include <linux/rtc.h>
   lib/vsprintf.c:33:1: iwyu: warning: superfluous #include <linux/uaccess.h>

vim +35 lib/vsprintf.c

4b6ccca701ef59 Al Viro           2013-09-03 @35  #include <linux/dcache.h>
312b4e226951f7 Ryan Mallon       2013-11-12  36  #include <linux/cred.h>
4d42c44727a062 Andy Shevchenko   2018-12-04  37  #include <linux/rtc.h>
7daac5b2fdf88e Andy Shevchenko   2020-04-15  38  #include <linux/time.h>
2b1b0d66704a8c Andy Shevchenko   2016-05-20  39  #include <linux/uuid.h>
ce4fecf1fe1518 Pantelis Antoniou 2015-01-21  40  #include <linux/of.h>
8a27f7c90ffcb7 Joe Perches       2009-08-17  41  #include <net/addrconf.h>
ad67b74d2469d9 Tobin C. Harding  2017-11-01  42  #include <linux/siphash.h>
ad67b74d2469d9 Tobin C. Harding  2017-11-01  43  #include <linux/compiler.h>
a92eb7621b9fb2 Sakari Ailus      2019-10-03  44  #include <linux/property.h>
1031bc589228ca Dmitry Monakhov   2015-04-13  45  #ifdef CONFIG_BLOCK
1031bc589228ca Dmitry Monakhov   2015-04-13  46  #include <linux/blkdev.h>
1031bc589228ca Dmitry Monakhov   2015-04-13  47  #endif
^1da177e4c3f41 Linus Torvalds    2005-04-16  48  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

_______________________________________________
kbuild mailing list -- kbuild(a)lists.01.org
To unsubscribe send an email to kbuild-leave(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 32324 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 15:22           ` Matthew Wilcox
@ 2021-05-31  0:39             ` Justin He
  2021-06-01 14:42             ` Justin He
  1 sibling, 0 replies; 28+ messages in thread
From: Justin He @ 2021-05-31  0:39 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390



> -----Original Message-----
> From: Matthew Wilcox <willy@infradead.org>
> Sent: Friday, May 28, 2021 11:22 PM
> To: Justin He <Justin.He@arm.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>; Petr Mladek
> <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>; Sergey
> Senozhatsky <senozhatsky@chromium.org>; Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>; Rasmus Villemoes
> <linux@rasmusvillemoes.dk>; Jonathan Corbet <corbet@lwn.net>; Alexander
> Viro <viro@zeniv.linux.org.uk>; Luca Coelho <luciano.coelho@intel.com>;
> Kalle Valo <kvalo@codeaurora.org>; David S. Miller <davem@davemloft.net>;
> Jakub Kicinski <kuba@kernel.org>; Heiko Carstens <hca@linux.ibm.com>;
> Vasily Gorbik <gor@linux.ibm.com>; Christian Borntraeger
> <borntraeger@de.ibm.com>; Johannes Berg <johannes.berg@intel.com>; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> wireless@vger.kernel.org; netdev@vger.kernel.org; linux-
> s390@vger.kernel.org
> Subject: Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path
> for file
>
> On Fri, May 28, 2021 at 03:09:28PM +0000, Justin He wrote:
> > > I'm not sure why it's so complicated.  p->len records how many bytes
> > > are needed for the entire path; can't you just return -p->len ?
> >
> > prepend_name() will return at the beginning if p->len is <0 in this case,
> > we can't even get the correct full path size if keep __prepend_path
> unchanged.
> > We need another new helper __prepend_path_size() to get the full path
> size
> > regardless of the negative value p->len.
>
> It's a little hard to follow, based on just the patches.  Is there a
> git tree somewhere of Al's patches that you're based on?

The git tree of Al's patches is at:
https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git/log/?h=work.d_path

>
> Seems to me that prepend_name() is just fine because it updates p->len
> before returning false:
>
>  static bool prepend_name(struct prepend_buffer *p, const struct qstr
> *name)
>  {
>       const char *dname = smp_load_acquire(&name->name); /* ^^^ */
>       u32 dlen = READ_ONCE(name->len);
>       char *s;
>
>       p->len -= dlen + 1;
>       if (unlikely(p->len < 0))
>               return false;
>
> I think the only change you'd need to make for vsnprintf() is in
> prepend_path():
>
> -             if (!prepend_name(&b, &dentry->d_name))
> -                     break;
> +             prepend_name(&b, &dentry->d_name);
>
> Would that hurt anything else?
I will try your suggestion soon.

>
> > More than that, even the 1st vsnprintf could have _end_ > _buf_ in some
> case:
> > What if printk("%pD", filp) ? The 1st vsnprintf has positive (end-buf).
>
> I don't understand the problem ... if p->len is positive, then you
> succeeded.  if p->len is negative then -p->len is the expected return
> value from vsnprintf().  No?

There are 3 cases I once met in my debugging:
1. p->len is positive but too small (e.g. end-buf is 6). In first prepend_name
loop p-len-=dlen, then p->len is negative

2. p->len is negative at the very beginning (i.e. end-buf is negative)

3. p->len positive and large enough. Typically the 2nd vsnprintf of printk


--
Cheers,
Justin (Jia He)


IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-30 15:18         ` Matthew Wilcox
@ 2021-05-31  9:40           ` Petr Mladek
  0 siblings, 0 replies; 28+ messages in thread
From: Petr Mladek @ 2021-05-31  9:40 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Rasmus Villemoes, Justin He, Linus Torvalds, Steven Rostedt,
	Sergey Senozhatsky, Andy Shevchenko, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

On Sun 2021-05-30 16:18:23, Matthew Wilcox wrote:
> On Fri, May 28, 2021 at 10:06:37PM +0200, Rasmus Villemoes wrote:
> > On 28/05/2021 16.22, Justin He wrote:
> > > 
> > >> From: Matthew Wilcox <willy@infradead.org>
> > 
> > >> How is it "safer"?  You already have a buffer passed from the caller.
> > >> Are you saying that d_path_fast() might overrun a really small buffer
> > >> but won't overrun a 256 byte buffer?
> > > No, it won't overrun a 256 byte buf. When the full path size is larger than 256, the p->len is < 0 in prepend_name, and this overrun will be
> > > dectected in extract_string() with "-ENAMETOOLONG".
> > > 
> > > Each printk contains 2 vsnprintf. vsnprintf() returns the required size after formatting the string.>
> > > 1. vprintk_store() will invoke 1st vsnprintf() will 8 bytes space to get the reserve_size. In this case, the _buf_ could be less than _end_ by design.
> > > 2. Then it invokes 2nd printk_sprint()->vscnprintf()->vsnprintf() to really fill the space.
> > 
> > Please do not assume that printk is the only user of vsnprintf() or the
> > only one that would use a given %p<foo> extension.
> > 
> > Also, is it clear that nothing can change underneath you in between two
> > calls to vsnprintf()? IOW, is it certain that the path will fit upon a
> > second call using the size returned from the first?
> 
> No, but that's also true of %s.  I think vprintk_store() is foolish to
> do it this way.

Just for record. vprintk_store() is foolish here by intention.
It avoids the need of static per-CPU X per-context buffers
and it is simple.

I believe that it should be good enough in practice. Any race here
would make the result racy anyway.

Of course, we might need to reconsider it if there are real life
problems with this approach.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-05-28 15:22           ` Matthew Wilcox
  2021-05-31  0:39             ` Justin He
@ 2021-06-01 14:42             ` Justin He
  2021-06-01 15:30               ` Matthew Wilcox
  1 sibling, 1 reply; 28+ messages in thread
From: Justin He @ 2021-06-01 14:42 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390

Hi Matthew

> -----Original Message-----
> From: Matthew Wilcox <willy@infradead.org>
> Sent: Friday, May 28, 2021 11:22 PM
> To: Justin He <Justin.He@arm.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>; Petr Mladek
> <pmladek@suse.com>; Steven Rostedt <rostedt@goodmis.org>; Sergey
> Senozhatsky <senozhatsky@chromium.org>; Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>; Rasmus Villemoes
> <linux@rasmusvillemoes.dk>; Jonathan Corbet <corbet@lwn.net>; Alexander
> Viro <viro@zeniv.linux.org.uk>; Luca Coelho <luciano.coelho@intel.com>;
> Kalle Valo <kvalo@codeaurora.org>; David S. Miller <davem@davemloft.net>;
> Jakub Kicinski <kuba@kernel.org>; Heiko Carstens <hca@linux.ibm.com>;
> Vasily Gorbik <gor@linux.ibm.com>; Christian Borntraeger
> <borntraeger@de.ibm.com>; Johannes Berg <johannes.berg@intel.com>; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> wireless@vger.kernel.org; netdev@vger.kernel.org; linux-
> s390@vger.kernel.org
> Subject: Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path
> for file
>
> On Fri, May 28, 2021 at 03:09:28PM +0000, Justin He wrote:
> > > I'm not sure why it's so complicated.  p->len records how many bytes
> > > are needed for the entire path; can't you just return -p->len ?
> >
> > prepend_name() will return at the beginning if p->len is <0 in this case,
> > we can't even get the correct full path size if keep __prepend_path
> unchanged.
> > We need another new helper __prepend_path_size() to get the full path
> size
> > regardless of the negative value p->len.
>
> It's a little hard to follow, based on just the patches.  Is there a
> git tree somewhere of Al's patches that you're based on?
>
> Seems to me that prepend_name() is just fine because it updates p->len
> before returning false:
>
>  static bool prepend_name(struct prepend_buffer *p, const struct qstr
> *name)
>  {
>       const char *dname = smp_load_acquire(&name->name); /* ^^^ */
>       u32 dlen = READ_ONCE(name->len);
>       char *s;
>
>       p->len -= dlen + 1;
>       if (unlikely(p->len < 0))
>               return false;
>
> I think the only change you'd need to make for vsnprintf() is in
> prepend_path():
>
> -             if (!prepend_name(&b, &dentry->d_name))
> -                     break;
> +             prepend_name(&b, &dentry->d_name);
>
> Would that hurt anything else?
>

It almost works except the snprintf case,
Consider,assuming filp path is 256 bytes, 2 dentries "/root/$long_string":
snprintf(buffer, 128, "%pD", filp);
p->len is positive at first, but negative after prepend_name loop.
So, it will not fill any bytes in _buffer_.
But in theory, it should fill the beginning 127 bytes and '\0'.

What do you think of it?

--
Cheers,
Justin (Jia He)


> > More than that, even the 1st vsnprintf could have _end_ > _buf_ in some
> case:
> > What if printk("%pD", filp) ? The 1st vsnprintf has positive (end-buf).
>
> I don't understand the problem ... if p->len is positive, then you
> succeeded.  if p->len is negative then -p->len is the expected return
> value from vsnprintf().  No?

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 14:42             ` Justin He
@ 2021-06-01 15:30               ` Matthew Wilcox
  2021-06-01 15:36                 ` Andy Shevchenko
  0 siblings, 1 reply; 28+ messages in thread
From: Matthew Wilcox @ 2021-06-01 15:30 UTC (permalink / raw)
  To: Justin He
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Andy Shevchenko, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, linux-fsdevel

somehow the linux-fsdevel mailing list got dropped from this revision
of the patch set.  anyone who's following along may wish to refer to
the archives:
https://lore.kernel.org/linux-doc/20210528113951.6225-1-justin.he@arm.com/

On Tue, Jun 01, 2021 at 02:42:15PM +0000, Justin He wrote:
> > On Fri, May 28, 2021 at 03:09:28PM +0000, Justin He wrote:
> > > > I'm not sure why it's so complicated.  p->len records how many bytes
> > > > are needed for the entire path; can't you just return -p->len ?
> > >
> > > prepend_name() will return at the beginning if p->len is <0 in this case,
> > > we can't even get the correct full path size if keep __prepend_path
> > unchanged.
> > > We need another new helper __prepend_path_size() to get the full path
> > size
> > > regardless of the negative value p->len.
> >
> > It's a little hard to follow, based on just the patches.  Is there a
> > git tree somewhere of Al's patches that you're based on?
> >
> > Seems to me that prepend_name() is just fine because it updates p->len
> > before returning false:
> >
> >  static bool prepend_name(struct prepend_buffer *p, const struct qstr
> > *name)
> >  {
> >       const char *dname = smp_load_acquire(&name->name); /* ^^^ */
> >       u32 dlen = READ_ONCE(name->len);
> >       char *s;
> >
> >       p->len -= dlen + 1;
> >       if (unlikely(p->len < 0))
> >               return false;
> >
> > I think the only change you'd need to make for vsnprintf() is in
> > prepend_path():
> >
> > -             if (!prepend_name(&b, &dentry->d_name))
> > -                     break;
> > +             prepend_name(&b, &dentry->d_name);
> >
> > Would that hurt anything else?
> >
> 
> It almost works except the snprintf case,
> Consider,assuming filp path is 256 bytes, 2 dentries "/root/$long_string":
> snprintf(buffer, 128, "%pD", filp);
> p->len is positive at first, but negative after prepend_name loop.
> So, it will not fill any bytes in _buffer_.
> But in theory, it should fill the beginning 127 bytes and '\0'.

I have a few thoughts ...

1. Do we actually depend on that anywhere?
2. Is that something we should support?
3. We could print the start of the filename, if we do.  So something like
this ...

static void prepend(struct prepend_buffer *p, const char *str, int namelen)
{
	p->len -= namelen;
	if (likely(p->len >= 0)) {
		p->buf -= namelen;
		memcpy(p->buf, str, namelen);
	} else {
		char *s = p->buf;
		int buflen = strlen(p->buf);

		/* The first time we overflow the buffer */
		if (p->len + namelen > 0) {
			p->buf -= p->len + namelen;
			buflen += p->len + namelen;
		}

		if (buflen > namelen) {
			memmove(p->buf + namelen, s, buflen - namelen);
			memcpy(p->buf, str, namelen);
		} else {
			memcpy(p->buf, str, buflen);
		}
	}
}

I haven't tested this; it's probably full of confusion and off-by-one
errors.  But I hope you get the point -- we continue to accumulate
p->len to indicate how many characters we shifted off the right of the
buffer while adding the (start of) the filename on the left.

4. If we want the end of the filename instead, that looks easier:

static void prepend(struct prepend_buffer *p, const char *str, int namelen)
{
	p->len -= namelen;
	if (likely(p->len >= 0)) {
		p->buf -= namelen;
		memcpy(p->buf, str, namelen);
	} else if (p->len + namelen > 0) {
		p->buf -= p->len + namelen;
		memcpy(p->buf, str - p->len, p->len + namelen)
	}
}

But I don't think we want any of this at all.  Just don't put anything
in the buffer if the user didn't supply enough space.  As long as you
get the return value right, they know the string is bad (or they don't
care if the string is bad)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 15:30               ` Matthew Wilcox
@ 2021-06-01 15:36                 ` Andy Shevchenko
  2021-06-01 15:44                   ` Matthew Wilcox
  0 siblings, 1 reply; 28+ messages in thread
From: Andy Shevchenko @ 2021-06-01 15:36 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Justin He, Linus Torvalds, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, Andy Shevchenko, Rasmus Villemoes,
	Jonathan Corbet, Alexander Viro, Luca Coelho, Kalle Valo,
	David S. Miller, Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Linux FS Devel

On Tue, Jun 1, 2021 at 6:32 PM Matthew Wilcox <willy@infradead.org> wrote:
> On Tue, Jun 01, 2021 at 02:42:15PM +0000, Justin He wrote:

...

> Just don't put anything
> in the buffer if the user didn't supply enough space.  As long as you
> get the return value right, they know the string is bad (or they don't
> care if the string is bad)

It might be that I'm out of context here, but printf() functionality
in the kernel (vsprintf() if being precise)  and its users consider
that it should fill buffer up to the end of whatever space is
available.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 15:36                 ` Andy Shevchenko
@ 2021-06-01 15:44                   ` Matthew Wilcox
  2021-06-01 15:53                     ` Andy Shevchenko
  0 siblings, 1 reply; 28+ messages in thread
From: Matthew Wilcox @ 2021-06-01 15:44 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Justin He, Linus Torvalds, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, Andy Shevchenko, Rasmus Villemoes,
	Jonathan Corbet, Alexander Viro, Luca Coelho, Kalle Valo,
	David S. Miller, Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Linux FS Devel

On Tue, Jun 01, 2021 at 06:36:41PM +0300, Andy Shevchenko wrote:
> On Tue, Jun 1, 2021 at 6:32 PM Matthew Wilcox <willy@infradead.org> wrote:
> > On Tue, Jun 01, 2021 at 02:42:15PM +0000, Justin He wrote:
> 
> ...
> 
> > Just don't put anything
> > in the buffer if the user didn't supply enough space.  As long as you
> > get the return value right, they know the string is bad (or they don't
> > care if the string is bad)
> 
> It might be that I'm out of context here, but printf() functionality
> in the kernel (vsprintf() if being precise)  and its users consider
> that it should fill buffer up to the end of whatever space is
> available.

Do they though?  What use is it to specify a small buffer, print a
large filename into it and then use that buffer, knowing that it wasn't
big enough?  That would help decide whether we should print the
start or the end of the filename.

Remember, we're going for usefulness here, not abiding by the letter of
the standard under all circumstances, no matter the cost.  At least
partially because we're far outside the standard here; POSIX does
not specify what %pD does.

"The argument shall be a pointer to void. The value of the
pointer is converted to a sequence of printable characters, in an
implementation-defined manner."


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 15:44                   ` Matthew Wilcox
@ 2021-06-01 15:53                     ` Andy Shevchenko
  2021-06-01 16:10                       ` Andy Shevchenko
  0 siblings, 1 reply; 28+ messages in thread
From: Andy Shevchenko @ 2021-06-01 15:53 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Justin He, Linus Torvalds, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Linux FS Devel

On Tue, Jun 01, 2021 at 04:44:00PM +0100, Matthew Wilcox wrote:
> On Tue, Jun 01, 2021 at 06:36:41PM +0300, Andy Shevchenko wrote:
> > On Tue, Jun 1, 2021 at 6:32 PM Matthew Wilcox <willy@infradead.org> wrote:
> > > On Tue, Jun 01, 2021 at 02:42:15PM +0000, Justin He wrote:
> > 
> > ...
> > 
> > > Just don't put anything
> > > in the buffer if the user didn't supply enough space.  As long as you
> > > get the return value right, they know the string is bad (or they don't
> > > care if the string is bad)
> > 
> > It might be that I'm out of context here, but printf() functionality
> > in the kernel (vsprintf() if being precise)  and its users consider
> > that it should fill buffer up to the end of whatever space is
> > available.
> 
> Do they though?  What use is it to specify a small buffer, print a
> large filename into it and then use that buffer, knowing that it wasn't
> big enough?  That would help decide whether we should print the
> start or the end of the filename.
> 
> Remember, we're going for usefulness here, not abiding by the letter of
> the standard under all circumstances, no matter the cost.  At least
> partially because we're far outside the standard here; POSIX does
> not specify what %pD does.
> 
> "The argument shall be a pointer to void. The value of the
> pointer is converted to a sequence of printable characters, in an
> implementation-defined manner."

All nice words, but don't forget kasprintf() or other usages like this.
For the same input we have to have the same result independently on the room in
the buffer.

So, if I print "Hello, World" I should always get it, not "Monkey's Paw".
I.o.w.

 snprintf(10) ==> "Hello, Wor"
 snprintf(5)  ==> "Hello"
 snprintf(2)  !=> "Mo"
 snprintf(1)  !=> "M"
 snprintf(1)  ==> "H"

Inconsistency here is really not what we want.


-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 15:53                     ` Andy Shevchenko
@ 2021-06-01 16:10                       ` Andy Shevchenko
  2021-06-01 17:05                         ` Matthew Wilcox
  0 siblings, 1 reply; 28+ messages in thread
From: Andy Shevchenko @ 2021-06-01 16:10 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Justin He, Linus Torvalds, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Linux FS Devel

On Tue, Jun 01, 2021 at 06:53:26PM +0300, Andy Shevchenko wrote:
> On Tue, Jun 01, 2021 at 04:44:00PM +0100, Matthew Wilcox wrote:
> > On Tue, Jun 01, 2021 at 06:36:41PM +0300, Andy Shevchenko wrote:
> > > On Tue, Jun 1, 2021 at 6:32 PM Matthew Wilcox <willy@infradead.org> wrote:
> > > > On Tue, Jun 01, 2021 at 02:42:15PM +0000, Justin He wrote:
> > > 
> > > ...
> > > 
> > > > Just don't put anything
> > > > in the buffer if the user didn't supply enough space.  As long as you
> > > > get the return value right, they know the string is bad (or they don't
> > > > care if the string is bad)
> > > 
> > > It might be that I'm out of context here, but printf() functionality
> > > in the kernel (vsprintf() if being precise)  and its users consider
> > > that it should fill buffer up to the end of whatever space is
> > > available.
> > 
> > Do they though?  What use is it to specify a small buffer, print a
> > large filename into it and then use that buffer, knowing that it wasn't
> > big enough?  That would help decide whether we should print the
> > start or the end of the filename.
> > 
> > Remember, we're going for usefulness here, not abiding by the letter of
> > the standard under all circumstances, no matter the cost.  At least
> > partially because we're far outside the standard here; POSIX does
> > not specify what %pD does.
> > 
> > "The argument shall be a pointer to void. The value of the
> > pointer is converted to a sequence of printable characters, in an
> > implementation-defined manner."
> 
> All nice words, but don't forget kasprintf() or other usages like this.
> For the same input we have to have the same result independently on the room in
> the buffer.
> 
> So, if I print "Hello, World" I should always get it, not "Monkey's Paw".
> I.o.w.
> 
>  snprintf(10) ==> "Hello, Wor"
>  snprintf(5)  ==> "Hello"
>  snprintf(2)  !=> "Mo"
>  snprintf(1)  !=> "M"
>  snprintf(1)  ==> "H"
> 
> Inconsistency here is really not what we want.

I have to add that in light of the topic those characters should be counted
from the end of the filename. So, we will give user as much as possible of useful
information. I.o.w. always print the last part of filename up to the buffer
size or if the filename is shorter than buffer we will have it in full.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 16:10                       ` Andy Shevchenko
@ 2021-06-01 17:05                         ` Matthew Wilcox
  2021-06-01 19:01                           ` Rasmus Villemoes
  0 siblings, 1 reply; 28+ messages in thread
From: Matthew Wilcox @ 2021-06-01 17:05 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Justin He, Linus Torvalds, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, Rasmus Villemoes, Jonathan Corbet,
	Alexander Viro, Luca Coelho, Kalle Valo, David S. Miller,
	Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Linux FS Devel

On Tue, Jun 01, 2021 at 07:10:41PM +0300, Andy Shevchenko wrote:
> On Tue, Jun 01, 2021 at 06:53:26PM +0300, Andy Shevchenko wrote:
> > On Tue, Jun 01, 2021 at 04:44:00PM +0100, Matthew Wilcox wrote:
> > > On Tue, Jun 01, 2021 at 06:36:41PM +0300, Andy Shevchenko wrote:
> > > > On Tue, Jun 1, 2021 at 6:32 PM Matthew Wilcox <willy@infradead.org> wrote:
> > > > > On Tue, Jun 01, 2021 at 02:42:15PM +0000, Justin He wrote:
> > > > 
> > > > ...
> > > > 
> > > > > Just don't put anything
> > > > > in the buffer if the user didn't supply enough space.  As long as you
> > > > > get the return value right, they know the string is bad (or they don't
> > > > > care if the string is bad)
> > > > 
> > > > It might be that I'm out of context here, but printf() functionality
> > > > in the kernel (vsprintf() if being precise)  and its users consider
> > > > that it should fill buffer up to the end of whatever space is
> > > > available.
> > > 
> > > Do they though?  What use is it to specify a small buffer, print a
> > > large filename into it and then use that buffer, knowing that it wasn't
> > > big enough?  That would help decide whether we should print the
> > > start or the end of the filename.
> > > 
> > > Remember, we're going for usefulness here, not abiding by the letter of
> > > the standard under all circumstances, no matter the cost.  At least
> > > partially because we're far outside the standard here; POSIX does
> > > not specify what %pD does.
> > > 
> > > "The argument shall be a pointer to void. The value of the
> > > pointer is converted to a sequence of printable characters, in an
> > > implementation-defined manner."
> > 
> > All nice words, but don't forget kasprintf() or other usages like this.
> > For the same input we have to have the same result independently on the room in
> > the buffer.
> > 
> > So, if I print "Hello, World" I should always get it, not "Monkey's Paw".
> > I.o.w.
> > 
> >  snprintf(10) ==> "Hello, Wor"
> >  snprintf(5)  ==> "Hello"
> >  snprintf(2)  !=> "Mo"
> >  snprintf(1)  !=> "M"
> >  snprintf(1)  ==> "H"
> > 
> > Inconsistency here is really not what we want.
> 
> I have to add that in light of the topic those characters should be counted
> from the end of the filename. So, we will give user as much as possible of useful
> information. I.o.w. always print the last part of filename up to the buffer
> size or if the filename is shorter than buffer we will have it in full.

Ah, not monkey's paw, but donkey hoof then ...

Here's some examples, what do you think makes sense?

snprintf(buf, 16, "bad file '%pD'\n", q);

what content do you want buf to have when q is variously:

1. /abcd/efgh
2. /a/bcdefgh.iso
3. /abcdef/gh

I would argue that
"bad file ''\n"
is actually a better string to have than any of (case 2)
"bad file '/a/bc"
"bad file 'bcdef"
"bad file 'h.iso"

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 17:05                         ` Matthew Wilcox
@ 2021-06-01 19:01                           ` Rasmus Villemoes
  2021-06-02  5:47                             ` Justin He
  0 siblings, 1 reply; 28+ messages in thread
From: Rasmus Villemoes @ 2021-06-01 19:01 UTC (permalink / raw)
  To: Matthew Wilcox, Andy Shevchenko
  Cc: Justin He, Linus Torvalds, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, Jonathan Corbet, Alexander Viro, Luca Coelho,
	Kalle Valo, David S. Miller, Jakub Kicinski, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Johannes Berg, linux-doc,
	linux-kernel, linux-wireless, netdev, linux-s390, Linux FS Devel

On 01/06/2021 19.05, Matthew Wilcox wrote:

> Here's some examples, what do you think makes sense?
> 
> snprintf(buf, 16, "bad file '%pD'\n", q);
> 
> what content do you want buf to have when q is variously:
> 
> 1. /abcd/efgh
> 2. /a/bcdefgh.iso
> 3. /abcdef/gh
> 
> I would argue that
> "bad file ''\n"
> is actually a better string to have than any of (case 2)
> "bad file '/a/bc"
> "bad file 'bcdef"
> "bad file 'h.iso"
> 

Whatever ends up being decided, _please_ document that in
machine-readable and -verifiable form. I.e., update lib/test_printf.c
accordingly.

Currently (and originally) it only tests %pd because %pD is/was
essentially just %pd with an indirection to get the struct dentry* from
a struct file*.

The existing framework is strongly centered around expecting '/a/bc (see
all the logic where we do multiple checks with size 0, size random, size
plenty, and for the random case check that the buffer contents match the
complete output up till the randomly chosen size), so adding tests for
some other semantics would require a bit more juggling.

Not that that should be an argument in favor of that behaviour. But FWIW
that would be my preference.

Rasmus



^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file
  2021-06-01 19:01                           ` Rasmus Villemoes
@ 2021-06-02  5:47                             ` Justin He
  0 siblings, 0 replies; 28+ messages in thread
From: Justin He @ 2021-06-02  5:47 UTC (permalink / raw)
  To: Rasmus Villemoes, Matthew Wilcox, Andy Shevchenko
  Cc: Linus Torvalds, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	Jonathan Corbet, Alexander Viro, Luca Coelho, Kalle Valo,
	David S. Miller, Jakub Kicinski, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Johannes Berg, linux-doc, linux-kernel,
	linux-wireless, netdev, linux-s390, Linux FS Devel

Hi Rasmus

> -----Original Message-----
> From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> Sent: Wednesday, June 2, 2021 3:02 AM
> To: Matthew Wilcox <willy@infradead.org>; Andy Shevchenko
> <andy.shevchenko@gmail.com>
> Cc: Justin He <Justin.He@arm.com>; Linus Torvalds <torvalds@linux-
> foundation.org>; Petr Mladek <pmladek@suse.com>; Steven Rostedt
> <rostedt@goodmis.org>; Sergey Senozhatsky <senozhatsky@chromium.org>;
> Jonathan Corbet <corbet@lwn.net>; Alexander Viro <viro@zeniv.linux.org.uk>;
> Luca Coelho <luciano.coelho@intel.com>; Kalle Valo <kvalo@codeaurora.org>;
> David S. Miller <davem@davemloft.net>; Jakub Kicinski <kuba@kernel.org>;
> Heiko Carstens <hca@linux.ibm.com>; Vasily Gorbik <gor@linux.ibm.com>;
> Christian Borntraeger <borntraeger@de.ibm.com>; Johannes Berg
> <johannes.berg@intel.com>; linux-doc@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-wireless@vger.kernel.org;
> netdev@vger.kernel.org; linux-s390@vger.kernel.org; Linux FS Devel <linux-
> fsdevel@vger.kernel.org>
> Subject: Re: [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for
> file
>
> On 01/06/2021 19.05, Matthew Wilcox wrote:
>
> > Here's some examples, what do you think makes sense?
> >
> > snprintf(buf, 16, "bad file '%pD'\n", q);
> >
> > what content do you want buf to have when q is variously:
> >
> > 1. /abcd/efgh
> > 2. /a/bcdefgh.iso
> > 3. /abcdef/gh
> >
> > I would argue that
> > "bad file ''\n"
> > is actually a better string to have than any of (case 2)
> > "bad file '/a/bc"
> > "bad file 'bcdef"
> > "bad file 'h.iso"
> >
>
> Whatever ends up being decided, _please_ document that in
> machine-readable and -verifiable form. I.e., update lib/test_printf.c
> accordingly.
>
> Currently (and originally) it only tests %pd because %pD is/was
> essentially just %pd with an indirection to get the struct dentry* from
> a struct file*.

Okay, I can add more test_printf cases for '%pD'

>
> The existing framework is strongly centered around expecting '/a/bc (see
> all the logic where we do multiple checks with size 0, size random, size
> plenty, and for the random case check that the buffer contents match the
> complete output up till the randomly chosen size), so adding tests for
> some other semantics would require a bit more juggling.
>

Yes, agree.
In other way, if the user:
char* full_path = d_path(...);
snprintf("%s", limited_size, full_path);

He/she will get the inconsistent result if we return "" for '%pD'.

--
Cheers,
Justin (Jia He)

> Not that that should be an argument in favor of that behaviour. But FWIW
> that would be my preference.
>
> Rasmus
>

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2021-06-02  5:48 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-28 11:39 [PATCH RFCv2 0/3] make '%pD' print full path for file Jia He
2021-05-28 11:39 ` [PATCH RFCv2 1/3] fs: introduce helper d_path_fast() Jia He
2021-05-28 12:37   ` kernel test robot
2021-05-28 12:44   ` Al Viro
2021-05-28 12:51   ` Matthew Wilcox
2021-05-28 14:23     ` Justin He
2021-05-28 16:02   ` kernel test robot
2021-05-28 11:39 ` [PATCH RFCv2 2/3] lib/vsprintf.c: make %pD print full path for file Jia He
2021-05-28 12:59   ` Matthew Wilcox
2021-05-28 14:22     ` Justin He
2021-05-28 14:52       ` Matthew Wilcox
2021-05-28 15:09         ` Justin He
2021-05-28 15:22           ` Matthew Wilcox
2021-05-31  0:39             ` Justin He
2021-06-01 14:42             ` Justin He
2021-06-01 15:30               ` Matthew Wilcox
2021-06-01 15:36                 ` Andy Shevchenko
2021-06-01 15:44                   ` Matthew Wilcox
2021-06-01 15:53                     ` Andy Shevchenko
2021-06-01 16:10                       ` Andy Shevchenko
2021-06-01 17:05                         ` Matthew Wilcox
2021-06-01 19:01                           ` Rasmus Villemoes
2021-06-02  5:47                             ` Justin He
2021-05-28 20:06       ` Rasmus Villemoes
2021-05-30 15:18         ` Matthew Wilcox
2021-05-31  9:40           ` Petr Mladek
2021-05-30 20:51   ` kernel test robot
2021-05-28 11:39 ` [PATCH RFCv2 3/3] s390/hmcdrv: remove the redundant directory path in debug message Jia He

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.