Tomas M:
> As usual, I forgot to note my kernel version, I am sorry.
> I am using 2.6.24-rc4 kernel.
:::
> > mknod empty/console c 5 1
> > mount -t aufs -o br:empty=rw aufs union
> > ls -l union
> > # in my case, the console device is entirely wrong now
I see XFS in linux-2.6.24-rc[34] changed the semantics of inode
attribute (i_rdev).
Here is a patch for it.
If you succeed, the patch will be included in next Monday release.
Junjiro Okajima
----------------------------------------------------------------------
diff -x CVS -x RCS -x .pdiff -rup ../../aufs.anon/aufs/fs/aufs/Makefile
./fs/aufs/Makefile
--- ../../aufs.anon/aufs/fs/aufs/Makefile 2007-12-03 10:44:05.000000000
+0900
+++ ./fs/aufs/Makefile 2007-12-12 02:56:13.416928552 +0900
@@ -24,6 +24,16 @@ fuse = $(shell grep '\#.*define.*FUSE_SU
EXTRA_CFLAGS += -DFUSE_SUPER_MAGIC=${fuse}
endif
+ifeq ($(strip $(shell test ${SUBLEVEL} -ge 24 && echo t)),t)
+ifdef CONFIG_XFS_FS
+# it isn't defined in a header file
+xfs = $(shell grep '\#.*define.*XFS_SB_MAGIC' ${srctree}/fs/xfs/xfs_sb.h | \
+ head -n 1 | \
+ awk '{print $$3}')
+EXTRA_CFLAGS += -DXFS_SB_MAGIC=${xfs}
+endif
+endif
+
ifdef CONFIG_TMPFS
# it isn't defined in a header file
tmpfs = $(shell grep '\#.*define.*TMPFS_MAGIC' ${srctree}/mm/shmem.c | \
diff -x CVS -x RCS -x .pdiff -rup ../../aufs.anon/aufs/fs/aufs/cpup.c
./fs/aufs/cpup.c
--- ../../aufs.anon/aufs/fs/aufs/cpup.c 2007-11-26 23:32:05.000000000 +0900
+++ ./fs/aufs/cpup.c 2007-12-12 02:46:17.432531952 +0900
@@ -106,7 +106,8 @@ void au_cpup_attr_all(struct inode *inod
switch (inode->i_mode & S_IFMT) {
case S_IFBLK:
case S_IFCHR:
- inode->i_rdev = h_inode->i_rdev;
+ inode->i_rdev = au_h_rdev(h_inode, /*h_mnt*/NULL,
+ /*h_dentry*/NULL);
}
inode->i_blkbits = h_inode->i_blkbits;
au_cpup_attr_blksize(inode, h_inode);
@@ -388,7 +389,9 @@ static int cpup_entry(struct dentry *den
/*FALLTHROUGH*/
case S_IFIFO:
case S_IFSOCK:
- err = vfsub_mknod(h_dir, h_dst, mode, h_inode->i_rdev, dlgt);
+ err = vfsub_mknod(h_dir, h_dst, mode,
+ au_h_rdev(h_inode, /*h_mnt*/NULL, h_src),
+ dlgt);
//if (LktrCond) {vfs_unlink(h_dir, h_dst); err = -1;}
break;
default:
diff -x CVS -x RCS -x .pdiff -rup ../../aufs.anon/aufs/fs/aufs/inode.c
./fs/aufs/inode.c
--- ../../aufs.anon/aufs/fs/aufs/inode.c 2007-12-10 10:22:41.000000000
+0900
+++ ./fs/aufs/inode.c 2007-12-12 02:39:49.265542304 +0900
@@ -162,8 +162,8 @@ int au_refresh_hinode(struct inode *inod
static int set_inode(struct inode *inode, struct dentry *dentry)
{
int err, isdir;
- struct dentry *hidden_dentry;
- struct inode *hidden_inode;
+ struct dentry *h_dentry;
+ struct inode *h_inode;
umode_t mode;
aufs_bindex_t bindex, bstart, btail;
struct aufs_iinfo *iinfo;
@@ -172,15 +172,15 @@ static int set_inode(struct inode *inode
LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(dentry));
AuDebugOn(!(inode->i_state & I_NEW));
IiMustWriteLock(inode);
- hidden_dentry = au_h_dptr(dentry);
- AuDebugOn(!hidden_dentry);
- hidden_inode = hidden_dentry->d_inode;
- AuDebugOn(!hidden_inode);
+ h_dentry = au_h_dptr(dentry);
+ AuDebugOn(!h_dentry);
+ h_inode = h_dentry->d_inode;
+ AuDebugOn(!h_inode);
err = 0;
isdir = 0;
bstart = dbstart(dentry);
- mode = hidden_inode->i_mode;
+ mode = h_inode->i_mode;
switch (mode & S_IFMT) {
case S_IFREG:
btail = dbtail(dentry);
@@ -200,7 +200,8 @@ static int set_inode(struct inode *inode
case S_IFIFO:
case S_IFSOCK:
btail = dbtail(dentry);
- init_special_inode(inode, mode, hidden_inode->i_rdev);
+ init_special_inode(inode, mode,
+ au_h_rdev(h_inode, /*h_mnt*/NULL, h_dentry));
break;
default:
AuIOErr("Unknown file type 0%o\n", mode);
@@ -213,11 +214,11 @@ static int set_inode(struct inode *inode
iinfo->ii_bstart = bstart;
iinfo->ii_bend = btail;
for (bindex = bstart; bindex <= btail; bindex++) {
- hidden_dentry = au_h_dptr_i(dentry, bindex);
- if (!hidden_dentry)
+ h_dentry = au_h_dptr_i(dentry, bindex);
+ if (!h_dentry)
continue;
- AuDebugOn(!hidden_dentry->d_inode);
- set_h_iptr(inode, bindex, igrab(hidden_dentry->d_inode), flags);
+ AuDebugOn(!h_dentry->d_inode);
+ set_h_iptr(inode, bindex, igrab(h_dentry->d_inode), flags);
}
au_cpup_attr_all(inode);
diff -x CVS -x RCS -x .pdiff -rup ../../aufs.anon/aufs/fs/aufs/super.h
./fs/aufs/super.h
--- ../../aufs.anon/aufs/fs/aufs/super.h 2007-12-10 10:22:41.000000000
+0900
+++ ./fs/aufs/super.h 2007-12-12 02:56:19.608987216 +0900
@@ -242,6 +242,21 @@ static inline int au_test_fuse(struct su
return ret;
}
+static inline int au_test_xfs(struct super_block *sb)
+{
+ int ret = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) \
+ && (defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE))
+#ifdef XFS_SB_MAGIC
+ BUILD_BUG_ON(XFS_SB_MAGIC != 0x58465342);
+ ret = (sb->s_magic == XFS_SB_MAGIC);
+#else
+ ret = !strcmp(au_sbtype(sb), "xfs");
+#endif
+#endif
+ return ret;
+}
+
static inline int au_test_nfs(struct super_block *sb)
{
#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
diff -x CVS -x RCS -x .pdiff -rup ../../aufs.anon/aufs/fs/aufs/vfsub.c
./fs/aufs/vfsub.c
--- ../../aufs.anon/aufs/fs/aufs/vfsub.c 2007-12-10 10:31:58.000000000
+0900
+++ ./fs/aufs/vfsub.c 2007-12-12 03:55:08.278547904 +0900
@@ -1040,6 +1040,54 @@ int au_update_fuse_h_inode(struct vfsmou
}
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) \
+ && (defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE))
+/* h_mnt can be NULL, is it safe? */
+dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt,
+ struct dentry *h_dentry)
+{
+ dev_t rdev;
+ int err;
+ struct kstat st;
+
+ LKTRTrace("hi%lu\n", h_inode->i_ino);
+ if (h_dentry)
+ LKTRTrace("%.*s\n", AuDLNPair(h_dentry));
+
+ rdev = h_inode->i_rdev;
+ if (!rdev || !au_test_xfs(h_inode->i_sb))
+ goto out;
+
+ rdev = 0;
+ if (!h_dentry) {
+ err = 0;
+ h_dentry = d_find_alias(h_inode);
+ if (unlikely(!h_dentry))
+ goto failure;
+ err = PTR_ERR(h_dentry);
+ if (IS_ERR(h_dentry)) {
+ h_dentry = NULL;
+ goto failure;
+ }
+ LKTRTrace("%.*s\n", AuDLNPair(h_dentry));
+ } else
+ dget(h_dentry);
+
+ err = vfsub_getattr(h_mnt, h_dentry, &st, /*dlgt*/0);
+ if (!err) {
+ rdev = st.rdev;
+ goto out; /* success */
+ }
+
+ failure:
+ AuIOErr("failed rdev for XFS inode, hi%lu, %d\n",
+ h_inode->i_ino, err);
+ out:
+ dput(h_dentry);
+ return rdev;
+}
+#endif /* xfs rdev */
+
#if 0 // temp
/*
* This function was born after a discussion with the FUSE developer.
diff -x CVS -x RCS -x .pdiff -rup ../../aufs.anon/aufs/fs/aufs/vfsub.h
./fs/aufs/vfsub.h
--- ../../aufs.anon/aufs/fs/aufs/vfsub.h 2007-11-26 23:32:05.000000000
+0900
+++ ./fs/aufs/vfsub.h 2007-12-12 02:56:05.695102448 +0900
@@ -216,6 +216,19 @@ int au_update_fuse_h_inode(struct vfsmou
}
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) \
+ && (defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE))
+dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt,
+ struct dentry *h_dentry);
+#else
+static inline
+dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt,
+ struct dentry *h_dentry)
+{
+ return h_inode->i_rdev;
+}
+#endif
+
/* simple abstractions, for future use */
static inline
int do_vfsub_permission(struct inode *inode, int mask, struct nameidata *nd)
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php