[Devel,RH7] docker: Revert "vfs: take stat's dev from mnt->sb"

Submitted by Pavel Tikhomirov on Aug. 24, 2016, 3:44 p.m.

Details

Message ID 1472053485-16872-1-git-send-email-ptikhomirov@virtuozzo.com
State New
Series "docker: Revert "vfs: take stat's dev from mnt->sb""
Headers show

Commit Message

Pavel Tikhomirov Aug. 24, 2016, 3:44 p.m.
This reverts commit ecfa1b0f7ba985e200e807941b5838943b266cb3.

All non-directory objects on overlayfs should report an st_dev from
lower or upper filesystem that is providing the object then call
stat(2) on it(Documentation/filesystems/overlayfs.txt). But in our
case file on overlayfs reports st_dev from overlayfs itself:

e.g.: on VZ7 host device is 57 but should be 64768:
mkdir /lower /upper /merged /work
mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,\
workdir=/work /merged
touch /merged/file
stat /merged/file | grep Device | awk '{print $1$2}'
  Device:39h/57d
cat /proc/self/mountinfo
  63 1 253:0 / / rw,relatime shared:1 - ext4
/dev/mapper/virtuozzo_pcs7-root rw,data=ordered
  149 63 0:57 / /merged rw,relatime shared:81 - overlay overlay
rw,lowerdir=/lower,upperdir=/upper,workdir=/work

Reason is in sys_stat->vfs_stat->vfs_fstatat->vfs_getattr:
1) Call ovl_getattr()->ovl_path_real() - find real object's path
2) Call ovl_getattr()->vfs_getattr() - find real object's s_dev
3) Replace it with overlay's s_dev, which is wrong.

We do not have simfs - remove step (3) and stat will be fine again.

*note: we need it for docker - when stat and fstat give different
s_dev ldconfig in glibc breaks, and thus docker-ui tests break.

https://jira.sw.ru/browse/PSBM-51255
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 fs/stat.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/stat.c b/fs/stat.c
index a423f63..d0ea7ef 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -14,7 +14,6 @@ 
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/pagemap.h>
-#include <linux/mount.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -48,14 +47,10 @@  int vfs_getattr(struct path *path, struct kstat *stat)
 		return retval;
 
 	if (inode->i_op->getattr)
-		retval = inode->i_op->getattr(path->mnt, path->dentry, stat);
-	else
-		generic_fillattr(inode, stat);
+		return inode->i_op->getattr(path->mnt, path->dentry, stat);
 
-	if (!retval)
-		stat->dev = path->mnt->mnt_sb->s_dev;
-
-	return retval;
+	generic_fillattr(inode, stat);
+	return 0;
 }
 
 EXPORT_SYMBOL(vfs_getattr);

Comments

Kirill Tkhai Aug. 24, 2016, 3:51 p.m.
Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>

On 24.08.2016 18:44, Pavel Tikhomirov wrote:
> This reverts commit ecfa1b0f7ba985e200e807941b5838943b266cb3.
> 
> All non-directory objects on overlayfs should report an st_dev from
> lower or upper filesystem that is providing the object then call
> stat(2) on it(Documentation/filesystems/overlayfs.txt). But in our
> case file on overlayfs reports st_dev from overlayfs itself:
> 
> e.g.: on VZ7 host device is 57 but should be 64768:
> mkdir /lower /upper /merged /work
> mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,\
> workdir=/work /merged
> touch /merged/file
> stat /merged/file | grep Device | awk '{print $1$2}'
>   Device:39h/57d
> cat /proc/self/mountinfo
>   63 1 253:0 / / rw,relatime shared:1 - ext4
> /dev/mapper/virtuozzo_pcs7-root rw,data=ordered
>   149 63 0:57 / /merged rw,relatime shared:81 - overlay overlay
> rw,lowerdir=/lower,upperdir=/upper,workdir=/work
> 
> Reason is in sys_stat->vfs_stat->vfs_fstatat->vfs_getattr:
> 1) Call ovl_getattr()->ovl_path_real() - find real object's path
> 2) Call ovl_getattr()->vfs_getattr() - find real object's s_dev
> 3) Replace it with overlay's s_dev, which is wrong.
> 
> We do not have simfs - remove step (3) and stat will be fine again.
> 
> *note: we need it for docker - when stat and fstat give different
> s_dev ldconfig in glibc breaks, and thus docker-ui tests break.
> 
> https://jira.sw.ru/browse/PSBM-51255
> Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
> ---
>  fs/stat.c | 11 +++--------
>  1 file changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/stat.c b/fs/stat.c
> index a423f63..d0ea7ef 100644
> --- a/fs/stat.c
> +++ b/fs/stat.c
> @@ -14,7 +14,6 @@
>  #include <linux/security.h>
>  #include <linux/syscalls.h>
>  #include <linux/pagemap.h>
> -#include <linux/mount.h>
>  
>  #include <asm/uaccess.h>
>  #include <asm/unistd.h>
> @@ -48,14 +47,10 @@ int vfs_getattr(struct path *path, struct kstat *stat)
>  		return retval;
>  
>  	if (inode->i_op->getattr)
> -		retval = inode->i_op->getattr(path->mnt, path->dentry, stat);
> -	else
> -		generic_fillattr(inode, stat);
> +		return inode->i_op->getattr(path->mnt, path->dentry, stat);
>  
> -	if (!retval)
> -		stat->dev = path->mnt->mnt_sb->s_dev;
> -
> -	return retval;
> +	generic_fillattr(inode, stat);
> +	return 0;
>  }
>  
>  EXPORT_SYMBOL(vfs_getattr);
>