Hi Hu,
thanks for looking into this.
Am 26.02.15 um 06:25 schrieb hujianyang:
Hi Atom2,
I didn't notice this before, but I had reproduced the situation as you
described. I'm not sure if it is a real problem.
My take on this is that stat, under all circumstances, should reliably
provide information about the device the queried entry resides on. In
case the entry only exists on the upperdir-device, overlayfs should not
fool the user that it instead resides in the r/o lowerdir when in fact
no such entry exists there.
In my view that's the only viable option to back-up (empty) directories
(from a running system) which only reside in the upperdir provided that
no backup is requested for the r/o (lower) file layer.
The performing of 'stat' in Overlayfs are different between files and
directories. Files directly call upper/lower getattr function but
directories will set @dev and @ino by Overlayfs superblock itself.
In my view that then seems to defeat the purpose of the device field for
the stat sys-calls for overlayfs.
See line 135 in fs/overlayfs/dir.c
"""
static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
int err;
enum ovl_path_type type;
struct path realpath;
type = ovl_path_real(dentry, &realpath);
err = vfs_getattr(&realpath, stat);
if (err)
return err;
stat->dev = dentry->d_sb->s_dev; // I think it's the cause.
stat->ino = dentry->d_inode->i_ino;
/*
* It's probably not worth it to count subdirs to get the
* correct link count. nlink=1 seems to pacify 'find' and
* other utilities.
*/
if (OVL_TYPE_MERGE(type))
stat->nlink = 1;
return 0;
}
"""
I don't have the Overlayfs code on 3.11 or 3.13. I've lookup the v11
code in Miklos's git tree:
git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git
and found the code had been changed since the earliest code I could
get. So I don't know the reason of this behavior. I guess it is used
for filesystem consistence: directories in the same superblock have
same device number?
Following that argument, why would that then be different for plain
files? In my understanding a directory in linux is not really different
from a file (both are just an abstraction of blocks from the underlying
block device) with the main difference being that the former's content
is interpreted by the file system code to allow traversal of
directories. So all operations that can be applied likewise to both
should provide consistent results between files and directories.
Probably there's a reason behind that difference, but it currently is
beyond me.
Thanks and regards Atom2
On 2015/2/21 2:15, Atom2 wrote:
I am using find with its printf "%D" option (provides the same information as stats device information "%d" - device number in decimal) to figure out whether a file system entry resides in the r/o lowerdir or the r/w upperdir of an overlayfs mounted filesystem. I distinguish between the two by getting the device number from a (plain) file know to be in the upperdir.
The use case behind that is to be able to backup only files from the upperdir for several systems sharing a common lowerdir filesystem. I have used that (scripted approach via rsync) now for quiet some time and a few kernels back and it seemed to have worked very well.
I think your requirement need to be reconsidering. Maybe we could keep
the @dev for a lower-only directory?
Add Cc Miklos.
Thanks,
Hu
Currently I am using kernel 3.17.7 on gentoo and I seem to observe a strange behaviour (which I do not recall to have seen before on 3.13 and 3.11) with my approach as follows:
.) plain files still work and the device number is correct
.) directories, however, always seem to reside in the lowerdir - even thoguh they do not exist there; in fact there's not a single file in the whole filesystem hierarchy that, according to stat/find, seems to reside in the upperdir:
please see the stat output for a file and a directory, both residing in the same (parent) directory which is completely located in the upperdir (and does not at all exist in the lowerdir):
# stat serial
File: ‘serial’
Size: 17 Blocks: 8 IO Block: 4096 regular file
Device: ca03h/51715d Inode: 88 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2014-02-19 19:01:56.278161346 +0100
Modify: 2014-02-19 19:01:56.278161346 +0100
Change: 2014-02-19 19:01:56.278161346 +0100
Birth: -
#
# stat certs/
File: ‘certs/’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: dh/13d Inode: 331140 Links: 2
Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2014-04-26 14:08:47.337968562 +0200
Modify: 2014-02-19 18:55:58.458161346 +0100
Change: 2014-02-19 18:55:58.458161346 +0100
Birth: -
For comparision, please see the stat of /bin which only resides in the lowerdir and does not exist in the upperdir:
# stat /bin
File: ‘/bin’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: dh/13d Inode: 401777 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-02-20 17:50:24.066368607 +0100
Modify: 2015-02-09 17:51:18.000000000 +0100
Change: 2015-02-09 23:58:06.011825328 +0100
Birth: -
I do not think that this is the expected behaviour and I am pretty confident that this was different on older kernels - or am I missing anything/doing anything wrong here?
--
To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html