Linux/fs/namespace.c

  1 /*
  2  *  linux/fs/namespace.c
  3  *
  4  * (C) Copyright Al Viro 2000, 2001
  5  *      Released under GPL v2.
  6  *
  7  * Based on code from fs/super.c, copyright Linus Torvalds and others.
  8  * Heavily rewritten.
  9  */
 10 
 11 #include <linux/syscalls.h>
 12 #include <linux/slab.h>
 13 #include <linux/sched.h>
 14 #include <linux/spinlock.h>
 15 #include <linux/percpu.h>
 16 #include <linux/init.h>
 17 #include <linux/kernel.h>
 18 #include <linux/acct.h>
 19 #include <linux/capability.h>
 20 #include <linux/cpumask.h>
 21 #include <linux/module.h>
 22 #include <linux/sysfs.h>
 23 #include <linux/seq_file.h>
 24 #include <linux/mnt_namespace.h>
 25 #include <linux/namei.h>
 26 #include <linux/nsproxy.h>
 27 #include <linux/security.h>
 28 #include <linux/mount.h>
 29 #include <linux/ramfs.h>
 30 #include <linux/log2.h>
 31 #include <linux/idr.h>
 32 #include <linux/fs_struct.h>
 33 #include <linux/fsnotify.h>
 34 #include <asm/uaccess.h>
 35 #include <asm/unistd.h>
 36 #include "pnode.h"
 37 #include "internal.h"
 38 
 39 #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head))
 40 #define HASH_SIZE (1UL << HASH_SHIFT)
 41 
 42 static int event;
 43 static DEFINE_IDA(mnt_id_ida);
 44 static DEFINE_IDA(mnt_group_ida);
 45 static DEFINE_SPINLOCK(mnt_id_lock);
 46 static int mnt_id_start = 0;
 47 static int mnt_group_start = 1;
 48 
 49 static struct list_head *mount_hashtable __read_mostly;
 50 static struct kmem_cache *mnt_cache __read_mostly;
 51 static struct rw_semaphore namespace_sem;
 52 
 53 /* /sys/fs */
 54 struct kobject *fs_kobj;
 55 EXPORT_SYMBOL_GPL(fs_kobj);
 56 
 57 /*
 58  * vfsmount lock may be taken for read to prevent changes to the
 59  * vfsmount hash, ie. during mountpoint lookups or walking back
 60  * up the tree.
 61  *
 62  * It should be taken for write in all cases where the vfsmount
 63  * tree or hash is modified or when a vfsmount structure is modified.
 64  */
 65 DEFINE_BRLOCK(vfsmount_lock);
 66 
 67 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
 68 {
 69         unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
 70         tmp += ((unsigned long)dentry / L1_CACHE_BYTES);
 71         tmp = tmp + (tmp >> HASH_SHIFT);
 72         return tmp & (HASH_SIZE - 1);
 73 }
 74 
 75 #define MNT_WRITER_UNDERFLOW_LIMIT -(1<<16)
 76 
 77 /*
 78  * allocation is serialized by namespace_sem, but we need the spinlock to
 79  * serialize with freeing.
 80  */
 81 static int mnt_alloc_id(struct vfsmount *mnt)
 82 {
 83         int res;
 84 
 85 retry:
 86         ida_pre_get(&mnt_id_ida, GFP_KERNEL);
 87         spin_lock(&mnt_id_lock);
 88         res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
 89         if (!res)
 90                 mnt_id_start = mnt->mnt_id + 1;
 91         spin_unlock(&mnt_id_lock);
 92         if (res == -EAGAIN)
 93                 goto retry;
 94 
 95         return res;
 96 }
 97 
 98 static void mnt_free_id(struct vfsmount *mnt)
 99 {
100         int id = mnt->mnt_id;
101         spin_lock(&mnt_id_lock);
102         ida_remove(&mnt_id_ida, id);
103         if (mnt_id_start > id)
104                 mnt_id_start = id;
105         spin_unlock(&mnt_id_lock);
106 }
107 
108 /*
109  * Allocate a new peer group ID
110  *
111  * mnt_group_ida is protected by namespace_sem
112  */
113 static int mnt_alloc_group_id(struct vfsmount *mnt)
114 {
115         int res;
116 
117         if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL))
118                 return -ENOMEM;
119 
120         res = ida_get_new_above(&mnt_group_ida,