diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2011-01-18 18:10:19 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2011-01-18 18:10:19 +0100 |
commit | 46b2bb3001ce838ba2483a08418587d8a027f3a9 (patch) | |
tree | b2b618839b5afcc859fcb90556e6f199d9a9a10c /target/linux | |
parent | 88d3e6d6c572143bd95a589a44e30bfefd616b88 (diff) | |
parent | 902ee7e7b23751ca7a8264d36a837aa4aae12032 (diff) |
Merge branch 'master' of git+ssh://openadk.org/git/openadk
Diffstat (limited to 'target/linux')
29 files changed, 199114 insertions, 74 deletions
diff --git a/target/linux/config/Config.in.block b/target/linux/config/Config.in.block index 59fad2d4a..1019477c1 100644 --- a/target/linux/config/Config.in.block +++ b/target/linux/config/Config.in.block @@ -120,6 +120,8 @@ config ADK_KERNEL_ATA_PIIX select ADK_KERNEL_ATA_BMDMA select ADK_KERNEL_BLK_DEV select ADK_KERNEL_BLK_DEV_SD + default y if ADK_TARGET_SYSTEM_QEMU_MIPS64 + default y if ADK_TARGET_SYSTEM_QEMU_MIPS64EL default y if ADK_TARGET_SYSTEM_QEMU_MIPS default y if ADK_TARGET_SYSTEM_QEMU_MIPSEL default y if ADK_TARGET_SYSTEM_QEMU_X86 @@ -153,6 +155,8 @@ config ADK_KPACKAGE_KMOD_SATA_AHCI config ADK_KPACKAGE_KMOD_BLK_DEV_LOOP prompt "kmod-blk-dev-loop................. Loop mount support" tristate + select ADK_KERNEL_BLOCK + select ADK_KERNEL_BLK_DEV default n help Saying Y here will allow you to use a regular file as a block diff --git a/target/linux/config/Config.in.fs b/target/linux/config/Config.in.fs index 852d46c6a..f6da0d980 100644 --- a/target/linux/config/Config.in.fs +++ b/target/linux/config/Config.in.fs @@ -40,6 +40,7 @@ config ADK_KPACKAGE_KMOD_EXPORTFS help config ADK_KERNEL_SQUASHFS + prompt ".................................. SquashFS filesystem" boolean select ADK_KERNEL_MISC_FILESYSTEMS default n @@ -150,7 +151,7 @@ config ADK_KPACKAGE_KMOD_NTFS_FS Kernel modules for NTFS support config ADK_KPACKAGE_KMOD_VFAT_FS - prompt "kmod-vfat-fs....................... VFAT filesystem support" + prompt "kmod-vfat-fs...................... VFAT filesystem support" tristate select ADK_KPACKAGE_KMOD_NLS if !ADK_KERNEL_NLS select ADK_KPACKAGE_KMOD_NLS_CODEPAGE_850 diff --git a/target/linux/config/Config.in.input b/target/linux/config/Config.in.input index 2241c0ed7..754cf7340 100644 --- a/target/linux/config/Config.in.input +++ b/target/linux/config/Config.in.input @@ -22,6 +22,13 @@ config ADK_KERNEL_KEYBOARD_ATKBD default y if ADK_TARGET_SYSTEM_SHUTTLE_SA76G2 default n +config ADK_KERNEL_INPUT_MOUSE + boolean + default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C + default y if ADK_TARGET_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_SHUTTLE_SA76G2 + default n + config ADK_KERNEL_INPUT_MOUSEDEV boolean default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C diff --git a/target/linux/config/Config.in.leds b/target/linux/config/Config.in.leds index 54cda3ceb..88acae81e 100644 --- a/target/linux/config/Config.in.leds +++ b/target/linux/config/Config.in.leds @@ -1,6 +1,10 @@ config ADK_KERNEL_NEW_LEDS boolean +config ADK_KERNEL_LEDS_CLASS + boolean + select ADK_KERNEL_NEW_LEDS + config ADK_KERNEL_LEDS_TRIGGERS boolean select ADK_KERNEL_NEW_LEDS @@ -8,17 +12,27 @@ config ADK_KERNEL_LEDS_TRIGGERS menu "LEDS driver support" depends on ADK_TARGET_WITH_LEDS -config ADK_KPACKAGE_KMOD_LEDS_CLASS - prompt "LED Class support" +config ADK_KPACKAGE_KMOD_LEDS_MIKROTIK_RB532 + prompt "LED suppport for RB532" tristate - select ADK_KERNEL_NEW_LEDS + select ADK_KERNEL_LEDS_CLASS + depends on ADK_TARGET_SYSTEM_MIKROTIK_RB532 + default y if ADK_TARGET_SYSTEM_MIKROTIK_RB532 + default n + +config ADK_KPACKAGE_KMOD_LEDS_WRAP + prompt "LED suppport for WRAP" + tristate + select ADK_KERNEL_LEDS_CLASS + depends on ADK_TARGET_SYSTEM_PCENGINES_WRAP + default y if ADK_TARGET_SYSTEM_PCENGINES_WRAP default n - help config ADK_KPACKAGE_KMOD_LEDS_ALIX2 prompt "LED suppport for ALIX2/ALIX3" tristate - select ADK_KPACKAGE_KMOD_LEDS_CLASS + select ADK_KERNEL_LEDS_CLASS + depends on ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 || ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default n @@ -27,24 +41,28 @@ config ADK_KPACKAGE_KMOD_LEDS_TRIGGER_TIMER prompt "LED Timer trigger" tristate select ADK_KERNEL_LEDS_TRIGGERS + select ADK_KERNEL_LEDS_CLASS default n config ADK_KPACKAGE_KMOD_LEDS_TRIGGER_HEARTBEAT prompt "LED Heartbeat trigger" tristate select ADK_KERNEL_LEDS_TRIGGERS + select ADK_KERNEL_LEDS_CLASS default n config ADK_KPACKAGE_KMOD_LEDS_TRIGGER_DEFAULT_ON prompt "LED Default On trigger" tristate select ADK_KERNEL_LEDS_TRIGGERS + select ADK_KERNEL_LEDS_CLASS default n config ADK_KPACKAGE_KMOD_NETFILTER_XT_TARGET_LED prompt "LED IPTables trigger" tristate select ADK_KERNEL_LEDS_TRIGGERS + select ADK_KERNEL_LEDS_CLASS select ADK_PACKAGE_IPTABLES default n diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index 40573a78f..ef12cbe0c 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -240,10 +240,10 @@ config ADK_KERNEL_RT2X00 select ADK_KPACKAGE_KMOD_FW_LOADER select ADK_KPACKAGE_KMOD_EEPROM_93CX6 -config ADK_MOD_KERNEL_CFG80211 +config ADK_KERNEL_MOD_CFG80211 tristate -config ADK_MOD_KERNEL_LIB80211 +config ADK_KERNEL_MOD_LIB80211 tristate config ADK_KERNEL_CFG80211_WEXT @@ -269,8 +269,8 @@ config ADK_KPACKAGE_KMOD_MAC80211 tristate select ADK_KERNEL_WIRELESS select ADK_KERNEL_WLAN_80211 - select ADK_MOD_KERNEL_CFG80211 - select ADK_MOD_KERNEL_LIB80211 + select ADK_KERNEL_MOD_CFG80211 + select ADK_KERNEL_MOD_LIB80211 select ADK_KPACKAGE_KMOD_CRYPTO_AES select ADK_KPACKAGE_KMOD_CRYPTO_ECB select ADK_KPACKAGE_KMOD_CRYPTO_ARC4 @@ -319,6 +319,7 @@ config ADK_KPACKAGE_KMOD_B43 tristate select ADK_KPACKAGE_KMOD_FW_LOADER depends on ADK_TARGET_WITH_SSB || ADK_TARGET_WITH_MINIPCI + default y if ADK_TARGET_SYSTEM_LINKSYS_WRT54G default n help Driver for Broadcom B43xx wireless chips. diff --git a/target/linux/config/Config.in.network b/target/linux/config/Config.in.network index b7555bd12..1bbf681dc 100644 --- a/target/linux/config/Config.in.network +++ b/target/linux/config/Config.in.network @@ -24,6 +24,10 @@ config ADK_KERNEL_NET_IPGRE_BROADCAST boolean default n +config ADK_KERNEL_NET_IPGRE_DEMUX + boolean + default n + config ADK_KERNEL_PPP_ASYNC boolean default n @@ -134,11 +138,11 @@ config ADK_KPACKAGE_KMOD_NET_IPIP mobile-IP facilities (allowing laptops to seamlessly move between networks without changing their IP addresses). - config ADK_KPACKAGE_KMOD_NET_IPGRE prompt "kmod-net-ipgre.................... GRE tunnels over IP" tristate - #depends on ADK_KPACKAGE_KMOD_NET_IPGRE_BROADCAST + select ADK_KERNEL_NET_IPGRE_BROADCAST + select ADK_KERNEL_NET_IPGRE_DEMUX default n help Tunneling means encapsulating data of one protocol type within diff --git a/target/linux/patches/2.6.36/aufs2.patch b/target/linux/patches/2.6.36/aufs2.patch new file mode 100644 index 000000000..e9e5fc277 --- /dev/null +++ b/target/linux/patches/2.6.36/aufs2.patch @@ -0,0 +1,33532 @@ +diff -Nur linux-2.6.36.orig/fs/Kconfig linux-2.6.36/fs/Kconfig +--- linux-2.6.36.orig/fs/Kconfig 2010-10-20 22:30:22.000000000 +0200 ++++ linux-2.6.36/fs/Kconfig 2011-01-10 19:52:38.000000000 +0100 +@@ -189,6 +189,7 @@ + source "fs/sysv/Kconfig" + source "fs/ufs/Kconfig" + source "fs/exofs/Kconfig" ++source "fs/aufs/Kconfig" + + endif # MISC_FILESYSTEMS + +diff -Nur linux-2.6.36.orig/fs/Makefile linux-2.6.36/fs/Makefile +--- linux-2.6.36.orig/fs/Makefile 2010-10-20 22:30:22.000000000 +0200 ++++ linux-2.6.36/fs/Makefile 2011-01-10 19:52:38.000000000 +0100 +@@ -126,3 +126,4 @@ + obj-$(CONFIG_GFS2_FS) += gfs2/ + obj-$(CONFIG_EXOFS_FS) += exofs/ + obj-$(CONFIG_CEPH_FS) += ceph/ ++obj-$(CONFIG_AUFS_FS) += aufs/ +diff -Nur linux-2.6.36.orig/fs/aufs/Kconfig linux-2.6.36/fs/aufs/Kconfig +--- linux-2.6.36.orig/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.36/fs/aufs/Kconfig 2011-01-10 19:24:41.000000000 +0100 +@@ -0,0 +1,180 @@ ++config AUFS_FS ++ tristate "Aufs (Advanced multi layered unification filesystem) support" ++ depends on EXPERIMENTAL ++ help ++ Aufs is a stackable unification filesystem such as Unionfs, ++ which unifies several directories and provides a merged single ++ directory. ++ In the early days, aufs was entirely re-designed and ++ re-implemented Unionfs Version 1.x series. Introducing many ++ original ideas, approaches and improvements, it becomes totally ++ different from Unionfs while keeping the basic features. ++ ++if AUFS_FS ++choice ++ prompt "Maximum number of branches" ++ default AUFS_BRANCH_MAX_127 ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_127 ++ bool "127" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_511 ++ bool "511" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_1023 ++ bool "1023" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_32767 ++ bool "32767" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++endchoice ++ ++config AUFS_SBILIST ++ bool ++ depends on AUFS_MAGIC_SYSRQ || PROC_FS ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq or /proc, enabled automatically. ++ ++config AUFS_HNOTIFY ++ bool "Detect direct branch access (bypassing aufs)" ++ help ++ If you want to modify files on branches directly, eg. bypassing aufs, ++ and want aufs to detect the changes of them fully, then enable this ++ option and use 'udba=notify' mount option. ++ Currently there is only one available configuration, "fsnotify". ++ It will have a negative impact to the performance. ++ See detail in aufs.5. ++ ++choice ++ prompt "method" if AUFS_HNOTIFY ++ default AUFS_HFSNOTIFY ++config AUFS_HFSNOTIFY ++ bool "fsnotify" ++ select FSNOTIFY ++endchoice ++ ++config AUFS_EXPORT ++ bool "NFS-exportable aufs" ++ depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS) ++ help ++ If you want to export your mounted aufs via NFS, then enable this ++ option. There are several requirements for this configuration. ++ See detail in aufs.5. ++ ++config AUFS_INO_T_64 ++ bool ++ depends on AUFS_EXPORT ++ depends on 64BIT && !(ALPHA || S390) ++ default y ++ help ++ Automatic configuration for internal use. ++ /* typedef unsigned long/int __kernel_ino_t */ ++ /* alpha and s390x are int */ ++ ++config AUFS_RDU ++ bool "Readdir in userspace" ++ help ++ Aufs has two methods to provide a merged view for a directory, ++ by a user-space library and by kernel-space natively. The latter ++ is always enabled but sometimes large and slow. ++ If you enable this option, install the library in aufs2-util ++ package, and set some environment variables for your readdir(3), ++ then the work will be handled in user-space which generally ++ shows better performance in most cases. ++ See detail in aufs.5. ++ ++config AUFS_SP_IATTR ++ bool "Respect the attributes (mtime/ctime mainly) of special files" ++ help ++ When you write something to a special file, some attributes of it ++ (mtime/ctime mainly) may be updated. Generally such updates are ++ less important (actually some device drivers and NFS ignore ++ it). But some applications (such like test program) requires ++ such updates. If you need these updates, then enable this ++ configuration which introduces some overhead. ++ Currently this configuration handles FIFO only. ++ ++config AUFS_SHWH ++ bool "Show whiteouts" ++ help ++ If you want to make the whiteouts in aufs visible, then enable ++ this option and specify 'shwh' mount option. Although it may ++ sounds like philosophy or something, but in technically it ++ simply shows the name of whiteout with keeping its behaviour. ++ ++config AUFS_BR_RAMFS ++ bool "Ramfs (initramfs/rootfs) as an aufs branch" ++ help ++ If you want to use ramfs as an aufs branch fs, then enable this ++ option. Generally tmpfs is recommended. ++ Aufs prohibited them to be a branch fs by default, because ++ initramfs becomes unusable after switch_root or something ++ generally. If you sets initramfs as an aufs branch and boot your ++ system by switch_root, you will meet a problem easily since the ++ files in initramfs may be inaccessible. ++ Unless you are going to use ramfs as an aufs branch fs without ++ switch_root or something, leave it N. ++ ++config AUFS_BR_FUSE ++ bool "Fuse fs as an aufs branch" ++ depends on FUSE_FS ++ select AUFS_POLL ++ help ++ If you want to use fuse-based userspace filesystem as an aufs ++ branch fs, then enable this option. ++ It implements the internal poll(2) operation which is ++ implemented by fuse only (curretnly). ++ ++config AUFS_POLL ++ bool ++ help ++ Automatic configuration for internal use. ++ ++config AUFS_BR_HFSPLUS ++ bool "Hfsplus as an aufs branch" ++ depends on HFSPLUS_FS ++ default y ++ help ++ If you want to use hfsplus fs as an aufs branch fs, then enable ++ this option. This option introduces a small overhead at ++ copying-up a file on hfsplus. ++ ++config AUFS_BDEV_LOOP ++ bool ++ depends on BLK_DEV_LOOP ++ default y ++ help ++ Automatic configuration for internal use. ++ Convert =[ym] into =y. ++ ++config AUFS_DEBUG ++ bool "Debug aufs" ++ help ++ Enable this to compile aufs internal debug code. ++ It will have a negative impact to the performance. ++ ++config AUFS_MAGIC_SYSRQ ++ bool ++ depends on AUFS_DEBUG && MAGIC_SYSRQ ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq, enabled automatically. ++endif +diff -Nur linux-2.6.36.orig/fs/aufs/Makefile linux-2.6.36/fs/aufs/Makefile +--- linux-2.6.36.orig/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.36/fs/aufs/Makefile 2011-01-10 19:24:41.000000000 +0100 +@@ -0,0 +1,38 @@ ++ ++include ${src}/magic.mk ++ifeq (${CONFIG_AUFS_FS},m) ++include ${src}/conf.mk ++endif ++-include ${src}/priv_def.mk ++ ++# cf. include/linux/kernel.h ++# enable pr_debug ++ccflags-y += -DDEBUG ++# sparse doesn't allow spaces ++ccflags-y += -D'pr_fmt(fmt)=AUFS_NAME"\040%s:%d:%s[%d]:\040"fmt,__func__,__LINE__,current->comm,current->pid' ++ ++obj-$(CONFIG_AUFS_FS) += aufs.o ++aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ ++ wkq.o vfsub.o dcsub.o \ ++ cpup.o whout.o wbr_policy.o \ ++ dinfo.o dentry.o \ ++ dynop.o \ ++ finfo.o file.o f_op.o \ ++ dir.o vdir.o \ ++ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ ++ ioctl.o ++ ++# all are boolean ++aufs-$(CONFIG_PROC_FS) += procfs.o plink.o ++aufs-$(CONFIG_SYSFS) += sysfs.o ++aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o ++aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o ++aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o ++aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o ++aufs-$(CONFIG_AUFS_EXPORT) += export.o ++aufs-$(CONFIG_AUFS_POLL) += poll.o ++aufs-$(CONFIG_AUFS_RDU) += rdu.o ++aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o ++aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o ++aufs-$(CONFIG_AUFS_DEBUG) += debug.o ++aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o +diff -Nur linux-2.6.36.orig/fs/aufs/aufs.h linux-2.6.36/fs/aufs/aufs.h +--- linux-2.6.36.orig/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.36/fs/aufs/aufs.h 2011-01-10 19:24:41.000000000 +0100 +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) 2005-2011 Junjiro R. Okajima ++ * ++ * This program, aufs 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, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * all header files ++ */ ++ ++#ifndef __AUFS_H__ ++#define __AUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#define AuStub(type, name, body, ...) \ ++ static inline type name(__VA_ARGS__) { body; } ++ ++#define AuStubVoid(name, ...) \ ++ AuStub(void, name, , __VA_ARGS__) ++#define AuStubInt0(name, ...) \ ++ AuStub(int, name, return 0, __VA_ARGS__) ++ ++#include "debug.h" ++ ++#include "branch.h" ++#include "cpup.h" ++#include "dcsub.h" ++#include "dbgaufs.h" ++#include "dentry.h" ++#include "dir.h" ++#include "dynop.h" ++#include "file.h" ++#include "fstype.h" ++#include "inode.h" ++#include "loop.h" ++#include "module.h" ++/* never include ./mtx.h */ ++#include "opts.h" ++#include "rwsem.h" ++#include "spl.h" ++#include "super.h" ++#include "sysaufs.h" ++#include "vfsub.h" ++#include "whout.h" ++#include "wkq.h" ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_H__ */ +diff -Nur linux-2.6.36.orig/fs/aufs/branch.c linux-2.6.36/fs/aufs/branch.c +--- linux-2.6.36.orig/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.36/fs/aufs/branch.c 2011-01-10 19:24:41.000000000 +0100 +@@ -0,0 +1,1071 @@ ++/* ++ * Copyright (C) 2005-2011 Junjiro R. Okajima ++ * ++ * This program, aufs 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, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * branch management ++ */ ++ ++#include <linux/file.h> ++#include <linux/statfs.h> ++#include "aufs.h" ++ ++/* ++ * free a single branch ++ */ ++static void au_br_do_free(struct au_branch *br) ++{ ++ int i; ++ struct au_wbr *wbr; ++ struct au_dykey **key; ++ ++ au_hnotify_fin_br(br); ++ ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ mutex_destroy(&br->br_xino.xi_nondir_mtx); ++ ++ AuDebugOn(atomic_read(&br->br_count)); ++ ++ wbr = br->br_wbr; ++ if (wbr) { ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(wbr->wbr_wh[i]); ++ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); ++ AuRwDestroy(&wbr->wbr_wh_rwsem); ++ } ++ ++ key = br->br_dykey; ++ for (i = 0; i < AuBrDynOp; i++, key++) ++ if (*key) ++ au_dy_put(*key); ++ else ++ break; ++ ++ mntput(br->br_mnt); ++ kfree(wbr); ++ kfree(br); ++} ++ ++/* ++ * frees all branches ++ */ ++void au_br_free(struct au_sbinfo *sbinfo) ++{ ++ aufs_bindex_t bmax; ++ struct au_branch **br; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ bmax = sbinfo->si_bend + 1; ++ br = sbinfo->si_branch; ++ while (bmax--) ++ au_br_do_free(*br++); ++} ++ ++/* ++ * find the index of a branch which is specified by @br_id. ++ */ ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (au_sbr_id(sb, bindex) == br_id) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * add a branch ++ */ ++ ++static int test_overlap(struct super_block *sb, struct dentry *h_adding, ++ struct dentry *h_root) ++{ ++ if (unlikely(h_adding == h_root ++ || au_test_loopback_overlap(sb, h_adding))) ++ return 1; ++ if (h_adding->d_sb != h_root->d_sb) ++ return 0; ++ return au_test_subdir(h_adding, h_root) ++ || au_test_subdir(h_root, h_adding); ++} ++ ++/* ++ * returns a newly allocated branch. @new_nbranch is a number of branches ++ * after adding a branch. ++ */ ++static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, ++ int perm) ++{ ++ struct au_branch *add_branch; ++ struct dentry *root; ++ int err; ++ ++ err = -ENOMEM; ++ root = sb->s_root; ++ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS); ++ if (unlikely(!add_branch)) ++ goto out; ++ ++ err = au_hnotify_init_br(add_branch, perm); ++ if (unlikely(err)) ++ goto out_br; ++ ++ add_branch->br_wbr = NULL; ++ if (au_br_writable(perm)) { ++ /* may be freed separately at changing the branch permission */ ++ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr), ++ GFP_NOFS); ++ if (unlikely(!add_branch->br_wbr)) ++ goto out_hnotify; ++ } ++ ++ 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) ++ return add_branch; /* success */ ++ ++ kfree(add_branch->br_wbr); ++ ++out_hnotify: ++ au_hnotify_fin_br(add_branch); ++out_br: ++ kfree(add_branch); ++out: ++ return ERR_PTR(err); ++} ++ ++/* ++ * test if the branch permission is legal or not. ++ */ ++static int test_br(struct inode *inode, int brperm, char *path) ++{ ++ int err; ++ ++ err = (au_br_writable(brperm) && IS_RDONLY(inode)); ++ if (!err) ++ goto out; ++ ++ err = -EINVAL; ++ pr_err("write permission for readonly mount or inode, %s\n", path); ++ ++out: ++ return err; ++} ++ ++/* ++ * returns: ++ * 0: success, the caller will add it ++ * plus: success, it is already unified, the caller should ignore it ++ * minus: error ++ */ ++static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root; ++ struct inode *inode, *h_inode; ++ ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ if (unlikely(bend >= 0 ++ && au_find_dbindex(root, add->path.dentry) >= 0)) { ++ err = 1; ++ if (!remount) { ++ err = -EINVAL; ++ pr_err("%s duplicated\n", add->pathname); ++ } ++ goto out; ++ } ++ ++ err = -ENOSPC; /* -E2BIG; */ ++ if (unlikely(AUFS_BRANCH_MAX <= add->bindex ++ || AUFS_BRANCH_MAX - 1 <= bend)) { ++ pr_err("number of branches exceeded %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EDOM; ++ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) { ++ pr_err("bad index %d\n", add->bindex); ++ goto out; ++ } ++ ++ inode = add->path.dentry->d_inode; ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) { ++ pr_err("no existence %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ if (unlikely(inode->i_sb == sb)) { ++ pr_err("%s must be outside\n", add->pathname); ++ goto out; ++ } ++ ++ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { ++ pr_err("unsupported filesystem, %s (%s)\n", ++ add->pathname, au_sbtype(inode->i_sb)); ++ goto out; ++ } ++ ++ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname); ++ if (unlikely(err)) ++ goto out; ++ ++ if (bend < 0) ++ return 0; /* success */ ++ ++ err = -EINVAL; ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (unlikely(test_overlap(sb, add->path.dentry, ++ au_h_dptr(root, bindex)))) { ++ pr_err("%s is overlapped\n", add->pathname); ++ goto out; ++ } ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { ++ h_inode = au_h_dptr(root, 0)->d_inode; ++ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) ++ || h_inode->i_uid != inode->i_uid ++ || h_inode->i_gid != inode->i_gid) ++ pr_warning("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", ++ add->pathname, ++ inode->i_uid, inode->i_gid, ++ (inode->i_mode & S_IALLUGO), ++ h_inode->i_uid, h_inode->i_gid, ++ (h_inode->i_mode & S_IALLUGO)); ++ } ++ ++out: ++ return err; ++} ++ ++/* ++ * initialize or clean the whiteouts for an adding branch ++ */ ++static int au_br_init_wh(struct super_block *sb, struct au_branch *br, ++ int new_perm, struct dentry *h_root) ++{ ++ int err, old_perm; ++ aufs_bindex_t bindex; ++ struct mutex *h_mtx; ++ struct au_wbr *wbr; ++ struct au_hinode *hdir; ++ ++ wbr = br->br_wbr; ++ old_perm = br->br_perm; ++ br->br_perm = new_perm; ++ hdir = NULL; ++ h_mtx = NULL; ++ bindex = au_br_index(sb, br->br_id); ++ if (0 <= bindex) { ++ hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ } else { ++ h_mtx = &h_root->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_PARENT); ++ } ++ if (!wbr) ++ err = au_wh_init(h_root, br, sb); ++ else { ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(h_root, br, sb); ++ wbr_wh_write_unlock(wbr); ++ } ++ if (hdir) ++ au_hn_imtx_unlock(hdir); ++ else ++ mutex_unlock(h_mtx); ++ br->br_perm = old_perm; ++ ++ if (!err && wbr && !au_br_writable(new_perm)) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_init(struct au_branch *br, struct super_block *sb, ++ int perm, struct path *path) ++{ ++ int err; ++ struct kstatfs kst; ++ struct au_wbr *wbr; ++ struct dentry *h_dentry; ++ ++ wbr = br->br_wbr; ++ au_rw_init(&wbr->wbr_wh_rwsem); ++ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh)); ++ atomic_set(&wbr->wbr_wh_running, 0); ++ wbr->wbr_bytes = 0; ++ ++ /* ++ * a limit for rmdir/rename a dir ++ * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h ++ */ |