From: Jan Rękorajski Date: Sun, 28 Jun 2015 16:38:11 +0000 (+0200) Subject: - updated aufs patch X-Git-Tag: auto/th/kernel-4.1.0-1~1 X-Git-Url: http://git.pld-linux.org/gitweb.cgi?a=commitdiff_plain;h=5527c038501e84d3608809658ed2ddeb73e78168;p=packages%2Fkernel.git - updated aufs patch --- diff --git a/kernel-aufs3+vserver.patch b/kernel-aufs4+vserver.patch similarity index 100% rename from kernel-aufs3+vserver.patch rename to kernel-aufs4+vserver.patch diff --git a/kernel-aufs3.patch b/kernel-aufs4.patch similarity index 96% rename from kernel-aufs3.patch rename to kernel-aufs4.patch index 53816565..505b512a 100644 --- a/kernel-aufs3.patch +++ b/kernel-aufs4.patch @@ -1,31 +1,31 @@ -aufs3.x-rcN kbuild patch +aufs4.x-rcN kbuild patch diff --git a/fs/Kconfig b/fs/Kconfig -index ec35851..a059d62 100644 +index 011f433..b1083f6 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -218,6 +218,7 @@ source "fs/sysv/Kconfig" +@@ -218,6 +218,7 @@ source "fs/pstore/Kconfig" + source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/exofs/Kconfig" - source "fs/f2fs/Kconfig" +source "fs/aufs/Kconfig" endif # MISC_FILESYSTEMS diff --git a/fs/Makefile b/fs/Makefile -index a88ac48..162500e 100644 +index cb92fd4..8c2df12 100644 --- a/fs/Makefile +++ b/fs/Makefile -@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules +@@ -127,3 +127,4 @@ obj-y += exofs/ # Multiple modules obj-$(CONFIG_CEPH_FS) += ceph/ obj-$(CONFIG_PSTORE) += pstore/ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ +obj-$(CONFIG_AUFS_FS) += aufs/ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild -index 68ceb97..0352fa4 100644 +index 1a0006a..ddad01a 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild -@@ -58,6 +58,7 @@ header-y += atmsvc.h +@@ -59,6 +59,7 @@ header-y += atmsvc.h header-y += atm_tcp.h header-y += atm_zatm.h header-y += audit.h @@ -33,13 +33,13 @@ index 68ceb97..0352fa4 100644 header-y += auto_fs4.h header-y += auto_fs.h header-y += auxvec.h -aufs3.x-rcN base patch +aufs4.x-rcN base patch diff --git a/MAINTAINERS b/MAINTAINERS -index efbcb50..30a1654 100644 +index d8afd29..feac5ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -1864,6 +1864,20 @@ F: include/linux/audit.h +@@ -1880,6 +1880,19 @@ F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -48,8 +48,7 @@ index efbcb50..30a1654 100644 +L: linux-unionfs@vger.kernel.org +L: aufs-users@lists.sourceforge.net (members only) +W: http://aufs.sourceforge.net -+T: git://git.code.sf.net/p/aufs/aufs3-linux -+T: git://github.com/sfjro/aufs3-linux.git ++T: git://github.com/sfjro/aufs4-linux.git +S: Supported +F: Documentation/filesystems/aufs/ +F: Documentation/ABI/testing/debugfs-aufs @@ -61,10 +60,10 @@ index efbcb50..30a1654 100644 M: Miguel Ojeda Sandonis W: http://miguelojeda.es/auxdisplay.htm diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index d1f168b..a0da519 100644 +index d7173cb..0160952 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -592,6 +592,24 @@ static inline int is_loop_device(struct file *file) +@@ -540,6 +540,24 @@ static inline int is_loop_device(struct file *file) return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; } @@ -90,10 +89,10 @@ index d1f168b..a0da519 100644 static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/dcache.c b/fs/dcache.c -index c71e373..b93a9f2 100644 +index 37b5afd..bc261e2 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1130,7 +1130,7 @@ enum d_walk_ret { +@@ -1164,7 +1164,7 @@ enum d_walk_ret { * * The @enter() and @finish() callbacks are called with d_lock held. */ @@ -102,11 +101,44 @@ index c71e373..b93a9f2 100644 enum d_walk_ret (*enter)(void *, struct dentry *), void (*finish)(void *)) { +diff --git a/fs/read_write.c b/fs/read_write.c +index 819ef3f..fd0414e 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, + } + EXPORT_SYMBOL(__vfs_write); + ++vfs_readf_t vfs_readf(struct file *file) ++{ ++ const struct file_operations *fop = file->f_op; ++ ++ if (fop->read) ++ return fop->read; ++ if (fop->read_iter) ++ return new_sync_read; ++ return ERR_PTR(-ENOSYS); ++} ++ ++vfs_writef_t vfs_writef(struct file *file) ++{ ++ const struct file_operations *fop = file->f_op; ++ ++ if (fop->write) ++ return fop->write; ++ if (fop->write_iter) ++ return new_sync_write; ++ return ERR_PTR(-ENOSYS); ++} ++ + ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) + { + mm_segment_t old_fs; diff --git a/fs/splice.c b/fs/splice.c -index 7968da9..beb9993 100644 +index bfe62ae..fa5eee5 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -1099,8 +1099,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); +@@ -1101,8 +1101,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); /* * Attempt to initiate a splice from pipe to file. */ @@ -117,7 +149,7 @@ index 7968da9..beb9993 100644 { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -@@ -1116,9 +1116,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1118,9 +1118,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, /* * Attempt to initiate a splice from a file to a pipe. */ @@ -142,6 +174,23 @@ index f87d308..9a290b3 100644 static inline void fput_light(struct file *file, int fput_needed) { +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 35ec87e..3229f97 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1649,6 +1649,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, + struct iovec *fast_pointer, + struct iovec **ret_pointer); + ++typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); ++typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, ++ loff_t *); ++vfs_readf_t vfs_readf(struct file *file); ++vfs_writef_t vfs_writef(struct file *file); ++ + extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); + extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *); + extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); diff --git a/include/linux/splice.h b/include/linux/splice.h index da2751d..2e0fca6 100644 --- a/include/linux/splice.h @@ -157,10 +206,10 @@ index da2751d..2e0fca6 100644 + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); #endif -aufs3.x-rcN mmap patch +aufs4.x-rcN mmap patch diff --git a/fs/buffer.c b/fs/buffer.c -index 20805db..363569f 100644 +index c7a5602..8c50a22 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2450,7 +2450,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, @@ -173,10 +222,10 @@ index 20805db..363569f 100644 ret = __block_page_mkwrite(vma, vmf, get_block); sb_end_pagefault(sb); diff --git a/fs/proc/base.c b/fs/proc/base.c -index 3f3d7ae..426bcc7 100644 +index 093ca14..fc1ac03 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -1735,7 +1735,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) +@@ -1744,7 +1744,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { @@ -243,10 +292,10 @@ index 599ec2e..1740207 100644 ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; diff --git a/include/linux/mm.h b/include/linux/mm.h -index 47a9392..c8f8b46 100644 +index 0755b9f..2ee5500 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -1254,6 +1254,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, +@@ -1172,6 +1172,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, } #endif @@ -276,7 +325,7 @@ index 47a9392..c8f8b46 100644 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf, int len, int write); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index 199a03a..ed38ea3 100644 +index 8d37e26..ce89d4c 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -241,6 +241,7 @@ struct vm_region { @@ -296,10 +345,10 @@ index 199a03a..ed38ea3 100644 #ifndef CONFIG_MMU diff --git a/kernel/fork.c b/kernel/fork.c -index cf65139..f28a048 100644 +index 03c1eaa..7e215ba 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -430,7 +430,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -456,7 +456,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) struct inode *inode = file_inode(file); struct address_space *mapping = file->f_mapping; @@ -309,7 +358,7 @@ index cf65139..f28a048 100644 atomic_dec(&inode->i_writecount); i_mmap_lock_write(mapping); diff --git a/mm/Makefile b/mm/Makefile -index 15dbe99..88e25b5 100644 +index 98c4eae..3f0c9b9 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -21,7 +21,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ @@ -322,10 +371,10 @@ index 15dbe99..88e25b5 100644 obj-y += init-mm.o diff --git a/mm/filemap.c b/mm/filemap.c -index ad72420..8885258 100644 +index 6bf5e42..a863d0f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -2064,7 +2064,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +@@ -2062,7 +2062,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) int ret = VM_FAULT_LOCKED; sb_start_pagefault(inode->i_sb); @@ -354,10 +403,10 @@ index d551475..1ebf71b 100644 return error; } diff --git a/mm/memory.c b/mm/memory.c -index 97839f5..5e5d491 100644 +index 22e037e..62096a2 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -2034,7 +2034,7 @@ static inline int wp_page_reuse(struct m +@@ -2034,7 +2034,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, } if (!page_mkwrite) @@ -367,7 +416,7 @@ index 97839f5..5e5d491 100644 return VM_FAULT_WRITE; diff --git a/mm/mmap.c b/mm/mmap.c -index 9ec50a3..4a6a641 100644 +index bb50cac..1ab5e596 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -274,7 +274,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) @@ -437,7 +486,7 @@ index 9ec50a3..4a6a641 100644 out: up_write(&mm->mmap_sem); if (populate) -@@ -2950,7 +2949,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2949,7 +2948,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, if (anon_vma_clone(new_vma, vma)) goto out_free_mempol; if (new_vma->vm_file) @@ -464,7 +513,7 @@ index bb04d53..5c24c54 100644 goto out; down_read(&mm->mmap_sem); diff --git a/mm/nommu.c b/mm/nommu.c -index 3fba2dc..870ce96 100644 +index e544508..dd6f74a 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -693,7 +693,7 @@ static void __put_nommu_region(struct vm_region *region) @@ -599,13 +648,13 @@ index 0000000..6aa5ab5 + fput(pr); +} +#endif /* !CONFIG_MMU */ -aufs3.x-rcN standalone patch +aufs4.x-rcN standalone patch diff --git a/fs/dcache.c b/fs/dcache.c -index b93a9f2..5a010ee 100644 +index bc261e2..8d7951d 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1235,6 +1235,7 @@ rename_retry: +@@ -1269,6 +1269,7 @@ rename_retry: seq = 1; goto again; } @@ -614,7 +663,7 @@ index b93a9f2..5a010ee 100644 /* * Search for at least 1 mount point in the dentry's subdirs. diff --git a/fs/file_table.c b/fs/file_table.c -index 3f85411..00e9dcf 100644 +index 294174d..3cea027 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -147,6 +147,7 @@ over: @@ -634,7 +683,7 @@ index 3f85411..00e9dcf 100644 void __init files_init(unsigned long mempages) { diff --git a/fs/inode.c b/fs/inode.c -index f00b16f..eb7b8b5 100644 +index ea37cd1..58f5f58 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -58,6 +58,7 @@ static struct hlist_head *inode_hashtable __read_mostly; @@ -646,7 +695,7 @@ index f00b16f..eb7b8b5 100644 /* * Empty aops. Can be used for the cases where the user does not diff --git a/fs/namespace.c b/fs/namespace.c -index 82ef140..a3aa4b9 100644 +index 1b9e111..d45b81b 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt) @@ -657,7 +706,7 @@ index 82ef140..a3aa4b9 100644 /** * mnt_drop_write - give up write access to a mount -@@ -1718,6 +1719,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, +@@ -1768,6 +1769,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, } return 0; } @@ -738,7 +787,7 @@ index 92e48c7..d2c4b68 100644 static int fsnotify_mark_destroy(void *ignored) { diff --git a/fs/open.c b/fs/open.c -index 33f9cbf..fcc7eb4 100644 +index 98e5a52..a94e2e7 100644 --- a/fs/open.c +++ b/fs/open.c @@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, @@ -749,7 +798,7 @@ index 33f9cbf..fcc7eb4 100644 long vfs_truncate(struct path *path, loff_t length) { -@@ -672,6 +673,7 @@ int open_check_o_direct(struct file *f) +@@ -676,6 +677,7 @@ int open_check_o_direct(struct file *f) } return 0; } @@ -757,11 +806,31 @@ index 33f9cbf..fcc7eb4 100644 static int do_dentry_open(struct file *f, int (*open)(struct inode *, struct file *), +diff --git a/fs/read_write.c b/fs/read_write.c +index fd0414e..8ace6ec 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -504,6 +504,7 @@ vfs_readf_t vfs_readf(struct file *file) + return new_sync_read; + return ERR_PTR(-ENOSYS); + } ++EXPORT_SYMBOL(vfs_readf); + + vfs_writef_t vfs_writef(struct file *file) + { +@@ -515,6 +516,7 @@ vfs_writef_t vfs_writef(struct file *file) + return new_sync_write; + return ERR_PTR(-ENOSYS); + } ++EXPORT_SYMBOL(vfs_writef); + + ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) + { diff --git a/fs/splice.c b/fs/splice.c -index beb9993..813275a 100644 +index fa5eee5..bfb3324 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -1112,6 +1112,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1114,6 +1114,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, return splice_write(pipe, out, ppos, len, flags); } @@ -769,7 +838,7 @@ index beb9993..813275a 100644 /* * Attempt to initiate a splice from a file to a pipe. -@@ -1138,6 +1139,7 @@ long do_splice_to(struct file *in, loff_t *ppos, +@@ -1140,6 +1141,7 @@ long do_splice_to(struct file *in, loff_t *ppos, return splice_read(in, ppos, pipe, len, flags); } @@ -790,7 +859,7 @@ index 4ef6985..6bb6303 100644 /* Compare an extended attribute value with the given value */ int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name, diff --git a/security/commoncap.c b/security/commoncap.c -index f66713b..fd4c4b8 100644 +index f2875cd..ebf06ec 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -975,9 +975,11 @@ int cap_mmap_addr(unsigned long addr) @@ -826,7 +895,7 @@ index 188c1d2..426d9af 100644 int devcgroup_inode_mknod(int mode, dev_t dev) { diff --git a/security/security.c b/security/security.c -index e81d5bb..0b7b840 100644 +index 8e9b1f4..c1c7cd1 100644 --- a/security/security.c +++ b/security/security.c @@ -430,6 +430,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry) @@ -911,7 +980,7 @@ index e81d5bb..0b7b840 100644 { diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs --- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/ABI/testing/debugfs-aufs 2014-01-30 21:10:02.794146538 +0100 ++++ linux/Documentation/ABI/testing/debugfs-aufs 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,50 @@ +What: /debug/aufs/si_/ +Date: March 2009 @@ -965,7 +1034,7 @@ diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Document + will be empty. About XINO files, see the aufs manual. diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs --- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/ABI/testing/sysfs-aufs 2014-01-30 21:10:02.794146538 +0100 ++++ linux/Documentation/ABI/testing/sysfs-aufs 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,31 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 @@ -1000,7 +1069,7 @@ diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentat + will be empty. About XINO files, see the aufs manual. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2015-06-22 08:27:37.867501461 +0200 ++++ linux/Documentation/filesystems/aufs/design/01intro.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,170 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -1174,7 +1243,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt lin +about it. But currently I have implemented it in kernel space. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2015-06-22 08:27:37.867501461 +0200 ++++ linux/Documentation/filesystems/aufs/design/02struct.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,258 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -1436,7 +1505,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt li +For this purpose, use "aumvdown" command in aufs-util.git. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,85 @@ + +# Copyright (C) 2015 Junjiro R. Okajima @@ -1525,7 +1594,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.t + be implemented in aufs, but not all I am afraid. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,113 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -1642,7 +1711,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt li + by over-mounting something (or another method). diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/04branch.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,74 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -1720,7 +1789,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt li + same named entry on the upper branch. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,64 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -1788,7 +1857,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.tx + copyup policy. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,120 @@ + +# Copyright (C) 2011-2015 Junjiro R. Okajima @@ -1912,7 +1981,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linu +should restore the original file state after an error happens. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,72 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -1988,7 +2057,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linu +I have to give up this "looks-smater" approach. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,96 @@ + +# Copyright (C) 2014-2015 Junjiro R. Okajima @@ -2088,7 +2157,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt lin +now, aufs implements the branch attributes to ignore the error. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/07export.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/07export.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,58 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -2150,7 +2219,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt li + lookup_one_len(), vfs_getattr(), encode_fh() and others. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,52 @@ + +# Copyright (C) 2005-2015 Junjiro R. Okajima @@ -2206,7 +2275,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linu +initramfs will use it to replace the old one at the next boot. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2015-06-22 08:27:37.870834875 +0200 ++++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,47 @@ + +# Copyright (C) 2010-2015 Junjiro R. Okajima @@ -2255,73 +2324,12 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt lin +XIP (DAX) mainly. +Currently this approach is applied to address_space_operations for +regular files only. -diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt ---- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2015-06-22 08:27:37.870834875 +0200 -@@ -0,0 +1,57 @@ -+ -+# Copyright (C) 2005-2015 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Plan -+ -+Restoring some features which was implemented in aufs1. -+They were dropped in aufs2 in order to make source files simpler and -+easier to be reviewed. -+ -+ -+Being Another Aufs's Readonly Branch (robr) -+---------------------------------------------------------------------- -+Aufs1 allows aufs to be another aufs's readonly branch. -+This feature was developed by a user's request. But it may not be used -+currently. -+ -+ -+Refresh the Opened File (refrof) -+---------------------------------------------------------------------- -+This option is implemented in aufs1 but incomplete. -+ -+When user reads from a file, he expects to get its latest filedata -+generally. If the file is removed and a new same named file is created, -+the content he gets is unchanged, ie. the unlinked filedata. -+ -+Let's try case study again. -+- aufs has two branches. -+ /au = /rw + /ro -+- "fileA" exists under /ro, but /rw. -+- user opened "/au/fileA". -+- he or someone else inserts a branch (/new) between /rw and /ro. -+ /au = /rw + /new + /ro -+- the new branch contains "fileA". -+- user reads from the opened "fileA" -+- which filedata should aufs return, from /ro or /new? -+ -+Some people says it has to be "from /ro" and it is a semantics of Unix. -+The others say it should be "from /new" because the file is not removed -+and it is equivalent to the case of someone else modifies the file. -+ -+Here again I don't have a best and final answer. I got an idea to -+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the -+Opened File) is specified (by default), aufs returns the filedata from -+/new. Otherwise from /ro. diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README --- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/README 2015-06-22 08:27:37.867501461 +0200 -@@ -0,0 +1,384 @@ ++++ linux/Documentation/filesystems/aufs/README 2015-06-28 17:35:44.344717109 +0200 +@@ -0,0 +1,383 @@ + -+Aufs3 -- advanced multi layered unification filesystem version 3.x ++Aufs4 -- advanced multi layered unification filesystem version 4.x +http://aufs.sf.net +Junjiro R. Okajima + @@ -2337,7 +2345,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +Unionfs is being developed by Professor Erez Zadok at Stony Brook +University and his team. + -+Aufs3 supports linux-3.0 and later. ++Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3. +If you want older kernel version support, try aufs2-2.6.git or +aufs2-standalone.git repository, aufs1 from CVS on SourceForge. + @@ -2399,7 +2407,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. +- and more... + -+Currently these features are dropped temporary from aufs3. ++Currently these features are dropped temporary from aufs4. +See design/08plan.txt in detail. +- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs + (robr) @@ -2417,65 +2425,64 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta + +2. Download +---------------------------------------- -+There were three GIT trees for aufs3, aufs3-linux.git, -+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in ++There are three GIT trees for aufs4, aufs4-linux.git, ++aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in +"aufs-util.git." -+While the aufs-util is always necessary, you need either of aufs3-linux -+or aufs3-standalone. ++While the aufs-util is always necessary, you need either of aufs4-linux ++or aufs4-standalone. + -+The aufs3-linux tree includes the whole linux mainline GIT tree, ++The aufs4-linux tree includes the whole linux mainline GIT tree, +git://git.kernel.org/.../torvalds/linux.git. +And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot -+build aufs3 as an external kernel module. ++build aufs4 as an external kernel module. +Several extra patches are not included in this tree. Only -+aufs3-standalong tree contains them. They are describe in the later ++aufs4-standalone tree contains them. They are describe in the later +section "Configuration and Compilation." + -+On the other hand, the aufs3-standalone tree has only aufs source files ++On the other hand, the aufs4-standalone tree has only aufs source files +and necessary patches, and you can select CONFIG_AUFS_FS=m. +But you need to apply all aufs patches manually. + -+You will find GIT branches whose name is in form of "aufs3.x" where "x" -+represents the linux kernel version, "linux-3.x". For instance, -+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use -+"aufs3.x-rcN" branch. ++You will find GIT branches whose name is in form of "aufs4.x" where "x" ++represents the linux kernel version, "linux-4.x". For instance, ++"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use ++"aufs4.x-rcN" branch. + -+o aufs3-linux tree ++o aufs4-linux tree +$ git clone --reference /your/linux/git/tree \ -+ git://git.code.sf.net/p/aufs/aufs3-linux aufs3-linux.git ++ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git +- if you don't have linux GIT tree, then remove "--reference ..." -+$ cd aufs3-linux.git -+$ git checkout origin/aufs3.0 ++$ cd aufs4-linux.git ++$ git checkout origin/aufs4.0 + +Or You may want to directly git-pull aufs into your linux GIT tree, and +leave the patch-work to GIT. +$ cd /your/linux/git/tree -+$ git remote add aufs3 https://github.com/sfjro/aufs3-linux.git -+- aufs3-linux.git tree also exists on github. -+$ git fetch aufs3 -+$ git checkout -b my3.14 v3.14 -+$ (add your change...) -+$ git pull aufs3 aufs3.14 -+- now you have v3.14 + your_changes + aufs3.14 in you my3.14 branch. ++$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git ++$ git fetch aufs4 ++$ git checkout -b my4.0 v4.0 ++$ (add your local change...) ++$ git pull aufs4 aufs4.0 ++- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch. +- you may need to solve some conflicts between your_changes and -+ aufs3.14. in this case, git-rerere is recommended so that you can -+ solve the similar confilicts automatically when you upgrade to 3.15 or ++ aufs4.0. in this case, git-rerere is recommended so that you can ++ solve the similar conflicts automatically when you upgrade to 4.1 or + later in the future. + -+o aufs3-standalone tree -+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \ -+ aufs3-standalone.git -+$ cd aufs3-standalone.git -+$ git checkout origin/aufs3.0 ++o aufs4-standalone tree ++$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git ++$ cd aufs4-standalone.git ++$ git checkout origin/aufs4.0 + +o aufs-util tree -+$ git clone git://git.code.sf.net/p/aufs/aufs-util \ -+ aufs-util.git ++$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git ++- note that the public aufs-util.git is on SourceForge instead of ++ GitHUB. +$ cd aufs-util.git -+$ git checkout origin/aufs3.0 ++$ git checkout origin/aufs4.0 + -+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY. -+The minor version number, 'x' in '3.x', of aufs may not always ++Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY. ++The minor version number, 'x' in '4.x', of aufs may not always +follow the minor version number of the kernel. +Because changes in the kernel that cause the use of a new +minor version number do not always require changes to aufs-util. @@ -2487,8 +2494,8 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +nearest lower number. + +For (an unreleased) example: -+If you are using "linux-3.10" and the "aufs3.10" branch -+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8" ++If you are using "linux-4.10" and the "aufs4.10" branch ++does not exist in aufs-util repository, then "aufs4.9", "aufs4.8" +or something numerically smaller is the branch for your kernel. + +Also you can view all branches by @@ -2499,19 +2506,19 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +---------------------------------------- +Make sure you have git-checkout'ed the correct branch. + -+For aufs3-linux tree, ++For aufs4-linux tree, +- enable CONFIG_AUFS_FS. +- set other aufs configurations if necessary. + -+For aufs3-standalone tree, ++For aufs4-standalone tree, +There are several ways to build. + +1. -+- apply ./aufs3-kbuild.patch to your kernel source files. -+- apply ./aufs3-base.patch too. -+- apply ./aufs3-mmap.patch too. -+- apply ./aufs3-standalone.patch too, if you have a plan to set -+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch. ++- apply ./aufs4-kbuild.patch to your kernel source files. ++- apply ./aufs4-base.patch too. ++- apply ./aufs4-mmap.patch too. ++- apply ./aufs4-standalone.patch too, if you have a plan to set ++ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch. +- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your + kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild. +- enable CONFIG_AUFS_FS, you can select either @@ -2528,9 +2535,9 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta + +2. +- module only (CONFIG_AUFS_FS=m). -+- apply ./aufs3-base.patch to your kernel source files. -+- apply ./aufs3-mmap.patch too. -+- apply ./aufs3-standalone.patch too. ++- apply ./aufs4-base.patch to your kernel source files. ++- apply ./aufs4-mmap.patch too. ++- apply ./aufs4-standalone.patch too. +- build your kernel, don't forget "make headers_install", and reboot. +- edit ./config.mk and set other aufs configurations if necessary. + Note: You should read $PWD/fs/aufs/Kconfig carefully which describes @@ -2549,7 +2556,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta + available in aufs standalone version's Makefile only), or copy + $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever + you like manually. By default, the target directory is $PWD/usr. -+- no need to apply aufs3-kbuild.patch, nor copying source files to your ++- no need to apply aufs4-kbuild.patch, nor copying source files to your + kernel source tree. + +Note: The header file aufs_type.h is necessary to build aufs-util @@ -2569,9 +2576,9 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta + then run "make install_ulib" too. And refer to the aufs manual in + detail. + -+There several other patches in aufs3-standalone.git. They are all ++There several other patches in aufs4-standalone.git. They are all +optional. When you meet some problems, they will help you. -+- aufs3-loopback.patch ++- aufs4-loopback.patch + Supports a nested loopback mount in a branch-fs. This patch is + unnecessary until aufs produces a message like "you may want to try + another patch for loopback file". @@ -2706,7 +2713,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +# End: ; diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h --- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/aufs.h 2015-06-22 08:27:37.874168290 +0200 ++++ linux/fs/aufs/aufs.h 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -2769,8 +2776,8 @@ diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h +#endif /* __AUFS_H__ */ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c --- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/branch.c 2015-06-22 08:29:23.703424266 +0200 -@@ -0,0 +1,1406 @@ ++++ linux/fs/aufs/branch.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,1414 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -2898,6 +2905,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c +{ + struct au_branch *add_branch; + struct dentry *root; ++ struct inode *inode; + int err; + + err = -ENOMEM; @@ -2929,8 +2937,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + err = au_sbr_realloc(au_sbi(sb), new_nbranch); + if (!err) + err = au_di_realloc(au_di(root), new_nbranch); -+ if (!err) -+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch); ++ if (!err) { ++ inode = d_inode(root); ++ err = au_ii_realloc(au_ii(inode), new_nbranch); ++ } + if (!err) + return add_branch; /* success */ + @@ -2972,7 +2982,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c +{ + int err; + aufs_bindex_t bend, bindex; -+ struct dentry *root; ++ struct dentry *root, *h_dentry; + struct inode *inode, *h_inode; + + root = sb->s_root; @@ -3000,7 +3010,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + goto out; + } + -+ inode = add->path.dentry->d_inode; ++ inode = d_inode(add->path.dentry); + err = -ENOENT; + if (unlikely(!inode->i_nlink)) { + pr_err("no existence %s\n", add->pathname); @@ -3025,7 +3035,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + goto out; + } + -+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname); ++ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname); + if (unlikely(err)) + goto out; + @@ -3042,7 +3052,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + + err = 0; + if (au_opt_test(au_mntflags(sb), WARN_PERM)) { -+ h_inode = au_h_dptr(root, 0)->d_inode; ++ h_dentry = au_h_dptr(root, 0); ++ h_inode = d_inode(h_dentry); + if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) + || !uid_eq(h_inode->i_uid, inode->i_uid) + || !gid_eq(h_inode->i_gid, inode->i_gid)) @@ -3069,6 +3080,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + struct mutex *h_mtx; + struct au_wbr *wbr; + struct au_hinode *hdir; ++ struct dentry *h_dentry; + + err = vfsub_mnt_want_write(au_br_mnt(br)); + if (unlikely(err)) @@ -3081,10 +3093,11 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + h_mtx = NULL; + bindex = au_br_index(sb, br->br_id); + if (0 <= bindex) { -+ hdir = au_hi(sb->s_root->d_inode, bindex); ++ hdir = au_hi(d_inode(sb->s_root), bindex); + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT); + } else { -+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex; ++ h_dentry = au_br_dentry(br); ++ h_mtx = &d_inode(h_dentry)->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_PARENT); + } + if (!wbr) @@ -3147,6 +3160,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + struct au_opt_add *add) +{ + int err; ++ struct inode *h_inode; + + err = 0; + memset(&br->br_xino, 0, sizeof(br->br_xino)); @@ -3167,7 +3181,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + } + + if (au_opt_test(au_mntflags(sb), XINO)) { -+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino, ++ h_inode = d_inode(add->path.dentry); ++ err = au_xino_br(sb, br, h_inode->i_ino, + au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1); + if (unlikely(err)) { + AuDebugOn(br->br_xino.xi_file); @@ -3236,11 +3251,11 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + aufs_bindex_t bindex) +{ + struct dentry *root, *h_dentry; -+ struct inode *root_inode; ++ struct inode *root_inode, *h_inode; + aufs_bindex_t bend, amount; + + root = sb->s_root; -+ root_inode = root->d_inode; ++ root_inode = d_inode(root); + bend = au_sbend(sb); + amount = bend + 1 - bindex; + h_dentry = au_br_dentry(br); @@ -3249,8 +3264,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + au_br_do_add_hdp(au_di(root), bindex, bend, amount); + au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount); + au_set_h_dptr(root, bindex, dget(h_dentry)); -+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode), -+ /*flags*/0); ++ h_inode = d_inode(h_dentry); ++ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0); + au_sbilist_unlock(); +} + @@ -3263,7 +3278,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + struct au_branch *add_branch; + + root = sb->s_root; -+ root_inode = root->d_inode; ++ root_inode = d_inode(root); + IMustLock(root_inode); + err = test_add(sb, add, remount); + if (unlikely(err < 0)) @@ -3299,7 +3314,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + au_cpup_attr_all(root_inode, /*force*/1); + sb->s_maxbytes = h_dentry->d_sb->s_maxbytes; + } else -+ au_add_nlink(root_inode, h_dentry->d_inode); ++ au_add_nlink(root_inode, d_inode(h_dentry)); + + /* + * this test/set prevents aufs from handling unnecesary notify events @@ -3386,7 +3401,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c +static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart, + aufs_bindex_t bend) +{ -+ return au_test_ibusy(dentry->d_inode, bstart, bend); ++ return au_test_ibusy(d_inode(dentry), bstart, bend); +} + +/* @@ -3519,7 +3534,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + + sigen = au_sigen(root->d_sb); + DiMustNoWaiters(root); -+ IiMustNoWaiters(root->d_inode); ++ IiMustNoWaiters(d_inode(root)); + di_write_unlock(root); + err = test_dentry_busy(root, bindex, sigen, verbose); + if (!err) @@ -3730,7 +3745,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + SiMustWriteLock(sb); + + root = sb->s_root; -+ inode = root->d_inode; ++ inode = d_inode(root); + sbinfo = au_sbi(sb); + bend = sbinfo->si_bend; + @@ -3846,10 +3861,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + } + + if (!bindex) { -+ au_cpup_attr_all(root->d_inode, /*force*/1); ++ au_cpup_attr_all(d_inode(root), /*force*/1); + sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes; + } else -+ au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode); ++ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry)); + if (au_opt_test(mnt_flags, PLINK)) + au_plink_half_refresh(sb, br_id); + @@ -4076,7 +4091,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + } + AuDbg("bindex b%d\n", bindex); + -+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path); ++ err = test_br(d_inode(mod->h_root), mod->perm, mod->path); + if (unlikely(err)) + goto out; + @@ -4104,7 +4119,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + if (!au_br_writable(mod->perm)) { + /* rw --> ro, file might be mmapped */ + DiMustNoWaiters(root); -+ IiMustNoWaiters(root->d_inode); ++ IiMustNoWaiters(d_inode(root)); + di_write_unlock(root); + err = au_br_mod_files_ro(sb, bindex); + /* aufs_write_lock() calls ..._child() */ @@ -4179,7 +4194,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c +} diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h --- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/branch.h 2015-06-22 08:29:23.703424266 +0200 ++++ linux/fs/aufs/branch.h 2015-06-28 17:36:09.025073697 +0200 @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -4369,10 +4384,10 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h +static const loff_t au_loff_max = LLONG_MAX; + +int au_xib_trunc(struct super_block *sb); -+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size, + loff_t *pos); -+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, -+ loff_t *pos); ++ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, ++ size_t size, loff_t *pos); +struct file *au_xino_create2(struct file *base_file, struct file *copy_src); +struct file *au_xino_create(struct super_block *sb, char *fname, int silent); +ino_t au_xino_new_ino(struct super_block *sb); @@ -4462,7 +4477,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h +#endif /* __AUFS_BRANCH_H__ */ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk --- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/conf.mk 2015-06-22 08:27:37.874168290 +0200 ++++ linux/fs/aufs/conf.mk 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,38 @@ + +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} @@ -4504,8 +4519,8 @@ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk +-include ${srctree}/${src}/conf_priv.mk diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c --- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/cpup.c 2015-06-22 08:29:23.703424266 +0200 -@@ -0,0 +1,1308 @@ ++++ linux/fs/aufs/cpup.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,1319 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -4638,7 +4653,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + + dt->dt_dentry = dentry; + dt->dt_h_path = *h_path; -+ h_inode = h_path->dentry->d_inode; ++ h_inode = d_inode(h_path->dentry); + dt->dt_atime = h_inode->i_atime; + dt->dt_mtime = h_inode->i_mtime; + /* smp_mb(); */ @@ -4683,10 +4698,10 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + struct au_branch *br; + + h_path.dentry = au_h_dptr(dst, bindex); -+ h_idst = h_path.dentry->d_inode; ++ h_idst = d_inode(h_path.dentry); + br = au_sbr(dst->d_sb, bindex); + h_path.mnt = au_br_mnt(br); -+ h_isrc = h_src->d_inode; ++ h_isrc = d_inode(h_src); + ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID + | ATTR_ATIME | ATTR_MTIME + | ATTR_ATIME_SET | ATTR_MTIME_SET; @@ -4915,7 +4930,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + } + + /* try stopping to update while we copyup */ -+ IMustLock(file[SRC].dentry->d_inode); ++ IMustLock(d_inode(file[SRC].dentry)); + err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); + + fput(file[DST].file); @@ -4937,7 +4952,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + struct inode *h_src_inode, *h_dst_inode; + + err = 0; -+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc); ++ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc); + l = i_size_read(h_src_inode); + if (cpg->len == -1 || l < cpg->len) + cpg->len = l; @@ -4949,7 +4964,13 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); + h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc); + h_src_attr->iflags = h_src_inode->i_flags; -+ err = vfs_getattr(&h_path, &h_src_attr->st); ++ if (!au_test_nfs(h_src_inode->i_sb)) ++ err = vfs_getattr(&h_path, &h_src_attr->st); ++ else { ++ mutex_unlock(&h_src_inode->i_mutex); ++ err = vfs_getattr(&h_path, &h_src_attr->st); ++ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD); ++ } + if (unlikely(err)) { + mutex_unlock(&h_src_inode->i_mutex); + goto out; @@ -4963,7 +4984,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + } + if (!err && (h_src_inode->i_state & I_LINKABLE)) { + h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst); -+ h_dst_inode = h_path.dentry->d_inode; ++ h_dst_inode = d_inode(h_path.dentry); + spin_lock(&h_dst_inode->i_lock); + h_dst_inode->i_state |= I_LINKABLE; + spin_unlock(&h_dst_inode->i_lock); @@ -4982,9 +5003,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + char *k; + char __user *u; + } sym; ++ struct inode *h_inode = d_inode(h_src); ++ const struct inode_operations *h_iop = h_inode->i_op; + + err = -ENOSYS; -+ if (unlikely(!h_src->d_inode->i_op->readlink)) ++ if (unlikely(!h_iop->readlink)) + goto out; + + err = -ENOMEM; @@ -4995,7 +5018,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + /* unnecessary to support mmap_sem since symlink is not mmap-able */ + old_fs = get_fs(); + set_fs(KERNEL_DS); -+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX); ++ symlen = h_iop->readlink(h_src, sym.u, PATH_MAX); + err = symlen; + set_fs(old_fs); + @@ -5021,13 +5044,13 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + struct au_dtime dt; + struct path h_path; + struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *h_inode, *h_dir; ++ struct inode *h_inode, *h_dir, *dir, *inode; + struct super_block *sb; + + /* bsrc branch can be ro/rw. */ + h_src = au_h_dptr(cpg->dentry, cpg->bsrc); -+ h_inode = h_src->d_inode; -+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc)); ++ h_inode = d_inode(h_src); ++ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc)); + + /* try stopping to be referenced while we are creating */ + h_dst = au_h_dptr(cpg->dentry, cpg->bdst); @@ -5035,7 +5058,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX, + AUFS_WH_PFX_LEN)); + h_parent = h_dst->d_parent; /* dir inode is locked */ -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + IMustLock(h_dir); + AuDebugOn(h_parent != h_dst->d_parent); + @@ -5066,10 +5089,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + * strange behaviour from the users view, + * particularry setattr case + */ -+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst) -+ au_cpup_attr_nlink(dst_parent->d_inode, -+ /*force*/1); -+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1); ++ dir = d_inode(dst_parent); ++ if (au_ibstart(dir) == cpg->bdst) ++ au_cpup_attr_nlink(dir, /*force*/1); ++ inode = d_inode(cpg->dentry); ++ au_cpup_attr_nlink(inode, /*force*/1); + } + break; + case S_IFLNK: @@ -5095,7 +5119,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + && (h_inode->i_nlink == 1 + || (h_inode->i_state & I_LINKABLE)) + /* todo: unnecessary? */ -+ /* && cpg->dentry->d_inode->i_nlink == 1 */ ++ /* && d_inode(cpg->dentry)->i_nlink == 1 */ + && cpg->bdst < cpg->bsrc + && !au_ftest_cpup(cpg->flags, KEEPLINO)) + au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0); @@ -5146,7 +5170,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + goto out; + + h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + IMustLock(h_dir); + AuDbg("%pd %pd\n", h_dentry, h_path->dentry); + /* no delegation since it is just created */ @@ -5170,7 +5194,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + aufs_bindex_t old_ibstart; + unsigned char isdir, plink; + struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *dst_inode, *h_dir, *inode, *delegated; ++ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode; + struct super_block *sb; + struct au_branch *br; + /* to reuduce stack size */ @@ -5191,11 +5215,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + a->h_path.mnt = au_br_mnt(br); + h_dst = au_h_dptr(cpg->dentry, cpg->bdst); + h_parent = h_dst->d_parent; /* dir inode is locked */ -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + IMustLock(h_dir); + + h_src = au_h_dptr(cpg->dentry, cpg->bsrc); -+ inode = cpg->dentry->d_inode; ++ inode = d_inode(cpg->dentry); + + if (!dst_parent) + dst_parent = dget_parent(cpg->dentry); @@ -5220,7 +5244,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + err = PTR_ERR(h_src); + if (IS_ERR(h_src)) + goto out_parent; -+ if (unlikely(!h_src->d_inode)) { ++ if (unlikely(d_is_negative(h_src))) { + err = -EIO; + AuIOErr("i%lu exists on a upper branch " + "but not pseudo-linked\n", @@ -5259,7 +5283,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + err = cpup_entry(cpg, dst_parent, &a->h_src_attr); + if (unlikely(err)) + goto out_rev; -+ dst_inode = h_dst->d_inode; ++ dst_inode = d_inode(h_dst); + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); + /* todo: necessary? */ + /* au_pin_hdir_unlock(cpg->pin); */ @@ -5294,9 +5318,10 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + if (unlikely(err)) + goto out_rev; + ++ src_inode = d_inode(h_src); + if (!isdir -+ && (h_src->d_inode->i_nlink > 1 -+ || h_src->d_inode->i_state & I_LINKABLE) ++ && (src_inode->i_nlink > 1 ++ || src_inode->i_state & I_LINKABLE) + && plink) + au_plink_append(inode, cpg->bdst, h_dst); + @@ -5313,7 +5338,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + au_dtime_store(&a->dt, dst_parent, &a->h_path); + a->h_path.dentry = h_dst; + rerr = 0; -+ if (h_dst->d_inode) { ++ if (d_is_positive(h_dst)) { + if (!isdir) { + /* no delegation since it is just created */ + rerr = vfsub_unlink(h_dir, &a->h_path, @@ -5396,7 +5421,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + struct dentry *h_dentry; + + h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc); -+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode)) ++ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode)) + err = au_cpup_single(cpg, dst_parent); + else { + struct au_cpup_single_args args = { @@ -5477,9 +5502,9 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + } + + parent = dget_parent(dentry); -+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst); ++ h_dir = au_h_iptr(d_inode(parent), cpg->bdst); + if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode)) ++ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) + err = au_cpup_simple(cpg); + else { + struct au_cpup_simple_args args = { @@ -5510,7 +5535,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) { + h_dentry = au_h_dptr(dentry, bsrc); + if (h_dentry) { -+ AuDebugOn(!h_dentry->d_inode); ++ AuDebugOn(d_is_negative(h_dentry)); + break; + } + } @@ -5602,17 +5627,17 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + h_path.dentry = wh_dentry; + if (!d_is_dir(wh_dentry)) { + /* no delegation since it is just created */ -+ err = vfsub_unlink(h_parent->d_inode, &h_path, ++ err = vfsub_unlink(d_inode(h_parent), &h_path, + /*delegated*/NULL, /*force*/0); + } else -+ err = vfsub_rmdir(h_parent->d_inode, &h_path); ++ err = vfsub_rmdir(d_inode(h_parent), &h_path); + if (unlikely(err)) { + AuIOErr("failed remove copied-up tmp file %pd(%d)\n", + wh_dentry, err); + err = -EIO; + } + au_dtime_revert(&dt); -+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry); ++ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry); + +out_wh: + dput(wh_dentry); @@ -5648,7 +5673,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + dentry = cpg->dentry; + bdst = cpg->bdst; + parent = dget_parent(dentry); -+ dir = parent->d_inode; ++ dir = d_inode(parent); + h_orph = NULL; + h_parent = NULL; + h_dir = au_igrab(au_h_iptr(dir, bdst)); @@ -5660,7 +5685,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + + h_parent = dget(au_h_dptr(parent, bdst)); + au_set_h_dptr(parent, bdst, dget(h_orph)); -+ h_tmpdir = h_orph->d_inode; ++ h_tmpdir = d_inode(h_orph); + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); + + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); @@ -5673,7 +5698,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + } + + if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode)) ++ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) + err = au_cpup_wh(cpg, file); + else { + struct au_cpup_wh_args args = { @@ -5714,7 +5739,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c +{ + int err; + struct au_pin pin; -+ struct dentry *d, *parent, *h_parent, *real_parent; ++ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry; + + err = 0; + parent = dget_parent(dentry); @@ -5747,8 +5772,9 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + di_write_lock_child3(d); + + /* somebody else might create while we were sleeping */ -+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) { -+ if (au_h_dptr(d, bdst)) ++ h_dentry = au_h_dptr(d, bdst); ++ if (!h_dentry || d_is_negative(h_dentry)) { ++ if (h_dentry) + au_update_dbstart(d); + + au_pin_set_dentry(&pin, d); @@ -5798,7 +5824,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + struct inode *dir; + + parent = dget_parent(dentry); -+ dir = parent->d_inode; ++ dir = d_inode(parent); + err = 0; + if (au_h_iptr(dir, bdst)) + goto out; @@ -5816,7 +5842,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c +} diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h --- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/cpup.h 2015-06-22 08:27:37.874168290 +0200 ++++ linux/fs/aufs/cpup.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -5914,7 +5940,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h +#endif /* __AUFS_CPUP_H__ */ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c --- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dbgaufs.c 2015-06-22 08:29:23.706757681 +0200 ++++ linux/fs/aufs/dbgaufs.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -6350,7 +6376,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c +} diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h --- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dbgaufs.h 2015-06-22 08:27:37.874168290 +0200 ++++ linux/fs/aufs/dbgaufs.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -6402,7 +6428,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h +#endif /* __DBGAUFS_H__ */ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c --- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dcsub.c 2015-06-22 08:27:37.877501704 +0200 ++++ linux/fs/aufs/dcsub.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -6630,8 +6656,8 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c +} diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h --- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dcsub.h 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,132 @@ ++++ linux/fs/aufs/dcsub.h 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -6695,10 +6721,12 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h +static inline int au_d_hashed_positive(struct dentry *d) +{ + int err; -+ struct inode *inode = d->d_inode; ++ struct inode *inode = d_inode(d); + + err = 0; -+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink)) ++ if (unlikely(d_unhashed(d) ++ || d_is_negative(d) ++ || !inode->i_nlink)) + err = -ENOENT; + return err; +} @@ -6706,11 +6734,11 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h +static inline int au_d_linkable(struct dentry *d) +{ + int err; -+ struct inode *inode = d->d_inode; ++ struct inode *inode = d_inode(d); + + err = au_d_hashed_positive(d); + if (err -+ && inode ++ && d_is_positive(d) + && (inode->i_state & I_LINKABLE)) + err = 0; + return err; @@ -6725,8 +6753,10 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h + if (!IS_ROOT(d)) + err = au_d_hashed_positive(d); + else { -+ inode = d->d_inode; -+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink)) ++ inode = d_inode(d); ++ if (unlikely(d_unlinked(d) ++ || d_is_negative(d) ++ || !inode->i_nlink)) + err = -ENOENT; + } + return err; @@ -6737,7 +6767,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h + int err; + + err = au_d_alive(d); -+ if (unlikely(err || IS_DEADDIR(d->d_inode))) ++ if (unlikely(err || IS_DEADDIR(d_inode(d)))) + err = -ENOENT; + return err; +} @@ -6766,8 +6796,8 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h +#endif /* __AUFS_DCSUB_H__ */ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c --- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/debug.c 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,438 @@ ++++ linux/fs/aufs/debug.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,440 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -6961,14 +6991,16 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c + au_dcount(dentry), dentry->d_flags, + d_unhashed(dentry) ? "un" : ""); + hn = -1; -+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { -+ iinfo = au_ii(dentry->d_inode); ++ if (bindex >= 0 ++ && d_is_positive(dentry) ++ && au_test_aufs(dentry->d_sb)) { ++ iinfo = au_ii(d_inode(dentry)); + if (iinfo) { + hn = !!au_hn(iinfo->ii_hinode + bindex); + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry; + } + } -+ do_pri_inode(bindex, dentry->d_inode, hn, wh); ++ do_pri_inode(bindex, d_inode(dentry), hn, wh); + return 0; +} + @@ -7123,7 +7155,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c + +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line) +{ -+ struct inode *h_inode, *inode = dentry->d_inode; ++ struct inode *h_inode, *inode = d_inode(dentry); + struct dentry *h_dentry; + aufs_bindex_t bindex, bend, bi; + @@ -7144,7 +7176,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c + if (!h_dentry) + continue; + h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(h_inode != h_dentry->d_inode)) { ++ if (unlikely(h_inode != d_inode(h_dentry))) { + au_debug_on(); + AuDbg("b%d, %s:%d\n", bindex, func, line); + AuDbgDentry(dentry); @@ -7208,8 +7240,8 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c +} diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h --- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/debug.h 2015-06-22 08:27:37.877501704 +0200 -@@ -0,0 +1,228 @@ ++++ linux/fs/aufs/debug.h 2015-06-28 17:35:44.348050491 +0200 +@@ -0,0 +1,225 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -7398,9 +7430,6 @@ diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h +} while (0) +#else +AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry) -+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen) -+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry, -+ unsigned int sigen) +AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen) +AuStubVoid(au_dbg_verify_kthread, void) +AuStubInt0(__init au_debug_init, void) @@ -7440,8 +7469,8 @@ diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h +#endif /* __AUFS_DEBUG_H__ */ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c --- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dentry.c 2015-06-22 08:27:37.877501704 +0200 -@@ -0,0 +1,1097 @@ ++++ linux/fs/aufs/dentry.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,1105 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -7526,8 +7555,8 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + goto out; + } + -+ h_inode = h_dentry->d_inode; -+ if (!h_inode) { ++ h_inode = d_inode(h_dentry); ++ if (d_is_negative(h_dentry)) { + if (!allow_neg) + goto out_neg; + } else if (wh_found @@ -7542,7 +7571,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + + if (!d_is_dir(h_dentry) + || !wh_able -+ || (d_is_positive(dentry) && !d_is_dir(dentry))) ++ || (d_really_is_positive(dentry) && !d_is_dir(dentry))) + goto out; /* success */ + + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); @@ -7588,7 +7617,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + }; + const struct qstr *name = &dentry->d_name; + struct dentry *parent; -+ struct inode *inode; + struct super_block *sb; + + sb = dentry->d_sb; @@ -7600,7 +7628,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + if (unlikely(err)) + goto out; + -+ inode = dentry->d_inode; + isdir = !!d_is_dir(dentry); + if (!type) + au_fset_lkup(args.flags, ALLOW_NEG); @@ -7615,7 +7642,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry) { -+ if (h_dentry->d_inode) ++ if (d_is_positive(h_dentry)) + npositive++; + if (type != S_IFDIR) + break; @@ -7625,7 +7652,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + if (!h_parent || !d_is_dir(h_parent)) + continue; + -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, + &args); @@ -7642,9 +7669,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + break; + if (!h_dentry) + continue; -+ h_inode = h_dentry->d_inode; -+ if (!h_inode) ++ if (d_is_negative(h_dentry)) + continue; ++ h_inode = d_inode(h_dentry); + npositive++; + if (!args.type) + args.type = h_inode->i_mode & S_IFMT; @@ -7682,7 +7709,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + struct dentry *dentry; + int wkq_err; + -+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC)) ++ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC)) + dentry = vfsub_lkup_one(name, parent); + else { + struct vfsub_lkup_one_args args = { @@ -7718,7 +7745,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out; -+ if (unlikely(h_dentry->d_inode)) { ++ if (unlikely(d_is_positive(h_dentry))) { + err = -EIO; + AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex); + dput(h_dentry); @@ -7793,10 +7820,11 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + err = 0; + memset(&ia, -1, sizeof(ia)); + h_sb = h_dentry->d_sb; -+ h_inode = h_dentry->d_inode; -+ if (h_inode) ++ h_inode = NULL; ++ if (d_is_positive(h_dentry)) { ++ h_inode = d_inode(h_dentry); + au_iattr_save(&ia, h_inode); -+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) ++ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) + /* nfs d_revalidate may return 0 for negative dentry */ + /* fuse d_revalidate always return 0 for negative dentry */ + goto out; @@ -7809,7 +7837,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + + err = 0; + if (unlikely(h_d != h_dentry -+ || h_d->d_inode != h_inode ++ || d_inode(h_d) != h_inode + || (h_inode && au_iattr_test(&ia, h_inode)))) + err = au_busy_or_stale(); + dput(h_d); @@ -7828,7 +7856,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + if (udba == AuOpt_UDBA_REVAL + && !au_test_fs_remote(h_dentry->d_sb)) { + IMustLock(h_dir); -+ err = (h_dentry->d_parent->d_inode != h_dir); ++ err = (d_inode(h_dentry->d_parent) != h_dir); + } else if (udba != AuOpt_UDBA_NONE) + err = au_h_verify_dentry(h_dentry, h_parent, br); + @@ -7920,9 +7948,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c +{ + struct inode *inode; + -+ inode = dentry->d_inode; -+ if (inode) { -+ if (!S_ISDIR(inode->i_mode)) { ++ if (d_really_is_positive(dentry)) { ++ inode = d_inode(dentry); ++ if (!d_is_dir(dentry)) { + if (inode->i_nlink && !d_unhashed(dentry)) + drop_nlink(inode); + } else { @@ -8019,20 +8047,26 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + + err = 0; + AuDebugOn(dinfo->di_bstart < 0); -+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry; -+ orig_h.inode = orig_h.dentry->d_inode; + orig_h.mode = 0; -+ if (orig_h.inode) ++ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry; ++ orig_h.inode = NULL; ++ if (d_is_positive(orig_h.dentry)) { ++ orig_h.inode = d_inode(orig_h.dentry); + orig_h.mode = orig_h.inode->i_mode & S_IFMT; ++ } + memset(&tmp_h, 0, sizeof(tmp_h)); + if (tmp->di_bstart >= 0) { + tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry; -+ tmp_h.inode = tmp_h.dentry->d_inode; -+ if (tmp_h.inode) ++ tmp_h.inode = NULL; ++ if (d_is_positive(tmp_h.dentry)) { ++ tmp_h.inode = d_inode(tmp_h.dentry); + tmp_h.mode = tmp_h.inode->i_mode & S_IFMT; ++ } + } + -+ inode = dentry->d_inode; ++ inode = NULL; ++ if (d_really_is_positive(dentry)) ++ inode = d_inode(dentry); + if (!orig_h.inode) { + AuDbg("nagative originally\n"); + if (inode) { @@ -8112,8 +8146,8 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + h_dentry = hd[bindex].hd_dentry; + if (!h_dentry) + continue; -+ h_inode = h_dentry->d_inode; -+ AuDebugOn(!h_inode); ++ AuDebugOn(d_is_negative(h_dentry)); ++ h_inode = d_inode(h_dentry); + AuDebugOn(orig_h.mode + != (h_inode->i_mode + & S_IFMT)); @@ -8147,10 +8181,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + + DiMustWriteLock(dentry); + AuDebugOn(IS_ROOT(dentry)); -+ AuDebugOn(!parent->d_inode); ++ AuDebugOn(d_really_is_negative(parent)); + + sb = dentry->d_sb; -+ inode = dentry->d_inode; + sigen = au_sigen(sb); + err = au_digen_test(parent, sigen); + if (unlikely(err)) @@ -8166,8 +8199,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + + if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) { + AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0); -+ if (inode) ++ if (d_really_is_positive(dentry)) { ++ inode = d_inode(dentry); + err = au_refresh_hinode_self(inode); ++ } + au_dbg_verify_dinode(dentry); + if (!err) + goto out_dgen; /* success */ @@ -8324,10 +8359,12 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + continue; + + /* UDBA tests */ -+ h_inode = h_dentry->d_inode; -+ if (unlikely(!!inode != !!h_inode)) ++ if (unlikely(!!inode != d_is_positive(h_dentry))) + goto err; + ++ h_inode = NULL; ++ if (d_is_positive(h_dentry)) ++ h_inode = d_inode(h_dentry); + h_plus = plus; + h_mode = mode; + h_cached_inode = h_inode; @@ -8386,7 +8423,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c +{ + int err; + struct dentry *d, *parent; -+ struct inode *inode; + + if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR)) + return simple_reval_dpath(dentry, sigen); @@ -8405,7 +8441,6 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + d = parent; + } + -+ inode = d->d_inode; + if (d != dentry) + di_write_lock_child2(d); + @@ -8462,7 +8497,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + AuTraceErr(err); + goto out; + } -+ inode = dentry->d_inode; ++ inode = NULL; ++ if (d_really_is_positive(dentry)) ++ inode = d_inode(dentry); + if (unlikely(inode && is_bad_inode(inode))) { + err = -EINVAL; + AuTraceErr(err); @@ -8541,7 +8578,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c +}; diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h --- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dentry.h 2015-06-22 08:27:37.877501704 +0200 ++++ linux/fs/aufs/dentry.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -8778,8 +8815,8 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h +#endif /* __AUFS_DENTRY_H__ */ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c --- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dinfo.c 2015-06-22 08:27:37.877501704 +0200 -@@ -0,0 +1,544 @@ ++++ linux/fs/aufs/dinfo.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,550 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -9002,24 +9039,30 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + +void di_read_lock(struct dentry *d, int flags, unsigned int lsc) +{ ++ struct inode *inode; ++ + au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); -+ if (d->d_inode) { ++ if (d_really_is_positive(d)) { ++ inode = d_inode(d); + if (au_ftest_lock(flags, IW)) -+ do_ii_write_lock(d->d_inode, lsc); ++ do_ii_write_lock(inode, lsc); + else if (au_ftest_lock(flags, IR)) -+ do_ii_read_lock(d->d_inode, lsc); ++ do_ii_read_lock(inode, lsc); + } +} + +void di_read_unlock(struct dentry *d, int flags) +{ -+ if (d->d_inode) { ++ struct inode *inode; ++ ++ if (d_really_is_positive(d)) { ++ inode = d_inode(d); + if (au_ftest_lock(flags, IW)) { + au_dbg_verify_dinode(d); -+ ii_write_unlock(d->d_inode); ++ ii_write_unlock(inode); + } else if (au_ftest_lock(flags, IR)) { + au_dbg_verify_dinode(d); -+ ii_read_unlock(d->d_inode); ++ ii_read_unlock(inode); + } + } + au_rw_read_unlock(&au_di(d)->di_rwsem); @@ -9027,30 +9070,30 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + +void di_downgrade_lock(struct dentry *d, int flags) +{ -+ if (d->d_inode && au_ftest_lock(flags, IR)) -+ ii_downgrade_lock(d->d_inode); ++ if (d_really_is_positive(d) && au_ftest_lock(flags, IR)) ++ ii_downgrade_lock(d_inode(d)); + au_rw_dgrade_lock(&au_di(d)->di_rwsem); +} + +void di_write_lock(struct dentry *d, unsigned int lsc) +{ + au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); -+ if (d->d_inode) -+ do_ii_write_lock(d->d_inode, lsc); ++ if (d_really_is_positive(d)) ++ do_ii_write_lock(d_inode(d), lsc); +} + +void di_write_unlock(struct dentry *d) +{ + au_dbg_verify_dinode(d); -+ if (d->d_inode) -+ ii_write_unlock(d->d_inode); ++ if (d_really_is_positive(d)) ++ ii_write_unlock(d_inode(d)); + au_rw_write_unlock(&au_di(d)->di_rwsem); +} + +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) +{ + AuDebugOn(d1 == d2 -+ || d1->d_inode == d2->d_inode ++ || d_inode(d1) == d_inode(d2) + || d1->d_sb != d2->d_sb); + + if (isdir && au_test_subdir(d1, d2)) { @@ -9066,7 +9109,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) +{ + AuDebugOn(d1 == d2 -+ || d1->d_inode == d2->d_inode ++ || d_inode(d1) == d_inode(d2) + || d1->d_sb != d2->d_sb); + + if (isdir && au_test_subdir(d1, d2)) { @@ -9082,7 +9125,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c +void di_write_unlock2(struct dentry *d1, struct dentry *d2) +{ + di_write_unlock(d1); -+ if (d1->d_inode == d2->d_inode) ++ if (d_inode(d1) == d_inode(d2)) + au_rw_write_unlock(&au_di(d2)->di_rwsem); + else + di_write_unlock(d2); @@ -9114,8 +9157,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + struct dentry *h_dentry; + struct inode *inode, *h_inode; + -+ inode = dentry->d_inode; -+ AuDebugOn(!inode); ++ AuDebugOn(d_really_is_negative(dentry)); + + h_dentry = NULL; + if (au_dbstart(dentry) <= bindex @@ -9126,6 +9168,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + goto out; /* success */ + } + ++ inode = d_inode(dentry); + AuDebugOn(bindex < au_ibstart(inode)); + AuDebugOn(au_ibend(inode) < bindex); + h_inode = au_h_iptr(inode, bindex); @@ -9225,7 +9268,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + + err = 0; + if (unlikely(au_digen(dentry) != sigen -+ || au_iigen_test(dentry->d_inode, sigen))) ++ || au_iigen_test(d_inode(dentry), sigen))) + err = -EIO; + + return err; @@ -9256,7 +9299,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + bend = dinfo->di_bend; + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) { + h_d = hdp[0 + bindex].hd_dentry; -+ if (h_d && !h_d->d_inode) ++ if (h_d && d_is_negative(h_d)) + au_set_h_dptr(dentry, bindex, NULL); + } + } @@ -9288,7 +9331,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; -+ if (h_dentry->d_inode) { ++ if (d_is_positive(h_dentry)) { + au_set_dbstart(dentry, bindex); + return; + } @@ -9306,7 +9349,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; -+ if (h_dentry->d_inode) { ++ if (d_is_positive(h_dentry)) { + au_set_dbend(dentry, bindex); + return; + } @@ -9326,8 +9369,8 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c +} diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c --- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dir.c 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,751 @@ ++++ linux/fs/aufs/dir.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,753 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -9410,8 +9453,8 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + bindex <= bend && sz < KMALLOC_MAX_SIZE; + bindex++) { + h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && h_dentry->d_inode) -+ sz += i_size_read(h_dentry->d_inode); ++ if (h_dentry && d_is_positive(h_dentry)) ++ sz += i_size_read(d_inode(h_dentry)); + } + } + if (sz < KMALLOC_MAX_SIZE) @@ -9443,12 +9486,12 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + aufs_bindex_t bstart, bindex; + + sb = a->dentry->d_sb; -+ dir = a->dentry->d_inode; -+ if (!dir) ++ if (d_really_is_negative(a->dentry)) + goto out; -+ /* no dir->i_mutex lock */ + aufs_read_lock(a->dentry, AuLock_DW | AuLock_DIR); /* noflush */ + ++ /* no dir->i_mutex lock */ ++ dir = d_inode(a->dentry); + bstart = au_ibstart(dir); + bindex = au_br_index(sb, a->brid); + if (bindex < bstart) @@ -9586,7 +9629,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + + err = 0; + dentry = file->f_path.dentry; -+ file->f_version = dentry->d_inode->i_version; ++ file->f_version = d_inode(dentry)->i_version; + bindex = au_dbstart(dentry); + au_set_fbstart(file, bindex); + btail = au_dbtaildir(dentry); @@ -9710,7 +9753,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + + err = 0; + sb = dentry->d_sb; -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + IMustLock(inode); + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) { @@ -9764,12 +9807,14 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c +{ + int err; + struct dentry *dentry; ++ struct inode *inode; + struct super_block *sb; + struct mutex *mtx; + + err = 0; + dentry = file->f_path.dentry; -+ mtx = &dentry->d_inode->i_mutex; ++ inode = d_inode(dentry); ++ mtx = &inode->i_mutex; + mutex_lock(mtx); + sb = dentry->d_sb; + si_noflush_read_lock(sb); @@ -9779,7 +9824,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + di_write_lock_child(dentry); + err = au_do_fsync_dir_no_file(dentry, datasync); + } -+ au_cpup_attr_timesizes(dentry->d_inode); ++ au_cpup_attr_timesizes(inode); + di_write_unlock(dentry); + if (file) + fi_write_unlock(file); @@ -9801,7 +9846,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos); + + dentry = file->f_path.dentry; -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + IMustLock(inode); + + sb = dentry->d_sb; @@ -9957,7 +10002,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + struct inode *h_inode; + + h_dentry = au_h_dptr(dentry, arg->bindex); -+ h_inode = h_dentry->d_inode; ++ h_inode = d_inode(h_dentry); + /* todo: i_mode changes anytime? */ + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); @@ -10022,7 +10067,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + struct dentry *h_dentry; + + h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && h_dentry->d_inode) { ++ if (h_dentry && d_is_positive(h_dentry)) { + arg.bindex = bindex; + err = test_empty(dentry, &arg); + } @@ -10054,7 +10099,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + struct dentry *h_dentry; + + h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && h_dentry->d_inode) { ++ if (h_dentry && d_is_positive(h_dentry)) { + arg.bindex = bindex; + err = sio_test_empty(dentry, &arg); + } @@ -10081,7 +10126,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c +}; diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h --- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dir.h 2015-06-22 08:27:37.877501704 +0200 ++++ linux/fs/aufs/dir.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -10216,7 +10261,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h +#endif /* __AUFS_DIR_H__ */ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c --- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dynop.c 2015-06-22 08:29:23.706757681 +0200 ++++ linux/fs/aufs/dynop.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2010-2015 Junjiro R. Okajima @@ -10589,7 +10634,7 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c +} diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h --- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dynop.h 2015-06-22 08:29:23.706757681 +0200 ++++ linux/fs/aufs/dynop.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010-2015 Junjiro R. Okajima @@ -10667,8 +10712,8 @@ diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h +#endif /* __AUFS_DYNOP_H__ */ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c --- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/export.c 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,831 @@ ++++ linux/fs/aufs/export.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,832 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -10917,7 +10962,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c + hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { + spin_lock(&d->d_lock); + if (!au_test_anon(d) -+ && d->d_parent->d_inode->i_ino == dir_ino) { ++ && d_inode(d->d_parent)->i_ino == dir_ino) { + dentry = dget_dlock(d); + spin_unlock(&d->d_lock); + break; @@ -11076,7 +11121,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c + goto out_name; + + /* do not call vfsub_lkup_one() */ -+ dir = parent->d_inode; ++ dir = d_inode(parent); + mutex_lock(&dir->i_mutex); + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); + mutex_unlock(&dir->i_mutex); @@ -11084,7 +11129,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c + if (IS_ERR(dentry)) + goto out_name; + AuDebugOn(au_test_anon(dentry)); -+ if (unlikely(!dentry->d_inode)) { ++ if (unlikely(d_really_is_negative(dentry))) { + dput(dentry); + dentry = ERR_PTR(-ENOENT); + } @@ -11225,10 +11270,10 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c + + dentry = ERR_PTR(-ENOENT); + AuDebugOn(au_test_anon(path.dentry)); -+ if (unlikely(!path.dentry->d_inode)) ++ if (unlikely(d_really_is_negative(path.dentry))) + goto out_path; + -+ if (ino != path.dentry->d_inode->i_ino) ++ if (ino != d_inode(path.dentry)->i_ino) + dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); + else + dentry = dget(path.dentry); @@ -11309,7 +11354,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c + +accept: + if (!au_digen_test(dentry, au_sigen(sb)) -+ && dentry->d_inode->i_generation == fh[Fh_igen]) ++ && d_inode(dentry)->i_generation == fh[Fh_igen]) + goto out_unlock; /* success */ + + dput(dentry); @@ -11393,7 +11438,8 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c + dput(dentry); + if (unlikely(!parent)) + goto out_unlock; -+ dir = parent->d_inode; ++ if (d_really_is_positive(parent)) ++ dir = d_inode(parent); + } + + ii_read_lock_parent(dir); @@ -11502,7 +11548,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c +} diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c --- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/fhsm.c 2015-06-22 08:27:37.880835119 +0200 ++++ linux/fs/aufs/fhsm.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2011-2015 Junjiro R. Okajima @@ -11932,8 +11978,8 @@ diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c +} diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c --- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/file.c 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,844 @@ ++++ linux/fs/aufs/file.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,841 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -11984,15 +12030,12 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + /* a race condition can happen between open and unlink/rmdir */ + h_file = ERR_PTR(-ENOENT); + h_dentry = au_h_dptr(dentry, bindex); -+ if (au_test_nfsd() && !h_dentry) -+ goto out; -+ h_inode = h_dentry->d_inode; -+ if (au_test_nfsd() && !h_inode) ++ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry))) + goto out; ++ h_inode = d_inode(h_dentry); + spin_lock(&h_dentry->d_lock); + err = (!d_unhashed(dentry) && d_unlinked(h_dentry)) -+ || !h_inode -+ /* || !dentry->d_inode->i_nlink */ ++ /* || !d_inode(dentry)->i_nlink */ + ; + spin_unlock(&h_dentry->d_lock); + if (unlikely(err)) @@ -12006,7 +12049,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + goto out; + + /* drop flags for writing */ -+ if (au_test_ro(sb, bindex, dentry->d_inode)) { ++ if (au_test_ro(sb, bindex, d_inode(dentry))) { + if (force_wr && !(flags & O_WRONLY)) + force_wr = 0; + flags = au_file_roflags(flags); @@ -12069,7 +12112,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + struct au_hinode *hdir; + + DiMustWriteLock(dentry); -+ IiMustWriteLock(dentry->d_inode); ++ IiMustWriteLock(d_inode(dentry)); + + err = 0; + if (IS_ROOT(dentry)) @@ -12132,7 +12175,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + + h_path.mnt = au_br_mnt(br); + h_path.dentry = au_h_dptr(dentry, cpg.bsrc); -+ hdir = au_hi(parent->d_inode, cpg.bsrc); ++ hdir = au_hi(d_inode(parent), cpg.bsrc); + delegated = NULL; + err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1); + au_unpin(&pin); @@ -12316,13 +12359,13 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + }; + + au_update_dbstart(cpg.dentry); -+ inode = cpg.dentry->d_inode; ++ inode = d_inode(cpg.dentry); + h_inode = NULL; + if (au_dbstart(cpg.dentry) <= bcpup + && au_dbend(cpg.dentry) >= bcpup) { + h_dentry = au_h_dptr(cpg.dentry, bcpup); -+ if (h_dentry) -+ h_inode = h_dentry->d_inode; ++ if (h_dentry && d_is_positive(h_dentry)) ++ h_inode = d_inode(h_dentry); + } + hi_wh = au_hi_wh(inode, bcpup); + if (!hi_wh && !h_inode) @@ -12361,7 +12404,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + }; + + sb = cpg.dentry->d_sb; -+ inode = cpg.dentry->d_inode; ++ inode = d_inode(cpg.dentry); + cpg.bsrc = au_fbstart(file); + err = au_test_ro(sb, cpg.bsrc, inode); + if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) { @@ -12482,7 +12525,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + err = 0; + finfo = au_fi(file); + sb = cpg.dentry->d_sb; -+ inode = cpg.dentry->d_inode; ++ inode = d_inode(cpg.dentry); + cpg.bdst = au_ibstart(inode); + if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry)) + goto out; @@ -12662,7 +12705,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c + + err = 0; + dentry = file->f_path.dentry; -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + sigen = au_sigen(dentry->d_sb); + fi_write_lock(file); + figen = au_figen(file); @@ -12710,8 +12753,8 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c +} + +/* it will never be called, but necessary to support O_DIRECT */ -+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb, -+ struct iov_iter *iter, loff_t offset) ++static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, ++ loff_t offset) +{ BUG(); return 0; } + +/* they will never be called. */ @@ -12780,7 +12823,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c +}; diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h --- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/file.h 2015-06-22 08:27:37.880835119 +0200 ++++ linux/fs/aufs/file.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -13075,7 +13118,7 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h +#endif /* __AUFS_FILE_H__ */ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c --- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/finfo.c 2015-06-22 08:29:23.706757681 +0200 ++++ linux/fs/aufs/finfo.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -13236,8 +13279,8 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c +} diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c --- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/f_op.c 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,748 @@ ++++ linux/fs/aufs/f_op.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,738 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -13545,8 +13588,6 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + ssize_t err; + struct file *file; + ssize_t (*iter)(struct kiocb *, struct iov_iter *); -+ ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long, -+ loff_t); + + err = security_file_permission(h_file, rw); + if (unlikely(err)) @@ -13554,14 +13595,10 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + + err = -ENOSYS; + iter = NULL; -+ aio = NULL; -+ if (rw == MAY_READ) { ++ if (rw == MAY_READ) + iter = h_file->f_op->read_iter; -+ aio = h_file->f_op->aio_read; -+ } else if (rw == MAY_WRITE) { ++ else if (rw == MAY_WRITE) + iter = h_file->f_op->write_iter; -+ aio = h_file->f_op->aio_write; -+ } + + file = kio->ki_filp; + kio->ki_filp = h_file; @@ -13569,10 +13606,6 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + lockdep_off(); + err = iter(kio, iov_iter); + lockdep_on(); -+ } else if (aio) { -+ lockdep_off(); -+ err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos); -+ lockdep_on(); + } else + /* currently there is no such fs */ + WARN_ON_ONCE(1); @@ -13988,7 +14021,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c +}; diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h --- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/fstype.h 2015-06-22 08:27:37.880835119 +0200 ++++ linux/fs/aufs/fstype.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -14392,7 +14425,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h +#endif /* __AUFS_FSTYPE_H__ */ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c --- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/hfsnotify.c 2015-06-22 08:27:37.880835119 +0200 ++++ linux/fs/aufs/hfsnotify.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -14684,7 +14717,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c +}; diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c --- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/hfsplus.c 2015-06-22 08:29:23.706757681 +0200 ++++ linux/fs/aufs/hfsplus.c 2015-06-28 17:36:09.025073697 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010-2015 Junjiro R. Okajima @@ -14723,7 +14756,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c + + h_dentry = au_h_dptr(dentry, bindex); + AuDebugOn(!h_dentry); -+ AuDebugOn(!h_dentry->d_inode); ++ AuDebugOn(d_is_negative(h_dentry)); + + h_file = NULL; + if (au_test_hfsplus(h_dentry->d_sb) @@ -14744,8 +14777,8 @@ diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c +} diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c --- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/hnotify.c 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,714 @@ ++++ linux/fs/aufs/hnotify.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,710 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -14919,10 +14952,10 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + continue; + + au_digen_dec(d); -+ if (d->d_inode) ++ if (d_really_is_positive(d)) + /* todo: reset children xino? + cached children only? */ -+ au_iigen_dec(d->d_inode); ++ au_iigen_dec(d_inode(d)); + } + } + @@ -15000,12 +15033,8 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c +static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir) +{ + int err; -+ struct inode *inode; + -+ inode = dentry->d_inode; -+ if (IS_ROOT(dentry) -+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */ -+ ) { ++ if (IS_ROOT(dentry)) { + pr_warn("branch root dir was changed\n"); + return 0; + } @@ -15013,11 +15042,11 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + err = 0; + if (!isdir) { + au_digen_dec(dentry); -+ if (inode) -+ au_iigen_dec(inode); ++ if (d_really_is_positive(dentry)) ++ au_iigen_dec(d_inode(dentry)); + } else { + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR); -+ if (inode) ++ if (d_really_is_positive(dentry)) + err = hn_gen_tree(dentry); + } + @@ -15237,8 +15266,8 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, + a->dir); + try_iput = 0; -+ if (dentry) -+ inode = dentry->d_inode; ++ if (dentry && d_really_is_positive(dentry)) ++ inode = d_inode(dentry); + if (xino && !inode && h_ino + && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0) + || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0) @@ -15462,7 +15491,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c +} diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c --- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/iinfo.c 2015-06-22 08:27:37.884168534 +0200 ++++ linux/fs/aufs/iinfo.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -15743,8 +15772,8 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c +} diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c --- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/inode.c 2015-06-22 08:27:37.884168534 +0200 -@@ -0,0 +1,495 @@ ++++ linux/fs/aufs/inode.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,500 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -15881,18 +15910,19 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + flags = au_hi_flags(inode, isdir); + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { -+ struct inode *h_i; ++ struct inode *h_i, *h_inode; + struct dentry *h_d; + + h_d = au_h_dptr(dentry, bindex); -+ if (!h_d || !h_d->d_inode) ++ if (!h_d || d_is_negative(h_d)) + continue; + -+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT)); ++ h_inode = d_inode(h_d); ++ AuDebugOn(mode != (h_inode->i_mode & S_IFMT)); + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { + h_i = au_h_iptr(inode, bindex); + if (h_i) { -+ if (h_i == h_d->d_inode) ++ if (h_i == h_inode) + continue; + err = -EIO; + break; @@ -15902,7 +15932,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + iinfo->ii_bstart = bindex; + if (iinfo->ii_bend < bindex) + iinfo->ii_bend = bindex; -+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags); ++ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags); + update = 1; + } + au_update_ibrange(inode, /*do_put_zero*/0); @@ -15933,7 +15963,8 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + err = 0; + isdir = 0; + bstart = au_dbstart(dentry); -+ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ h_dentry = au_h_dptr(dentry, bstart); ++ h_inode = d_inode(h_dentry); + mode = h_inode->i_mode; + switch (mode & S_IFMT) { + case S_IFREG: @@ -15982,7 +16013,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry) + au_set_h_iptr(inode, bindex, -+ au_igrab(h_dentry->d_inode), flags); ++ au_igrab(d_inode(h_dentry)), flags); + } + au_cpup_attr_all(inode, /*force*/1); + /* @@ -16007,6 +16038,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + struct au_iigen iigen; + aufs_bindex_t bindex, bend; + struct inode *h_inode, *h_dinode; ++ struct dentry *h_dentry; + + /* + * before this function, if aufs got any iinfo lock, it must be only @@ -16019,7 +16051,8 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + + err = 1; + ii_write_lock_new_child(inode); -+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode; ++ h_dentry = au_h_dptr(dentry, au_dbstart(dentry)); ++ h_dinode = d_inode(h_dentry); + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); @@ -16081,7 +16114,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c +/* todo: return with unlocked? */ +struct inode *au_new_inode(struct dentry *dentry, int must_new) +{ -+ struct inode *inode; ++ struct inode *inode, *h_inode; + struct dentry *h_dentry; + struct super_block *sb; + struct mutex *mtx; @@ -16092,7 +16125,8 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + sb = dentry->d_sb; + bstart = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bstart); -+ h_ino = h_dentry->d_inode->i_ino; ++ h_inode = d_inode(h_dentry); ++ h_ino = h_inode->i_ino; + + /* + * stop 'race'-ing between hardlinks under different @@ -16175,7 +16209,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c + mutex_lock(mtx); + } + -+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode))) ++ if (unlikely(au_test_fs_unique_ino(h_inode))) + AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," + " b%d, %s, %pd, hi%lu, i%lu.\n", + bstart, au_sbtype(h_dentry->d_sb), dentry, @@ -16242,7 +16276,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c +} diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h --- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/inode.h 2015-06-22 08:27:37.884168534 +0200 ++++ linux/fs/aufs/inode.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,673 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -16919,7 +16953,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h +#endif /* __AUFS_INODE_H__ */ diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c --- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/ioctl.c 2015-06-22 08:29:23.706757681 +0200 ++++ linux/fs/aufs/ioctl.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -17142,8 +17176,8 @@ diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c +#endif diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c --- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op_add.c 2015-06-22 08:27:37.880835119 +0200 -@@ -0,0 +1,930 @@ ++++ linux/fs/aufs/i_op_add.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,932 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -17186,7 +17220,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + bwh = -1; + sb = dir->i_sb; + if (wh_dentry) { -+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ + IMustLock(h_dir); + AuDebugOn(au_h_iptr(dir, bindex) != h_dir); + bwh = au_dbwh(dentry); @@ -17201,7 +17235,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + inode = au_new_inode(dentry, /*must_new*/1); + if (!IS_ERR(inode)) { + d_instantiate(dentry, inode); -+ dir = dentry->d_parent->d_inode; /* dir inode is locked */ ++ dir = d_inode(dentry->d_parent); /* dir inode is locked */ + IMustLock(dir); + au_dir_ts(dir, bindex); + dir->i_version++; @@ -17235,7 +17269,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + err = 0; + if (unlikely(d_unhashed(dentry))) + err = -ENOENT; -+ if (unlikely(dentry->d_inode)) ++ if (unlikely(d_really_is_positive(dentry))) + err = -EEXIST; + return err; +} @@ -17257,15 +17291,17 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + goto out; + + h_dentry = au_h_dptr(dentry, bindex); -+ h_inode = h_dentry->d_inode; -+ if (!dentry->d_inode) { ++ if (d_really_is_negative(dentry)) { + err = -EEXIST; -+ if (unlikely(h_inode)) ++ if (unlikely(d_is_positive(h_dentry))) + goto out; + } else { + /* rename(2) case */ + err = -EIO; -+ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ if (unlikely(d_is_negative(h_dentry))) ++ goto out; ++ h_inode = d_inode(h_dentry); ++ if (unlikely(!h_inode->i_nlink)) + goto out; + + h_mode = h_inode->i_mode; @@ -17460,7 +17496,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + err = epilog(dir, bstart, wh_dentry, dentry); + + /* revert */ -+ if (unlikely(created && err && a->h_path.dentry->d_inode)) { ++ if (unlikely(created && err && d_is_positive(a->h_path.dentry))) { + /* no delegation since it is just created */ + rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL, + /*force*/0); @@ -17573,7 +17609,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + parent = d_find_any_alias(dir); + AuDebugOn(!parent); + di_write_lock_parent(parent); -+ if (unlikely(parent->d_inode != dir)) ++ if (unlikely(d_inode(parent) != dir)) + goto out_parent; + + err = au_digen_test(parent, au_sigen(sb)); @@ -17599,7 +17635,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + goto out_parent; + + h_parent = au_h_dptr(parent, bindex); -+ err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC); ++ err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC); + if (unlikely(err)) + goto out_mnt; + @@ -17716,7 +17752,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + plink = 0; + h_inode = NULL; + sb = src_dentry->d_sb; -+ inode = src_dentry->d_inode; ++ inode = d_inode(src_dentry); + if (au_ibstart(inode) <= a->bdst) + h_inode = au_h_iptr(inode, a->bdst); + if (!h_inode || !h_inode->i_nlink) { @@ -17730,7 +17766,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + au_set_h_dptr(dentry, a->bdst, NULL); + AuDbg("temporary d_inode...\n"); + spin_lock(&dentry->d_lock); -+ dentry->d_inode = src_dentry->d_inode; /* tmp */ ++ dentry->d_inode = d_inode(src_dentry); /* tmp */ + spin_unlock(&dentry->d_lock); + h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0); + if (IS_ERR(h_file)) @@ -17769,7 +17805,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + if (IS_ERR(h_src_dentry)) + goto out; + -+ if (unlikely(!h_src_dentry->d_inode)) { ++ if (unlikely(d_is_negative(h_src_dentry))) { + dput(h_src_dentry); + h_src_dentry = NULL; + } @@ -17815,7 +17851,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + }; + + IMustLock(dir); -+ inode = src_dentry->d_inode; ++ inode = d_inode(src_dentry); + IMustLock(inode); + + err = -ENOMEM; @@ -17901,7 +17937,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + if (!err) { + h_src_dentry = au_h_dptr(src_dentry, a->bdst); + err = -ENOENT; -+ if (h_src_dentry && h_src_dentry->d_inode) { ++ if (h_src_dentry && d_is_positive(h_src_dentry)) { + delegated = NULL; + err = vfsub_link(h_src_dentry, + au_pinned_h_dir(&a->pin), @@ -18017,7 +18053,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + + /* make the dir opaque */ + diropq = 0; -+ h_mtx = &h_path.dentry->d_inode->i_mutex; ++ h_mtx = &d_inode(h_path.dentry)->i_mutex; + if (wh_dentry + || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); @@ -18076,8 +18112,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c +} diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c --- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op.c 2015-06-22 08:29:23.706757681 +0200 -@@ -0,0 +1,1445 @@ ++++ linux/fs/aufs/i_op.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,1447 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -18492,7 +18528,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + struct inode *h_dir; + + if (add_entry) -+ IMustLock(parent->d_inode); ++ IMustLock(d_inode(parent)); + else + di_write_lock_parent(parent); + @@ -18507,7 +18543,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + } + if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) { + h_parent = au_h_dptr(parent, bcpup); -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + err = au_lkup_neg(dentry, bcpup, /*wh*/0); + /* todo: no unlock here */ @@ -18515,7 +18551,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + + AuDbg("bcpup %d\n", bcpup); + if (!err) { -+ if (!dentry->d_inode) ++ if (d_really_is_negative(dentry)) + au_set_h_dptr(dentry, bstart, NULL); + au_update_dbrange(dentry, /*do_put_zero*/0); + } @@ -18566,7 +18602,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + bcpup = err; + } + -+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) { ++ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) { + if (add_entry) + err = AuWbrCopyup(sbinfo, dentry); + else { @@ -18583,7 +18619,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + } + } else { + bcpup = args->force_btgt; -+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode)); ++ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry))); + } + + AuDbg("bstart %d, bcpup %d\n", bstart, bcpup); @@ -18594,7 +18630,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + /* copyup the new parent into the branch we process */ + err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart); + if (err >= 0) { -+ if (!dentry->d_inode) { ++ if (d_really_is_negative(dentry)) { + au_set_h_dptr(dentry, bstart, NULL); + au_set_dbstart(dentry, bcpup); + au_set_dbend(dentry, bcpup); @@ -18629,7 +18665,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + au_hn_imtx_lock_nested(p->hdir, p->lsc_hi); + + err = -EBUSY; -+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode)) ++ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent))) + goto out; + + err = 0; @@ -18657,9 +18693,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) { + if (!h_d[i]) + continue; -+ h_i = h_d[i]->d_inode; -+ if (h_i) ++ if (d_is_positive(h_d[i])) { ++ h_i = d_inode(h_d[i]); + err = !h_i->i_nlink; ++ } + } + +out: @@ -18747,7 +18784,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + + h_dir = NULL; + p->h_parent = au_h_dptr(p->parent, p->bindex); -+ p->hdir = au_hi(p->parent->d_inode, p->bindex); ++ p->hdir = au_hi(d_inode(p->parent), p->bindex); + if (p->hdir) + h_dir = p->hdir->hi_inode; + @@ -18834,11 +18871,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c +int au_reval_for_attr(struct dentry *dentry, unsigned int sigen) +{ + int err; -+ struct inode *inode; + struct dentry *parent; + + err = 0; -+ inode = dentry->d_inode; + if (au_digen_test(dentry, sigen)) { + parent = dget_parent(dentry); + di_read_lock_parent(parent, AuLock_IR); @@ -18868,7 +18903,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + au_fset_wrdir(wr_dir_args.flags, ISDIR); + /* plink or hi_wh() case */ + bstart = au_dbstart(dentry); -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + ibstart = au_ibstart(inode); + if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode)) + wr_dir_args.force_btgt = ibstart; @@ -18893,8 +18928,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + goto out_parent; + + a->h_path.dentry = au_h_dptr(dentry, bstart); -+ a->h_inode = a->h_path.dentry->d_inode; + sz = -1; ++ a->h_inode = d_inode(a->h_path.dentry); + if (ia && (ia->ia_valid & ATTR_SIZE)) { + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); + if (ia->ia_size < i_size_read(a->h_inode)) @@ -18948,7 +18983,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + a->h_path.dentry = hi_wh; /* do not dget here */ + +out_unlock: -+ a->h_inode = a->h_path.dentry->d_inode; ++ a->h_inode = d_inode(a->h_path.dentry); + if (!err) + goto out; /* success */ + au_unpin(&a->pin); @@ -18971,7 +19006,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + struct file *file; + struct au_icpup_args *a; + -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + IMustLock(inode); + + err = -ENOMEM; @@ -19119,7 +19154,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + struct au_icpup_args *a; + struct inode *inode, *h_inode; + -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + IMustLock(inode); + + err = -ENOMEM; @@ -19150,7 +19185,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + break; + case AU_ACL_SET: + err = -EOPNOTSUPP; -+ h_inode = h_path.dentry->d_inode; ++ h_inode = d_inode(h_path.dentry); + if (h_inode->i_op->set_acl) + err = h_inode->i_op->set_acl(h_inode, + arg->u.acl_set.acl, @@ -19253,7 +19288,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + } else + di_read_lock_child(dentry, AuLock_IR); + -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + bindex = au_ibstart(inode); + h_path->mnt = au_sbr_mnt(sb, bindex); + h_sb = h_path->mnt->mnt_sb; @@ -19286,7 +19321,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + struct inode *inode; + struct super_block *sb; + -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + sb = dentry->d_sb; + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); + if (unlikely(err)) @@ -19298,13 +19333,13 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + /* illegally overlapped or something */ + goto out_fill; /* pretending success */ + -+ positive = !!h_path.dentry->d_inode; ++ positive = d_is_positive(h_path.dentry); + if (positive) + err = vfs_getattr(&h_path, st); + if (!err) { + if (positive) + au_refresh_iattr(inode, st, -+ h_path.dentry->d_inode->i_nlink); ++ d_inode(h_path.dentry)->i_nlink); + goto out_fill; /* success */ + } + AuTraceErr(err); @@ -19329,10 +19364,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + int err; + struct super_block *sb; + struct dentry *h_dentry; ++ struct inode *inode, *h_inode; + + err = -EINVAL; + h_dentry = au_h_dptr(dentry, bindex); -+ if (unlikely(!h_dentry->d_inode->i_op->readlink)) ++ h_inode = d_inode(h_dentry); ++ if (unlikely(!h_inode->i_op->readlink)) + goto out; + + err = security_inode_readlink(h_dentry); @@ -19340,11 +19377,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + goto out; + + sb = dentry->d_sb; -+ if (!au_test_ro(sb, bindex, dentry->d_inode)) { ++ inode = d_inode(dentry); ++ if (!au_test_ro(sb, bindex, inode)) { + vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry); -+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode); ++ fsstack_copy_attr_atime(inode, h_inode); + } -+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz); ++ err = h_inode->i_op->readlink(h_dentry, buf, bufsiz); + +out: + return err; @@ -19525,8 +19563,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c +}; diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c --- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op_del.c 2015-06-22 08:27:37.884168534 +0200 -@@ -0,0 +1,506 @@ ++++ linux/fs/aufs/i_op_del.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,510 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -19570,7 +19608,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + bstart = au_dbstart(dentry); + if (*bcpup < 0) { + *bcpup = bstart; -+ if (au_test_ro(sb, bstart, dentry->d_inode)) { ++ if (au_test_ro(sb, bstart, d_inode(dentry))) { + err = AuWbrCopyup(au_sbi(sb), dentry); + *bcpup = err; + if (unlikely(err < 0)) @@ -19578,7 +19616,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + } + } else + AuDebugOn(bstart < *bcpup -+ || au_test_ro(sb, *bcpup, dentry->d_inode)); ++ || au_test_ro(sb, *bcpup, d_inode(dentry))); + AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart); + + if (*bcpup != bstart) { @@ -19622,10 +19660,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + struct inode *h_inode; + + h_dentry = au_h_dptr(dentry, bindex); -+ h_inode = h_dentry->d_inode; -+ if (dentry->d_inode) { ++ if (d_really_is_positive(dentry)) { + err = -ENOENT; -+ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ if (unlikely(d_is_negative(h_dentry))) ++ goto out; ++ h_inode = d_inode(h_dentry); ++ if (unlikely(!h_inode->i_nlink)) + goto out; + + h_mode = h_inode->i_mode; @@ -19640,7 +19680,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + } else { + /* rename(2) case */ + err = -EIO; -+ if (unlikely(h_inode)) ++ if (unlikely(d_is_positive(h_dentry))) + goto out; + } + @@ -19656,7 +19696,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + */ + err = -EACCES; + if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1) -+ && au_test_h_perm(h_parent->d_inode, ++ && au_test_h_perm(d_inode(h_parent), + MAY_EXEC | MAY_WRITE))) + goto out; + @@ -19746,6 +19786,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + int rmdir_later, err, dirwh; + struct dentry *h_dentry; + struct super_block *sb; ++ struct inode *inode; + + sb = dentry->d_sb; + SiMustAnyLock(sb); @@ -19755,7 +19796,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + goto out; + + /* stop monitoring */ -+ au_hn_free(au_hi(dentry->d_inode, bindex)); ++ inode = d_inode(dentry); ++ au_hn_free(au_hi(inode, bindex)); + + if (!au_test_fs_remote(h_dentry->d_sb)) { + dirwh = au_sbi(sb)->si_dirwh; @@ -19788,7 +19830,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c +{ + struct inode *inode; + -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + d_drop(dentry); + inode->i_ctime = dir->i_ctime; + @@ -19848,7 +19890,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + err = au_d_hashed_positive(dentry); + if (unlikely(err)) + goto out_unlock; -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + IMustLock(inode); + err = -EISDIR; + if (unlikely(d_is_dir(dentry))) @@ -19879,7 +19921,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + } + } else { + /* dir inode is locked */ -+ h_dir = wh_dentry->d_parent->d_inode; ++ h_dir = d_inode(wh_dentry->d_parent); + IMustLock(h_dir); + err = 0; + } @@ -19892,7 +19934,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + if (bindex == bstart) { + vfsub_update_h_iattr(&a->h_path, /*did*/NULL); + /*ignore*/ -+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; ++ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; + } else + /* todo: this timestamp may be reverted later */ + inode->i_ctime = h_dir->i_ctime; @@ -19949,7 +19991,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + err = au_alive_dir(dentry); + if (unlikely(err)) + goto out_unlock; -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + IMustLock(inode); + err = -ENOTDIR; + if (unlikely(!d_is_dir(dentry))) @@ -19989,7 +20031,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c + au_hn_free(au_hi(inode, bstart)); + + /* dir inode is locked */ -+ IMustLock(wh_dentry->d_parent->d_inode); ++ IMustLock(d_inode(wh_dentry->d_parent)); + err = 0; + } + @@ -20035,8 +20077,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c +} diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c --- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op_ren.c 2015-06-22 08:27:37.884168534 +0200 -@@ -0,0 +1,1015 @@ ++++ linux/fs/aufs/i_op_ren.c 2015-06-28 17:36:09.025073697 +0200 +@@ -0,0 +1,1017 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -20193,7 +20235,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + RevertFailure("lkup one %pd", a->dst_dentry); + return; + } -+ if (a->h_path.dentry->d_inode) { ++ if (d_is_positive(a->h_path.dentry)) { + d_drop(a->h_path.dentry); + dput(a->h_path.dentry); + return; @@ -20319,7 +20361,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + + /* prepare workqueue args for asynchronous rmdir */ + h_d = a->dst_h_dentry; -+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) { ++ if (au_ftest_ren(a->flags, ISDIR) && d_is_positive(h_d)) { + err = -ENOMEM; + a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS); + if (unlikely(!a->thargs)) @@ -20345,7 +20387,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + err = PTR_ERR(h_d); + if (IS_ERR(h_d)) + goto out_whsrc; -+ if (!h_d->d_inode) ++ if (d_is_negative(h_d)) + dput(h_d); + else + a->dst_wh_dentry = h_d; @@ -20365,7 +20407,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + a->dst_h_dentry = au_h_dptr(d, a->btgt); + } + -+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt); ++ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_bstart != a->btgt); + + /* rename by vfs_rename or cpup */ + d = a->dst_dentry; @@ -20392,7 +20434,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); + a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); + vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ -+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; ++ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; + + /* remove whiteout for dentry */ + if (a->dst_wh_dentry) { @@ -20565,20 +20607,18 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + goto out; + + err = -EIO; -+ h_inode = a->dst_h_dentry->d_inode; + isdir = !!au_ftest_ren(a->flags, ISDIR); -+ if (!a->dst_dentry->d_inode) { -+ if (unlikely(h_inode)) -+ goto out; -+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent, -+ isdir); ++ if (d_really_is_negative(a->dst_dentry)) { ++ if (d_is_negative(a->dst_h_dentry)) ++ err = au_may_add(a->dst_dentry, a->btgt, ++ a->dst_h_parent, isdir); + } else { -+ if (unlikely(!h_inode || !h_inode->i_nlink)) -+ goto out; -+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent, -+ isdir); -+ if (unlikely(err)) ++ if (unlikely(d_is_negative(a->dst_h_dentry))) + goto out; ++ h_inode = d_inode(a->dst_h_dentry); ++ if (h_inode->i_nlink) ++ err = au_may_del(a->dst_dentry, a->btgt, ++ a->dst_h_parent, isdir); + } + +out: @@ -20639,16 +20679,16 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, + a->dst_h_parent, a->dst_hdir); + udba = au_opt_udba(a->src_dentry->d_sb); -+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode -+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode)) ++ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent) ++ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent))) + err = au_busy_or_stale(); + if (!err && au_dbstart(a->src_dentry) == a->btgt) + err = au_h_verify(a->src_h_dentry, udba, -+ a->src_h_parent->d_inode, a->src_h_parent, ++ d_inode(a->src_h_parent), a->src_h_parent, + a->br); + if (!err && au_dbstart(a->dst_dentry) == a->btgt) + err = au_h_verify(a->dst_h_dentry, udba, -+ a->dst_h_parent->d_inode, a->dst_h_parent, ++ d_inode(a->dst_h_parent), a->dst_h_parent, + a->br); + if (!err) + goto out; /* success */ @@ -20755,7 +20795,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + struct au_branch *br; + + parent = dentry->d_parent; -+ IMustLock(parent->d_inode); /* dir is locked */ ++ IMustLock(d_inode(parent)); /* dir is locked */ + + bdiropq = au_dbdiropq(parent); + bwh = au_dbwh(dentry); @@ -20807,7 +20847,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + + a->h_path.dentry = a->src_h_dentry; + au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); -+ if (a->dst_h_dentry->d_inode) { ++ if (d_is_positive(a->dst_h_dentry)) { + au_fset_ren(a->flags, DT_DSTDIR); + a->h_path.dentry = a->dst_h_dentry; + au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); @@ -20825,14 +20865,14 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + + if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) { + h_d = a->src_dt[AuCHILD].dt_h_path.dentry; -+ h_mtx = &h_d->d_inode->i_mutex; ++ h_mtx = &d_inode(h_d)->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + au_dtime_revert(a->src_dt + AuCHILD); + mutex_unlock(h_mtx); + + if (au_ftest_ren(a->flags, DT_DSTDIR)) { + h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; -+ h_mtx = &h_d->d_inode->i_mutex; ++ h_mtx = &d_inode(h_d)->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + au_dtime_revert(a->dst_dt + AuCHILD); + mutex_unlock(h_mtx); @@ -20861,11 +20901,15 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + + a->src_dir = _src_dir; + a->src_dentry = _src_dentry; -+ a->src_inode = a->src_dentry->d_inode; ++ a->src_inode = NULL; ++ if (d_really_is_positive(a->src_dentry)) ++ a->src_inode = d_inode(a->src_dentry); + a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ + a->dst_dir = _dst_dir; + a->dst_dentry = _dst_dentry; -+ a->dst_inode = a->dst_dentry->d_inode; ++ a->dst_inode = NULL; ++ if (d_really_is_positive(a->dst_dentry)) ++ a->dst_inode = d_inode(a->dst_dentry); + a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ + if (a->dst_inode) { + IMustLock(a->dst_inode); @@ -20876,7 +20920,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN; + if (d_is_dir(a->src_dentry)) { + au_fset_ren(a->flags, ISDIR); -+ if (unlikely(d_is_positive(a->dst_dentry) ++ if (unlikely(d_really_is_positive(a->dst_dentry) + && !d_is_dir(a->dst_dentry))) + goto out_free; + err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, @@ -20913,7 +20957,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + * there may exist a problem somewhere else. + */ + err = -EINVAL; -+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode)) ++ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry))) + goto out_unlock; + + au_fset_ren(a->flags, ISSAMEDIR); /* temporary */ @@ -21054,7 +21098,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c +} diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig --- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/Kconfig 2015-06-22 08:27:37.874168290 +0200 ++++ linux/fs/aufs/Kconfig 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,185 @@ +config AUFS_FS + tristate "Aufs (Advanced multi layered unification filesystem) support" @@ -21243,7 +21287,7 @@ diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig +endif diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c --- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/loop.c 2015-06-22 08:29:23.706757681 +0200 ++++ linux/fs/aufs/loop.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -21392,7 +21436,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c +} diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h --- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/loop.h 2015-06-22 08:27:37.884168534 +0200 ++++ linux/fs/aufs/loop.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -21448,7 +21492,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h +#endif /* __AUFS_LOOP_H__ */ diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk --- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/magic.mk 2015-06-22 08:27:37.884168534 +0200 ++++ linux/fs/aufs/magic.mk 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,30 @@ + +# defined in ${srctree}/fs/fuse/inode.c @@ -21482,7 +21526,7 @@ diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk +endif diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile --- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/Makefile 2015-06-22 08:27:37.874168290 +0200 ++++ linux/fs/aufs/Makefile 2015-06-28 17:35:44.344717109 +0200 @@ -0,0 +1,44 @@ + +include ${src}/magic.mk @@ -21530,7 +21574,7 @@ diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c --- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/module.c 2015-06-22 08:27:37.884168534 +0200 ++++ linux/fs/aufs/module.c 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -21744,7 +21788,7 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c +module_exit(aufs_exit); diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h --- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/module.h 2015-06-22 08:27:37.884168534 +0200 ++++ linux/fs/aufs/module.h 2015-06-28 17:35:44.348050491 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -21852,7 +21896,7 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h +#endif /* __AUFS_MODULE_H__ */ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c --- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/mvdown.c 2015-06-22 08:27:37.884168534 +0200 ++++ linux/fs/aufs/mvdown.c 2015-06-28 17:36:09.025073697 +0200 @@ -0,0 +1,694 @@ +/* + * Copyright (C) 2011-2015 Junjiro R. Okajima @@ -22006,7 +22050,7 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c + AuPin_MNT_WRITE | AuPin_DI_LOCKED); + err = au_do_pin(&a->mvd_pin_src); + AuTraceErr(err); -+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode; ++ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); + if (unlikely(err)) { + AU_MVD_PR(dmsg, "pin_src failed\n"); + goto out_dst; @@ -22020,7 +22064,7 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c + au_opt_udba(a->sb), + AuPin_MNT_WRITE | AuPin_DI_LOCKED); + AuTraceErr(err); -+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode; ++ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); + if (unlikely(err)) { + AU_MVD_PR(dmsg, "pin_src failed\n"); + au_pin_hdir_lock(&a->mvd_pin_dst); @@ -22114,10 +22158,10 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c + } + + err = 0; -+ if (h_path.dentry->d_inode) { ++ if (d_is_positive(h_path.dentry)) { + h_path.mnt = au_br_mnt(br); + delegated = NULL; -+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path, ++ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path, + &delegated, /*force*/0); + if (unlikely(err == -EWOULDBLOCK)) { + pr_warn("cannot retry for NFSv4 delegation" @@ -22499,13 +22543,13 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c + args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R); + args->mvdown.au_errno = 0; + args->dentry = dentry; -+ args->inode = dentry->d_inode; ++ args->inode = d_inode(dentry); + args->sb = dentry->d_sb; + + err = -ENOENT; + dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG); + args->parent = dget_parent(dentry); -+ args->dir = args->parent->d_inode; ++ args->dir = d_inode(args->parent); + mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT); + dput(args->parent); + if (unlikely(args->parent != dentry->d_parent)) { @@ -22550,8 +22594,8 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c +} diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c --- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/opts.c 2015-06-22 08:29:23.710091096 +0200 -@@ -0,0 +1,1854 @@ ++++ linux/fs/aufs/opts.c 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,1835 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -22598,7 +22642,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + Opt_warn_perm, Opt_nowarn_perm, + Opt_wbr_copyup, Opt_wbr_create, + Opt_fhsm_sec, -+ Opt_refrof, Opt_norefrof, + Opt_verbose, Opt_noverbose, + Opt_sum, Opt_nosum, Opt_wsum, + Opt_dirperm1, Opt_nodirperm1, @@ -22682,9 +22725,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + {Opt_dirperm1, "dirperm1"}, + {Opt_nodirperm1, "nodirperm1"}, + -+ {Opt_refrof, "refrof"}, -+ {Opt_norefrof, "norefrof"}, -+ + {Opt_verbose, "verbose"}, + {Opt_verbose, "v"}, + {Opt_noverbose, "noverbose"}, @@ -23250,12 +23290,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + case Opt_nowarn_perm: + AuLabel(nowarn_perm); + break; -+ case Opt_refrof: -+ AuLabel(refrof); -+ break; -+ case Opt_norefrof: -+ AuLabel(norefrof); -+ break; + case Opt_verbose: + AuLabel(verbose); + break; @@ -23742,8 +23776,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + case Opt_diropq_w: + case Opt_warn_perm: + case Opt_nowarn_perm: -+ case Opt_refrof: -+ case Opt_norefrof: + case Opt_verbose: + case Opt_noverbose: + case Opt_sum: @@ -23933,13 +23965,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + au_opt_clr(sbinfo->si_mntflags, WARN_PERM); + break; + -+ case Opt_refrof: -+ au_opt_set(sbinfo->si_mntflags, REFROF); -+ break; -+ case Opt_norefrof: -+ au_opt_clr(sbinfo->si_mntflags, REFROF); -+ break; -+ + case Opt_verbose: + au_opt_set(sbinfo->si_mntflags, VERBOSE); + break; @@ -24172,7 +24197,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + err = 0; + fhsm = 0; + root = sb->s_root; -+ dir = root->d_inode; ++ dir = d_inode(root); + do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) { @@ -24345,7 +24370,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + /* go on even if err */ + } + if (au_opt_test(tmp, UDBA_HNOTIFY)) { -+ dir = sb->s_root->d_inode; ++ dir = d_inode(sb->s_root); + au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); + } + @@ -24363,7 +24388,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + + SiMustWriteLock(sb); + -+ dir = sb->s_root->d_inode; ++ dir = d_inode(sb->s_root); + sbinfo = au_sbi(sb); + err = 0; + opt_xino = NULL; @@ -24408,8 +24433,8 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c +} diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h --- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/opts.h 2015-06-22 08:27:37.887501948 +0200 -@@ -0,0 +1,211 @@ ++++ linux/fs/aufs/opts.h 2015-06-28 17:35:44.351383872 +0200 +@@ -0,0 +1,210 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -24454,7 +24479,6 @@ diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h +#define AuOpt_PLINK (1 << 6) /* pseudo-link */ +#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm + bits */ -+#define AuOpt_REFROF (1 << 8) /* unimplemented */ +#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */ +#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ +#define AuOpt_SUM_W (1 << 11) /* unimplemented */ @@ -24623,8 +24647,8 @@ diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h +#endif /* __AUFS_OPTS_H__ */ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c --- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/plink.c 2015-06-22 08:27:37.887501948 +0200 -@@ -0,0 +1,532 @@ ++++ linux/fs/aufs/plink.c 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,528 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -24829,7 +24853,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + struct dentry *h_dentry; + struct mutex *h_mtx; + -+ h_mtx = &h_parent->d_inode->i_mutex; ++ h_mtx = &d_inode(h_parent)->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); + h_dentry = vfsub_lkup_one(tgtname, h_parent); + mutex_unlock(h_mtx); @@ -24847,7 +24871,6 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c +{ + struct dentry *h_dentry, *h_parent; + struct au_branch *br; -+ struct inode *h_dir; + int wkq_err; + char a[PLINK_NAME_LEN]; + struct qstr tgtname = QSTR_INIT(a, 0); @@ -24856,7 +24879,6 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + + br = au_sbr(inode->i_sb, bindex); + h_parent = br->br_wbr->wbr_plink; -+ h_dir = h_parent->d_inode; + tgtname.len = plink_name(a, sizeof(a), inode, bindex); + + if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { @@ -24886,7 +24908,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + }; + struct inode *h_dir, *delegated; + -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); +again: + h_path.dentry = vfsub_lkup_one(tgt, h_parent); @@ -24897,8 +24919,8 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + err = 0; + /* wh.plink dir is not monitored */ + /* todo: is it really safe? */ -+ if (h_path.dentry->d_inode -+ && h_path.dentry->d_inode != h_dentry->d_inode) { ++ if (d_is_positive(h_path.dentry) ++ && d_inode(h_path.dentry) != d_inode(h_dentry)) { + delegated = NULL; + err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0); + if (unlikely(err == -EWOULDBLOCK)) { @@ -24911,7 +24933,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + if (!err) + goto again; + } -+ if (!err && !h_path.dentry->d_inode) { ++ if (!err && d_is_negative(h_path.dentry)) { + delegated = NULL; + err = vfsub_link(h_dentry, h_dir, &h_path, &delegated); + if (unlikely(err == -EWOULDBLOCK)) { @@ -24947,13 +24969,11 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + int err, wkq_err; + struct au_wbr *wbr; + struct dentry *h_parent; -+ struct inode *h_dir; + char a[PLINK_NAME_LEN]; + struct qstr tgtname = QSTR_INIT(a, 0); + + wbr = au_sbr(inode->i_sb, bindex)->br_wbr; + h_parent = wbr->wbr_plink; -+ h_dir = h_parent->d_inode; + tgtname.len = plink_name(a, sizeof(a), inode, bindex); + + /* always superio. */ @@ -25159,7 +25179,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c +} diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c --- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/poll.c 2015-06-22 08:29:23.710091096 +0200 ++++ linux/fs/aufs/poll.c 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -25215,7 +25235,7 @@ diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c +} diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c --- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/posix_acl.c 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/posix_acl.c 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2014-2015 Junjiro R. Okajima @@ -25318,7 +25338,7 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c +} diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c --- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/procfs.c 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/procfs.c 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2010-2015 Junjiro R. Okajima @@ -25491,7 +25511,7 @@ diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c +} diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c --- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/rdu.c 2015-06-22 08:29:23.710091096 +0200 ++++ linux/fs/aufs/rdu.c 2015-06-28 17:36:09.028407078 +0200 @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -25652,7 +25672,7 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c + goto out; + + dentry = file->f_path.dentry; -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); +#if 1 + mutex_lock(&inode->i_mutex); +#else @@ -25883,7 +25903,7 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c +#endif diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h --- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/rwsem.h 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/rwsem.h 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -26078,8 +26098,8 @@ diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h +#endif /* __AUFS_RWSEM_H__ */ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c --- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sbinfo.c 2015-06-22 08:27:37.887501948 +0200 -@@ -0,0 +1,354 @@ ++++ linux/fs/aufs/sbinfo.c 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,356 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -26245,13 +26265,15 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c +unsigned int au_sigen_inc(struct super_block *sb) +{ + unsigned int gen; ++ struct inode *inode; + + SiMustWriteLock(sb); + + gen = ++au_sbi(sb)->si_generation; + au_update_digen(sb->s_root); -+ au_update_iigen(sb->s_root->d_inode, /*half*/0); -+ sb->s_root->d_inode->i_version++; ++ inode = d_inode(sb->s_root); ++ au_update_iigen(inode, /*half*/0); ++ inode->i_version++; + return gen; +} + @@ -26436,7 +26458,7 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c +} diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h --- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/spl.h 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/spl.h 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -26551,8 +26573,8 @@ diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h +#endif /* __AUFS_SPL_H__ */ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c --- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/super.c 2015-06-22 08:29:23.710091096 +0200 -@@ -0,0 +1,1007 @@ ++++ linux/fs/aufs/super.c 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,1004 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -26813,7 +26835,6 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + AuBool(PLINK, plink); + AuBool(DIO, dio); + AuBool(DIRPERM1, dirperm1); -+ /* AuBool(REFROF, refrof); */ + + v = sbinfo->si_wbr_create; + if (v != AuWbrCreate_Def) @@ -27128,7 +27149,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + di_read_lock_parent(parent, AuLock_IR); + err = au_refresh_dentry(dentry, parent); + if (!err && dir_flags) -+ au_hn_reset(dentry->d_inode, dir_flags); ++ au_hn_reset(d_inode(dentry), dir_flags); + di_read_unlock(parent, AuLock_IR); + di_write_unlock(dentry); + @@ -27141,14 +27162,12 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c +{ + int err; + struct dentry *parent; -+ struct inode *inode; + + err = 0; + parent = dget_parent(dentry); + if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) { -+ inode = dentry->d_inode; -+ if (inode) { -+ if (!S_ISDIR(inode->i_mode)) ++ if (d_really_is_positive(dentry)) { ++ if (!d_is_dir(dentry)) + err = au_do_refresh(dentry, /*dir_flags*/0, + parent); + else { @@ -27175,7 +27194,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + struct dentry **dentries, *d; + struct au_sbinfo *sbinfo; + struct dentry *root = sb->s_root; -+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1); ++ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1); + + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) @@ -27256,7 +27275,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + + root = sb->s_root; + DiMustNoWaiters(root); -+ inode = root->d_inode; ++ inode = d_inode(root); + IiMustNoWaiters(inode); + + udba = au_opt_udba(sb); @@ -27336,7 +27355,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + goto out_opts; + + sbinfo = au_sbi(sb); -+ inode = root->d_inode; ++ inode = d_inode(root); + mutex_lock(&inode->i_mutex); + err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); + if (unlikely(err)) @@ -27462,7 +27481,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + goto out_info; + } + root = sb->s_root; -+ inode = root->d_inode; ++ inode = d_inode(root); + + /* + * actually we can parse options regardless aufs lock here. @@ -27562,8 +27581,8 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c +}; diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h --- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/super.h 2015-06-22 08:27:37.887501948 +0200 -@@ -0,0 +1,638 @@ ++++ linux/fs/aufs/super.h 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,635 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -27591,14 +27610,11 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h +#ifdef __KERNEL__ + +#include ++#include +#include "rwsem.h" +#include "spl.h" +#include "wkq.h" + -+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *); -+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t, -+ loff_t *); -+ +/* policies to select one among multiple writable branches */ +struct au_wbr_copyup_operations { + int (*copyup)(struct dentry *dentry); @@ -27713,8 +27729,8 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h + unsigned int si_mntflags; + + /* external inode number (bitmap and translation table) */ -+ au_readf_t si_xread; -+ au_writef_t si_xwrite; ++ vfs_readf_t si_xread; ++ vfs_writef_t si_xwrite; + struct file *si_xib; + struct mutex si_xib_mtx; /* protect xib members */ + unsigned long *si_xib_buf; @@ -28204,7 +28220,7 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h +#endif /* __AUFS_SUPER_H__ */ diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c --- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysaufs.c 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/sysaufs.c 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -28312,7 +28328,7 @@ diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c +} diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h --- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysaufs.h 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/sysaufs.h 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -28417,7 +28433,7 @@ diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h +#endif /* __SYSAUFS_H__ */ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c --- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysfs.c 2015-06-22 08:29:23.710091096 +0200 ++++ linux/fs/aufs/sysfs.c 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -28793,7 +28809,7 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c +} diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c --- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysrq.c 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/sysrq.c 2015-06-28 17:36:09.028407078 +0200 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -28845,7 +28861,7 @@ diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c + pr("root dentry\n"); + au_dpri_dentry(sb->s_root); + pr("root inode\n"); -+ au_dpri_inode(sb->s_root->d_inode); ++ au_dpri_inode(d_inode(sb->s_root)); +#endif + +#if 0 @@ -28954,7 +28970,7 @@ diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c +} diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c --- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vdir.c 2015-06-22 08:29:23.710091096 +0200 ++++ linux/fs/aufs/vdir.c 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,888 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -29846,8 +29862,8 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c +} diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c --- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vfsub.c 2015-06-22 08:29:23.710091096 +0200 -@@ -0,0 +1,846 @@ ++++ linux/fs/aufs/vfsub.c 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,848 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -29904,7 +29920,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + current_cred()); + if (!IS_ERR_OR_NULL(file) + && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) -+ i_readcount_inc(path->dentry->d_inode); ++ i_readcount_inc(d_inode(path->dentry)); + + return file; +} @@ -29982,7 +29998,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + int err; + + err = kern_path(name, flags, path); -+ if (!err && path->dentry->d_inode) ++ if (!err && d_is_positive(path->dentry)) + vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ + return err; +} @@ -29995,12 +30011,12 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + }; + + /* VFS checks it too, but by WARN_ON_ONCE() */ -+ IMustLock(parent->d_inode); ++ IMustLock(d_inode(parent)); + + path.dentry = lookup_one_len(name, parent, len); + if (IS_ERR(path.dentry)) + goto out; -+ if (path.dentry->d_inode) ++ if (d_is_positive(path.dentry)) + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ + +out: @@ -30161,7 +30177,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + + IMustLock(dir); + -+ err = au_test_nlink(src_dentry->d_inode); ++ err = au_test_nlink(d_inode(src_dentry)); + if (unlikely(err)) + return err; + @@ -30459,7 +30475,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + goto out; + } + -+ h_inode = h_path->dentry->d_inode; ++ h_inode = d_inode(h_path->dentry); + h_sb = h_inode->i_sb; + lockdep_off(); + sb_start_write(h_sb); @@ -30568,7 +30584,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + struct notify_change_args *a = args; + struct inode *h_inode; + -+ h_inode = a->path->dentry->d_inode; ++ h_inode = d_inode(a->path->dentry); + IMustLock(h_inode); + + *a->errp = -EPERM; @@ -30644,9 +30660,11 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + + if (!stop_sillyrename) + dget(d); -+ h_inode = d->d_inode; -+ if (h_inode) ++ h_inode = NULL; ++ if (d_is_positive(d)) { ++ h_inode = d_inode(d); + ihold(h_inode); ++ } + + lockdep_off(); + *a->errp = vfs_unlink(a->dir, d, a->delegated_inode); @@ -30696,7 +30714,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c +} diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h --- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vfsub.h 2015-06-22 08:29:23.710091096 +0200 ++++ linux/fs/aufs/vfsub.h 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -30986,7 +31004,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h +#endif /* __AUFS_VFSUB_H__ */ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c --- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/wbr_policy.c 2015-06-22 08:27:37.887501948 +0200 ++++ linux/fs/aufs/wbr_policy.c 2015-06-28 17:36:09.028407078 +0200 @@ -0,0 +1,765 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -31020,13 +31038,13 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + struct iattr ia; + struct inode *h_isrc; + -+ h_isrc = h_src->d_inode; ++ h_isrc = d_inode(h_src); + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; + ia.ia_mode = h_isrc->i_mode; + ia.ia_uid = h_isrc->i_uid; + ia.ia_gid = h_isrc->i_gid; + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags); ++ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags); + /* no delegation since it is just created */ + err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); + @@ -31081,7 +31099,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + goto out; + + err = 0; -+ if (h_path.dentry->d_inode) { ++ if (d_is_positive(h_path.dentry)) { + h_path.mnt = au_br_mnt(br); + err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path, + dentry); @@ -31106,8 +31124,8 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + bstart = au_dbstart(dentry); + /* dentry is di-locked */ + parent = dget_parent(dentry); -+ dir = parent->d_inode; -+ h_dir = h_parent->d_inode; ++ dir = d_inode(parent); ++ h_dir = d_inode(h_parent); + AuDebugOn(h_dir != au_h_iptr(dir, bdst)); + IMustLock(h_dir); + @@ -31129,7 +31147,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + au_fset_cpdown(*flags, WHED); + if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst) + au_fset_cpdown(*flags, PARENT_OPQ); -+ h_inode = h_path.dentry->d_inode; ++ h_inode = d_inode(h_path.dentry); + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + if (au_ftest_cpdown(*flags, WHED)) { + err = au_cpdown_dir_opq(dentry, bdst, flags); @@ -31150,7 +31168,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + goto out_opq; + } + -+ inode = dentry->d_inode; ++ inode = d_inode(dentry); + if (au_ibend(inode) < bdst) + au_set_ibend(inode, bdst); + au_set_h_iptr(inode, bdst, au_igrab(h_inode), @@ -31269,7 +31287,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + parent = dget_parent(dentry); + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) { + h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || !h_parent->d_inode) ++ if (!h_parent || d_is_negative(h_parent)) + continue; + + if (!au_br_rdonly(au_sbr(sb, bindex))) { @@ -31421,7 +31439,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + for (; bindex <= bend; bindex++) { + if (parent) { + h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || !h_parent->d_inode) ++ if (!h_parent || d_is_negative(h_parent)) + continue; + } + br = au_sbr(sb, bindex); @@ -31569,7 +31587,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + + for (bindex = bstart; bindex <= bend; bindex++) { + h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || !h_parent->d_inode) ++ if (!h_parent || d_is_negative(h_parent)) + continue; + + br = au_sbr(sb, bindex); @@ -31648,7 +31666,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + bstart = au_dbstart(parent); + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) { + h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || !h_parent->d_inode) ++ if (!h_parent || d_is_negative(h_parent)) + continue; + + if (!au_br_rdonly(au_sbr(sb, bindex))) { @@ -31755,8 +31773,8 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c +}; diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c --- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/whout.c 2015-06-22 08:29:23.710091096 +0200 -@@ -0,0 +1,1064 @@ ++++ linux/fs/aufs/whout.c 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,1063 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -31839,7 +31857,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + } + + err = 0; -+ if (!wh_dentry->d_inode) ++ if (d_is_negative(wh_dentry)) + goto out_wh; /* success */ + + err = 1; @@ -31848,7 +31866,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + + err = -EIO; + AuIOErr("%pd Invalid whiteout entry type 0%o.\n", -+ wh_dentry, wh_dentry->d_inode->i_mode); ++ wh_dentry, d_inode(wh_dentry)->i_mode); + +out_wh: + dput(wh_dentry); @@ -31864,7 +31882,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + int err; + struct inode *h_dir; + -+ h_dir = h_dentry->d_inode; ++ h_dir = d_inode(h_dentry); + err = au_wh_test(h_dentry, &diropq_name, + au_test_h_perm_sio(h_dir, MAY_EXEC)); + return err; @@ -31910,7 +31928,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + for (i = 0; i < 3; i++) { + sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++); + dentry = au_sio_lkup_one(&qs, h_parent); -+ if (IS_ERR(dentry) || !dentry->d_inode) ++ if (IS_ERR(dentry) || d_is_negative(dentry)) + goto out_name; + dput(dentry); + } @@ -31940,7 +31958,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + struct dentry *h_parent; + + h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + IMustLock(h_dir); + + h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); @@ -31979,7 +31997,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + * this may be a violation of unix fs semantics. + */ + force = (h_dir->i_mode & S_ISVTX) -+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid); ++ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid); + delegated = NULL; + err = vfsub_unlink(h_dir, h_path, &delegated, force); + if (unlikely(err == -EWOULDBLOCK)) { @@ -32015,9 +32033,8 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + if (IS_ERR(h_path.dentry)) + err = PTR_ERR(h_path.dentry); + else { -+ if (h_path.dentry->d_inode -+ && d_is_reg(h_path.dentry)) -+ err = do_unlink_wh(h_parent->d_inode, &h_path); ++ if (d_is_reg(h_path.dentry)) ++ err = do_unlink_wh(d_inode(h_parent), &h_path); + dput(h_path.dentry); + } + @@ -32035,7 +32052,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + int err; + struct inode *delegated; + -+ if (!whpath->dentry->d_inode) ++ if (d_is_negative(whpath->dentry)) + return; + + if (isdir) @@ -32056,7 +32073,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + +static int test_linkable(struct dentry *h_root) +{ -+ struct inode *h_dir = h_root->d_inode; ++ struct inode *h_dir = d_inode(h_root); + + if (h_dir->i_op->link) + return 0; @@ -32072,7 +32089,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + int err; + + err = -EEXIST; -+ if (!path->dentry->d_inode) { ++ if (d_is_negative(path->dentry)) { + int mode = S_IRWXU; + + if (au_test_nfs(path->dentry->d_sb)) @@ -32115,7 +32132,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + int err; + struct inode *h_dir; + -+ h_dir = h_root->d_inode; ++ h_dir = d_inode(h_root); + h_path->dentry = base[AuBrWh_BASE].dentry; + au_wh_clean(h_dir, h_path, /*isdir*/0); + h_path->dentry = base[AuBrWh_PLINK].dentry; @@ -32169,8 +32186,8 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + * todo: should this create be done in /sbin/mount.aufs helper? + */ + err = -EEXIST; -+ h_dir = h_root->d_inode; -+ if (!base[AuBrWh_BASE].dentry->d_inode) { ++ h_dir = d_inode(h_root); ++ if (d_is_negative(base[AuBrWh_BASE].dentry)) { + h_path->dentry = base[AuBrWh_BASE].dentry; + err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true); + } else if (d_is_reg(base[AuBrWh_BASE].dentry)) @@ -32261,7 +32278,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + + err = 0; + if (!au_br_writable(br->br_perm)) { -+ h_dir = h_root->d_inode; ++ h_dir = d_inode(h_root); + au_wh_init_ro(h_dir, base, &path); + } else if (!au_br_wh_linkable(br->br_perm)) { + err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path); @@ -32321,7 +32338,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + goto out; + + di_read_lock_parent(a->sb->s_root, AuLock_IR); -+ dir = a->sb->s_root->d_inode; ++ dir = d_inode(a->sb->s_root); + hdir = au_hi(dir, bindex); + h_root = au_h_dptr(a->sb->s_root, bindex); + AuDebugOn(h_root != au_br_dentry(a->br)); @@ -32417,7 +32434,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + struct inode *h_dir, *delegated; + + h_parent = wh->d_parent; /* dir inode is locked */ -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + IMustLock(h_dir); + + br = au_sbr(sb, bindex); @@ -32480,7 +32497,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + .dentry = opq_dentry, + .mnt = au_br_mnt(br) + }; -+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp); ++ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp); + if (!err) + au_set_dbdiropq(dentry, -1); + } @@ -32510,7 +32527,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + struct dentry *diropq, *h_dentry; + + h_dentry = au_h_dptr(dentry, bindex); -+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE)) ++ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE)) + diropq = do_diropq(dentry, bindex, flags); + else { + int wkq_err; @@ -32565,7 +32582,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + + sb = dentry->d_sb; + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); -+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) { ++ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) { + err = link_or_create_wh(sb, bindex, wh_dentry); + if (!err) { + au_set_dbwh(dentry, bindex); @@ -32700,11 +32717,11 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + struct inode *wh_inode, *h_dir; + struct au_branch *br; + -+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ + IMustLock(h_dir); + + br = au_sbr(dir->i_sb, bindex); -+ wh_inode = wh_dentry->d_inode; ++ wh_inode = d_inode(wh_dentry); + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); + + /* @@ -32776,7 +32793,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + err = -EIO; + ii_write_lock_parent(a->dir); + h_parent = dget_parent(a->wh_dentry); -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + hdir = au_hi(a->dir, bindex); + err = vfsub_mnt_want_write(au_br_mnt(a->br)); + if (unlikely(err)) @@ -32823,7 +32840,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c +} diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h --- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/whout.h 2015-06-22 08:27:37.890835363 +0200 ++++ linux/fs/aufs/whout.h 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -32912,7 +32929,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h +#endif /* __AUFS_WHOUT_H__ */ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c --- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/wkq.c 2015-06-22 08:27:37.890835363 +0200 ++++ linux/fs/aufs/wkq.c 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -33129,7 +33146,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c +} diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h --- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/wkq.h 2015-06-22 08:27:37.890835363 +0200 ++++ linux/fs/aufs/wkq.h 2015-06-28 17:35:44.351383872 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -33224,7 +33241,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h +#endif /* __AUFS_WKQ_H__ */ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c --- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/xattr.c 2015-06-22 08:27:37.890835363 +0200 ++++ linux/fs/aufs/xattr.c 2015-06-28 17:36:09.028407078 +0200 @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2014-2015 Junjiro R. Okajima @@ -33303,7 +33320,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + if (err == -ENODATA + || (err == -EOPNOTSUPP + && ((ignore_flags & au_xattr_out_of_list) -+ || (au_test_nfs_noacl(h_src->d_inode) ++ || (au_test_nfs_noacl(d_inode(h_src)) + && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) + || !strcmp(name, + XATTR_NAME_POSIX_ACL_DEFAULT)))) @@ -33315,7 +33332,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + } + + /* unlock it temporary */ -+ h_idst = h_dst->d_inode; ++ h_idst = d_inode(h_dst); + mutex_unlock(&h_idst->i_mutex); + err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0); + mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2); @@ -33339,8 +33356,8 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + + /* try stopping to update the source inode while we are referencing */ + /* there should not be the parent-child relationship between them */ -+ h_isrc = h_src->d_inode; -+ h_idst = h_dst->d_inode; ++ h_isrc = d_inode(h_src); ++ h_idst = d_inode(h_dst); + mutex_unlock(&h_idst->i_mutex); + mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD); + mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2); @@ -33572,8 +33589,8 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c +#endif diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c --- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/xino.c 2015-06-22 08:29:23.710091096 +0200 -@@ -0,0 +1,1322 @@ ++++ linux/fs/aufs/xino.c 2015-06-28 17:36:09.028407078 +0200 +@@ -0,0 +1,1297 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima + * @@ -33600,7 +33617,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c +#include "aufs.h" + +/* todo: unnecessary to support mmap_sem since kernel-space? */ -+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size, ++ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size, + loff_t *pos) +{ + ssize_t err; @@ -33629,7 +33646,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + +/* ---------------------------------------------------------------------- */ + -+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf, ++static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf, + size_t size, loff_t *pos) +{ + ssize_t err; @@ -33658,7 +33675,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + +struct do_xino_fwrite_args { + ssize_t *errp; -+ au_writef_t func; ++ vfs_writef_t func; + struct file *file; + void *buf; + size_t size; @@ -33671,8 +33688,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); +} + -+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, -+ loff_t *pos) ++ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, ++ size_t size, loff_t *pos) +{ + ssize_t err; + @@ -33720,7 +33737,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + + base = base_file->f_path.dentry; + parent = base->d_parent; /* dir inode is locked */ -+ dir = parent->d_inode; ++ dir = d_inode(parent); + IMustLock(dir); + + file = ERR_PTR(-EINVAL); @@ -33798,11 +33815,11 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + if (brid >= 0) + bindex = au_br_index(sb, brid); + if (bindex >= 0) { -+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex); ++ ldir->hdir = au_hi(d_inode(sb->s_root), bindex); + au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT); + } else { + ldir->parent = dget_parent(xino->f_path.dentry); -+ ldir->mtx = &ldir->parent->d_inode->i_mutex; ++ ldir->mtx = &d_inode(ldir->parent)->i_mutex; + mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT); + } +} @@ -33913,7 +33930,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + + err = 0; + sb = args->sb; -+ dir = sb->s_root->d_inode; ++ dir = d_inode(sb->s_root); + br = args->br; + + si_noflush_write_lock(sb); @@ -33990,7 +34007,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + +/* ---------------------------------------------------------------------- */ + -+static int au_xino_do_write(au_writef_t write, struct file *file, ++static int au_xino_do_write(vfs_writef_t write, struct file *file, + ino_t h_ino, ino_t ino) +{ + loff_t pos; @@ -34150,7 +34167,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + struct au_hinode *hi; + struct inode *h_inode; + struct au_branch *br; -+ au_writef_t xwrite; ++ vfs_writef_t xwrite; + + sb = inode->i_sb; + mnt_flags = au_mntflags(sb); @@ -34326,7 +34343,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + err = 0; + inode = file_inode(file); + h_parent = dget_parent(file->f_path.dentry); -+ h_dir = h_parent->d_inode; ++ h_dir = d_inode(h_parent); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + /* mnt_want_write() is unnecessary here */ + /* no delegation since it is just created */ @@ -34452,7 +34469,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + unsigned long pindex; + loff_t pos, pend; + struct au_sbinfo *sbinfo; -+ au_readf_t func; ++ vfs_readf_t func; + ino_t *ino; + unsigned long *p; + @@ -34570,31 +34587,6 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c +/* + * xino mount option handlers + */ -+static au_readf_t find_readf(struct file *h_file) -+{ -+ const struct file_operations *fop = h_file->f_op; -+ -+ if (fop->read) -+ return fop->read; -+ if (fop->aio_read) -+ return do_sync_read; -+ if (fop->read_iter) -+ return new_sync_read; -+ return ERR_PTR(-ENOSYS); -+} -+ -+static au_writef_t find_writef(struct file *h_file) -+{ -+ const struct file_operations *fop = h_file->f_op; -+ -+ if (fop->write) -+ return fop->write; -+ if (fop->aio_write) -+ return do_sync_write; -+ if (fop->write_iter) -+ return new_sync_write; -+ return ERR_PTR(-ENOSYS); -+} + +/* xino bitmap */ +static void xino_clear_xib(struct super_block *sb) @@ -34630,8 +34622,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = file; -+ sbinfo->si_xread = find_readf(file); -+ sbinfo->si_xwrite = find_writef(file); ++ sbinfo->si_xread = vfs_readf(file); ++ sbinfo->si_xwrite = vfs_writef(file); + + err = -ENOMEM; + if (!sbinfo->si_xib_buf) @@ -34692,7 +34684,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + } *fpair, *p; + struct au_branch *br; + struct inode *inode; -+ au_writef_t writef; ++ vfs_writef_t writef; + + SiMustWriteLock(sb); + @@ -34702,7 +34694,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + if (unlikely(!fpair)) + goto out; + -+ inode = sb->s_root->d_inode; ++ inode = d_inode(sb->s_root); + ino = AUFS_ROOT_INO; + writef = au_sbi(sb)->si_xwrite; + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { @@ -34792,7 +34784,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + } + + au_opt_set(sbinfo->si_mntflags, XINO); -+ dir = parent->d_inode; ++ dir = d_inode(parent); + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + /* mnt_want_write() is unnecessary here */ + err = au_xino_set_xib(sb, xino->file); @@ -34898,7 +34890,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c +} diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h --- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/include/uapi/linux/aufs_type.h 2015-06-22 08:29:23.710091096 +0200 ++++ linux/include/uapi/linux/aufs_type.h 2015-06-28 17:36:09.028407078 +0200 @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2005-2015 Junjiro R. Okajima @@ -34941,7 +34933,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin + +#include + -+#define AUFS_VERSION "3.x-rcN-20150622" ++#define AUFS_VERSION "4.x-rcN-20150622" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -35319,3 +35311,277 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin +#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int) + +#endif /* __AUFS_TYPE_H__ */ +aufs4.x-rcN loopback patch + +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 0160952..866f8e2 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -419,7 +419,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) + } + + struct switch_request { +- struct file *file; ++ struct file *file, *virt_file; + struct completion wait; + }; + +@@ -439,6 +439,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) + mapping = file->f_mapping; + mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); + lo->lo_backing_file = file; ++ lo->lo_backing_virt_file = p->virt_file; + lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ? + mapping->host->i_bdev->bd_block_size : PAGE_SIZE; + lo->old_gfp_mask = mapping_gfp_mask(mapping); +@@ -450,11 +451,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) + * First it needs to flush existing IO, it does this by sending a magic + * BIO down the pipe. The completion of this BIO does the actual switch. + */ +-static int loop_switch(struct loop_device *lo, struct file *file) ++static int loop_switch(struct loop_device *lo, struct file *file, ++ struct file *virt_file) + { + struct switch_request w; + + w.file = file; ++ w.virt_file = virt_file; + + /* freeze queue and wait for completion of scheduled requests */ + blk_mq_freeze_queue(lo->lo_queue); +@@ -473,7 +476,16 @@ static int loop_switch(struct loop_device *lo, struct file *file) + */ + static int loop_flush(struct loop_device *lo) + { +- return loop_switch(lo, NULL); ++ return loop_switch(lo, NULL, NULL); ++} ++ ++static struct file *loop_real_file(struct file *file) ++{ ++ struct file *f = NULL; ++ ++ if (file->f_path.dentry->d_sb->s_op->real_loop) ++ f = file->f_path.dentry->d_sb->s_op->real_loop(file); ++ return f; + } + + /* +@@ -488,6 +500,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, + unsigned int arg) + { + struct file *file, *old_file; ++ struct file *f, *virt_file = NULL, *old_virt_file; + struct inode *inode; + int error; + +@@ -504,9 +517,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, + file = fget(arg); + if (!file) + goto out; ++ f = loop_real_file(file); ++ if (f) { ++ virt_file = file; ++ file = f; ++ get_file(file); ++ } + + inode = file->f_mapping->host; + old_file = lo->lo_backing_file; ++ old_virt_file = lo->lo_backing_virt_file; + + error = -EINVAL; + +@@ -518,17 +538,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, + goto out_putf; + + /* and ... switch */ +- error = loop_switch(lo, file); ++ error = loop_switch(lo, file, virt_file); + if (error) + goto out_putf; + + fput(old_file); ++ if (old_virt_file) ++ fput(old_virt_file); + if (lo->lo_flags & LO_FLAGS_PARTSCAN) + ioctl_by_bdev(bdev, BLKRRPART, 0); + return 0; + + out_putf: + fput(file); ++ if (virt_file) ++ fput(virt_file); + out: + return error; + } +@@ -689,7 +713,7 @@ static void loop_config_discard(struct loop_device *lo) + static int loop_set_fd(struct loop_device *lo, fmode_t mode, + struct block_device *bdev, unsigned int arg) + { +- struct file *file, *f; ++ struct file *file, *f, *virt_file = NULL; + struct inode *inode; + struct address_space *mapping; + unsigned lo_blocksize; +@@ -704,6 +728,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, + file = fget(arg); + if (!file) + goto out; ++ f = loop_real_file(file); ++ if (f) { ++ virt_file = file; ++ file = f; ++ get_file(file); ++ } + + error = -EBUSY; + if (lo->lo_state != Lo_unbound) +@@ -752,6 +782,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, + lo->lo_device = bdev; + lo->lo_flags = lo_flags; + lo->lo_backing_file = file; ++ lo->lo_backing_virt_file = virt_file; + lo->transfer = NULL; + lo->ioctl = NULL; + lo->lo_sizelimit = 0; +@@ -783,6 +814,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, + + out_putf: + fput(file); ++ if (virt_file) ++ fput(virt_file); + out: + /* This is safe: open() is still holding a reference. */ + module_put(THIS_MODULE); +@@ -829,6 +862,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, + static int loop_clr_fd(struct loop_device *lo) + { + struct file *filp = lo->lo_backing_file; ++ struct file *virt_filp = lo->lo_backing_virt_file; + gfp_t gfp = lo->old_gfp_mask; + struct block_device *bdev = lo->lo_device; + +@@ -857,6 +891,7 @@ static int loop_clr_fd(struct loop_device *lo) + spin_lock_irq(&lo->lo_lock); + lo->lo_state = Lo_rundown; + lo->lo_backing_file = NULL; ++ lo->lo_backing_virt_file = NULL; + spin_unlock_irq(&lo->lo_lock); + + loop_release_xfer(lo); +@@ -898,6 +933,8 @@ static int loop_clr_fd(struct loop_device *lo) + * bd_mutex which is usually taken before lo_ctl_mutex. + */ + fput(filp); ++ if (virt_filp) ++ fput(virt_filp); + return 0; + } + +diff --git a/drivers/block/loop.h b/drivers/block/loop.h +index 301c27f..df84aa0 100644 +--- a/drivers/block/loop.h ++++ b/drivers/block/loop.h +@@ -46,7 +46,7 @@ struct loop_device { + int (*ioctl)(struct loop_device *, int cmd, + unsigned long arg); + +- struct file * lo_backing_file; ++ struct file * lo_backing_file, *lo_backing_virt_file; + struct block_device *lo_device; + unsigned lo_blocksize; + void *key_data; +diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c +index 91c2ce7..d4ee5a7 100644 +--- a/fs/aufs/f_op.c ++++ b/fs/aufs/f_op.c +@@ -389,7 +389,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, + if (IS_ERR(h_file)) + goto out; + +- if (au_test_loopback_kthread()) { ++ if (0 && au_test_loopback_kthread()) { + au_warn_loopback(h_file->f_path.dentry->d_sb); + if (file->f_mapping != h_file->f_mapping) { + file->f_mapping = h_file->f_mapping; +diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c +index 69f7e96..7941063 100644 +--- a/fs/aufs/loop.c ++++ b/fs/aufs/loop.c +@@ -130,3 +130,19 @@ void au_loopback_fin(void) + symbol_put(loop_backing_file); + kfree(au_warn_loopback_array); + } ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* support the loopback block device insude aufs */ ++ ++struct file *aufs_real_loop(struct file *file) ++{ ++ struct file *f; ++ ++ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb)); ++ fi_read_lock(file); ++ f = au_hf_top(file); ++ fi_read_unlock(file); ++ AuDebugOn(!f); ++ return f; ++} +diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h +index 6d9864d..3322557 100644 +--- a/fs/aufs/loop.h ++++ b/fs/aufs/loop.h +@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb); + + int au_loopback_init(void); + void au_loopback_fin(void); ++ ++struct file *aufs_real_loop(struct file *file); + #else ++AuStub(struct file *, loop_backing_file, return NULL) ++ + AuStubInt0(au_test_loopback_overlap, struct super_block *sb, + struct dentry *h_adding) + AuStubInt0(au_test_loopback_kthread, void) +@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb) + + AuStubInt0(au_loopback_init, void) + AuStubVoid(au_loopback_fin, void) ++ ++AuStub(struct file *, aufs_real_loop, return NULL, struct file *file) + #endif /* BLK_DEV_LOOP */ + + #endif /* __KERNEL__ */ +diff --git a/fs/aufs/super.c b/fs/aufs/super.c +index ee5780d..da35759 100644 +--- a/fs/aufs/super.c ++++ b/fs/aufs/super.c +@@ -807,7 +807,10 @@ static const struct super_operations aufs_sop = { + .statfs = aufs_statfs, + .put_super = aufs_put_super, + .sync_fs = aufs_sync_fs, +- .remount_fs = aufs_remount_fs ++ .remount_fs = aufs_remount_fs, ++#ifdef CONFIG_AUFS_BDEV_LOOP ++ .real_loop = aufs_real_loop ++#endif + }; + + /* ---------------------------------------------------------------------- */ +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 3229f97..f63cc0d 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1696,6 +1696,10 @@ struct super_operations { + struct shrink_control *); + long (*free_cached_objects)(struct super_block *, + struct shrink_control *); ++#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE) ++ /* and aufs */ ++ struct file *(*real_loop)(struct file *); ++#endif + }; + + /* diff --git a/kernel.spec b/kernel.spec index 41145f1e..984623f9 100644 --- a/kernel.spec +++ b/kernel.spec @@ -196,20 +196,20 @@ Patch85: kernel-hostap.patch Patch100: kernel-vserver-2.3.patch Patch101: kernel-vserver-fixes.patch -# git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git, read README +# git://github.com/sfjro/aufs4-standalone.git, read README # Patch creation: -# git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git -# cd aufs3-standalone -# git checkout -b aufs4.0 origin/aufs4.0 -# cat aufs3-kbuild.patch aufs3-base.patch aufs3-mmap.patch aufs3-standalone.patch > ~/rpm/packages/kernel/kernel-aufs3.patch +# git clone git://github.com/sfjro/aufs4-standalone.git +# cd aufs4-standalone +# git checkout -b aufs4.1 origin/aufs4.1 +# cat aufs4-kbuild.patch aufs4-base.patch aufs4-mmap.patch aufs4-standalone.patch > ~/rpm/packages/kernel/kernel-aufs4.patch # mkdir linux # cp -a Documentation fs include linux -# diff -urN /usr/share/empty linux >> ~/rpm/packages/kernel/kernel-aufs3.patch +# diff -urN /usr/share/empty linux >> ~/rpm/packages/kernel/kernel-aufs4.patch # drop hunk at the end of patch (hunk is patching include/linux/Kbuild with single line change) -# cat aufs3-loopback.patch >> ~/rpm/packages/kernel/kernel-aufs3.patch +# cat aufs4-loopback.patch >> ~/rpm/packages/kernel/kernel-aufs4.patch # -Patch145: kernel-aufs3.patch -Patch146: kernel-aufs3+vserver.patch +Patch145: kernel-aufs4.patch +Patch146: kernel-aufs4+vserver.patch %define uksm_major_version 0.1.2.3 %define uksm_version %{uksm_major_version}-for-v3.18