Instead of borrowing proc's inode pool and starting at a custom offset, give nsfs its own dedicated inode pool without an offset. Signed-off-by: Richard Guy Briggs <rgb@xxxxxxxxxx> --- fs/nsfs.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ fs/proc/internal.h | 2 ++ include/linux/proc_ns.h | 20 ++++++++------------ init/version.c | 2 +- ipc/msgutil.c | 2 +- kernel/pid.c | 2 +- kernel/user.c | 2 +- 7 files changed, 58 insertions(+), 16 deletions(-) diff --git a/fs/nsfs.c b/fs/nsfs.c index af1b24f..1fcd529 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -159,3 +159,47 @@ void __init nsfs_init(void) panic("can't set nsfs up\n"); nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER; } + +static DEFINE_IDA(ns_inum_ida); +static DEFINE_SPINLOCK(ns_inum_lock); /* protects the above */ + +/* + * Return an inode number between PROC_DYNAMIC_FIRST and + * 0xffffffff, or zero on failure. + */ +int ns_alloc_inum(struct ns_common *ns) +{ + unsigned int i; + int error; + + atomic_long_set(&ns->stashed, 0); +retry: + if (!ida_pre_get(&ns_inum_ida, GFP_KERNEL)) + return -ENOMEM; + + spin_lock_irq(&ns_inum_lock); + error = ida_get_new(&ns_inum_ida, &i); + spin_unlock_irq(&ns_inum_lock); + if (error == -EAGAIN) + goto retry; + else if (error) + return error; + + if (i > UINT_MAX) { + spin_lock_irq(&ns_inum_lock); + ida_remove(&ns_inum_ida, i); + spin_unlock_irq(&ns_inum_lock); + return -ENOSPC; + } + ns->inum = NS_DYNAMIC_FIRST + i; + return 0; +} + +void ns_free_inum(struct ns_common *ns) +{ + unsigned long flags; + spin_lock_irqsave(&ns_inum_lock, flags); + ida_remove(&ns_inum_ida, ns->inum - NS_DYNAMIC_FIRST); + spin_unlock_irqrestore(&ns_inum_lock, flags); +} + diff --git a/fs/proc/internal.h b/fs/proc/internal.h index c835b94..8f89cbb 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -18,6 +18,8 @@ struct ctl_table_header; struct mempolicy; +#define PROC_ROOT_INO 1 + /* * This is not completely implemented yet. The idea is to * create an in-memory tree (like the actual /proc filesystem diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h index 2654550..721d0e2 100644 --- a/include/linux/proc_ns.h +++ b/include/linux/proc_ns.h @@ -30,11 +30,12 @@ extern const struct proc_ns_operations *ns_entries[]; * We always define these enumerators */ enum { - PROC_ROOT_INO = 1, - PROC_IPC_INIT_INO = 0xEFFFFFFFU, - PROC_UTS_INIT_INO = 0xEFFFFFFEU, - PROC_USER_INIT_INO = 0xEFFFFFFDU, - PROC_PID_INIT_INO = 0xEFFFFFFCU, + NS_NULL_INIT_INO, + NS_IPC_INIT_INO, + NS_UTS_INIT_INO, + NS_USER_INIT_INO, + NS_PID_INIT_INO, + NS_DYNAMIC_FIRST, }; #ifdef CONFIG_PROC_FS @@ -58,13 +59,8 @@ static inline void proc_free_inum(unsigned int inum) {} #endif /* CONFIG_PROC_FS */ -static inline int ns_alloc_inum(struct ns_common *ns) -{ - atomic_long_set(&ns->stashed, 0); - return proc_alloc_inum(&ns->inum); -} - -#define ns_free_inum(ns) proc_free_inum((ns)->inum) +extern int ns_alloc_inum(struct ns_common *ns); +extern void ns_free_inum(struct ns_common *ns); extern struct file *proc_ns_fget(int fd); #define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private) diff --git a/init/version.c b/init/version.c index fe41a63..050dda0 100644 --- a/init/version.c +++ b/init/version.c @@ -35,7 +35,7 @@ struct uts_namespace init_uts_ns = { .domainname = UTS_DOMAINNAME, }, .user_ns = &init_user_ns, - .ns.inum = PROC_UTS_INIT_INO, + .ns.inum = NS_UTS_INIT_INO, #ifdef CONFIG_UTS_NS .ns.ops = &utsns_operations, #endif diff --git a/ipc/msgutil.c b/ipc/msgutil.c index 2b49159..aca24bb 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -31,7 +31,7 @@ DEFINE_SPINLOCK(mq_lock); struct ipc_namespace init_ipc_ns = { .count = ATOMIC_INIT(1), .user_ns = &init_user_ns, - .ns.inum = PROC_IPC_INIT_INO, + .ns.inum = NS_IPC_INIT_INO, #ifdef CONFIG_IPC_NS .ns.ops = &ipcns_operations, #endif diff --git a/kernel/pid.c b/kernel/pid.c index cd36a5e..a06abc2 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -79,7 +79,7 @@ struct pid_namespace init_pid_ns = { .level = 0, .child_reaper = &init_task, .user_ns = &init_user_ns, - .ns.inum = PROC_PID_INIT_INO, + .ns.inum = NS_PID_INIT_INO, #ifdef CONFIG_PID_NS .ns.ops = &pidns_operations, #endif diff --git a/kernel/user.c b/kernel/user.c index b069ccb..deaf107 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -50,7 +50,7 @@ struct user_namespace init_user_ns = { .count = ATOMIC_INIT(3), .owner = GLOBAL_ROOT_UID, .group = GLOBAL_ROOT_GID, - .ns.inum = PROC_USER_INIT_INO, + .ns.inum = NS_USER_INIT_INO, #ifdef CONFIG_USER_NS .ns.ops = &userns_operations, #endif -- 1.7.1 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/containers