armbian-build/patch/kernel/pine64-default/01-patch-3.10.83-00-aufs-fix.patch
2016-05-06 23:33:22 +03:00

199 lines
4.8 KiB
Diff

--- a/fs/aufs/branch.c
+++ b/fs/aufs/branch.c
@@ -571,22 +571,25 @@
{
unsigned long long n;
struct file **p, *f;
+ struct au_sphlhead *files;
+ struct au_finfo *finfo;
struct super_block *sb = arg;
n = 0;
p = a;
- lg_global_lock(&files_lglock);
- do_file_list_for_each_entry(sb, f) {
- if (au_fi(f)
- && file_count(f)
+ files = &au_sbi(sb)->si_files;
+ spin_lock(&files->spin);
+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
+ f = finfo->fi_file;
+ if (file_count(f)
&& !special_file(file_inode(f)->i_mode)) {
get_file(f);
*p++ = f;
n++;
AuDebugOn(n > max);
}
- } while_file_list_for_each_entry;
- lg_global_unlock(&files_lglock);
+ }
+ spin_unlock(&files->spin);
return n;
}
@@ -1240,7 +1243,13 @@
continue;
/* todo: already flushed? */
- /* cf. fs/super.c:mark_files_ro() */
+ /*
+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
+ * approach which resets f_mode and calls mnt_drop_write() and
+ * file_release_write() for each file, because the branch
+ * attribute in aufs world is totally different from the native
+ * fs rw/ro mode.
+ */
/* fi_read_lock(file); */
hfile = &au_fi(file)->fi_htop;
hf = hfile->hf_file;
--- a/fs/aufs/file.h
+++ b/fs/aufs/file.h
@@ -61,6 +61,9 @@
atomic_t fi_mmapped;
};
struct au_fidir *fi_hdir; /* for dir only */
+
+ struct hlist_node fi_hlist;
+ struct file *fi_file; /* very ugly */
} ____cacheline_aligned_in_smp;
/* ---------------------------------------------------------------------- */
--- a/fs/aufs/sbinfo.c
+++ b/fs/aufs/sbinfo.c
@@ -118,6 +118,8 @@
init_waitqueue_head(&sbinfo->si_plink_wq);
spin_lock_init(&sbinfo->si_plink_maint_lock);
+ au_sphl_init(&sbinfo->si_files);
+
/* leave other members for sysaufs and si_mnt. */
sbinfo->si_sb = sb;
sb->s_fs_info = sbinfo;
--- a/fs/aufs/super.h
+++ b/fs/aufs/super.h
@@ -108,7 +108,8 @@
} au_si_pid;
/*
- * dirty approach to protect sb->sb_inodes and ->s_files from remount.
+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
+ * remount.
*/
atomic_long_t si_ninodes, si_nfiles;
@@ -188,6 +189,9 @@
wait_queue_head_t si_plink_wq;
spinlock_t si_plink_maint_lock;
pid_t si_plink_maint_pid;
+
+ /* file list */
+ struct au_sphlhead si_files;
/*
* sysfs and lifetime management.
--- a/fs/aufs/sysrq.c
+++ b/fs/aufs/sysrq.c
@@ -30,6 +30,8 @@
char *plevel;
struct au_sbinfo *sbinfo;
struct file *file;
+ struct au_sphlhead *files;
+ struct au_finfo *finfo;
plevel = au_plevel;
au_plevel = KERN_WARNING;
@@ -86,15 +88,17 @@
}
#endif
pr("files\n");
- lg_global_lock(&files_lglock);
- do_file_list_for_each_entry(sb, file) {
+ files = &au_sbi(sb)->si_files;
+ spin_lock(&files->spin);
+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
umode_t mode;
+ file = finfo->fi_file;
mode = file_inode(file)->i_mode;
if (!special_file(mode))
au_dpri_file(file);
- } while_file_list_for_each_entry;
- lg_global_unlock(&files_lglock);
+ }
+ spin_unlock(&files->spin);
pr("done\n");
#undef pr
--- a/fs/aufs/vfsub.h
+++ b/fs/aufs/vfsub.h
@@ -32,7 +32,6 @@
/* copied from linux/fs/internal.h */
/* todo: BAD approach!! */
-extern struct lglock vfsmount_lock;
extern void __mnt_drop_write(struct vfsmount *);
extern spinlock_t inode_sb_list_lock;
-/* copied from linux/fs/file_table.c */
-extern struct lglock files_lglock;
-#ifdef CONFIG_SMP
-/*
- * These macros iterate all files on all CPUs for a given superblock.
- * files_lglock must be held globally.
- */
-#define do_file_list_for_each_entry(__sb, __file) \
-{ \
- int i; \
- for_each_possible_cpu(i) { \
- struct list_head *list; \
- list = per_cpu_ptr((__sb)->s_files, i); \
- list_for_each_entry((__file), list, f_u.fu_list)
-
-#define while_file_list_for_each_entry \
- } \
-}
-
-#else
-
-#define do_file_list_for_each_entry(__sb, __file) \
-{ \
- struct list_head *list; \
- list = &(sb)->s_files; \
- list_for_each_entry((__file), list, f_u.fu_list)
-
-#define while_file_list_for_each_entry \
-}
-#endif
-
-/* ---------------------------------------------------------------------- */
-
/* lock subclass for lower inode */
/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
/* reduce? gave up. */
--- a/fs/aufs/export.c
+++ b/fs/aufs/export.c
@@ -301,9 +301,9 @@
};
get_fs_root(current->fs, &root);
- br_read_lock(&vfsmount_lock);
+ rcu_read_lock();
err = iterate_mounts(au_compare_mnt, &args, root.mnt);
- br_read_unlock(&vfsmount_lock);
+ rcu_read_unlock();
path_put(&root);
AuDebugOn(!err);
AuDebugOn(!args.mnt);
--- a/fs/aufs/dcsub.c
+++ b/fs/aufs/dcsub.c
@@ -197,7 +197,7 @@
goto out;
/*
- * vfsmount_lock is unnecessary since this is a traverse in a single
+ * RCU for vfsmount is unnecessary since this is a traverse in a single
* mount
*/
while (!IS_ROOT(dentry)) {