1 #include <linux/module.h> 2 #include <linux/sched.h> 3 #include <linux/fs.h> 4 #include <linux/path.h> 5 #include <linux/slab.h> 6 #include <linux/fs_struct.h> 7 #include "internal.h" 8 9 static inline void path_get_longterm(struct path *path) 10 { 11 path_get(path); 12 mnt_make_longterm(path->mnt); 13 } 14 15 static inline void path_put_longterm(struct path *path) 16 { 17 mnt_make_shortterm(path->mnt); 18 path_put(path); 19 } 20 21 /* 22 * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. 23 * It can block. 24 */ 25 void set_fs_root(struct fs_struct *fs, struct path *path) 26 { 27 struct path old_root; 28 29 spin_lock(&fs->lock); 30 write_seqcount_begin(&fs->seq); 31 old_root = fs->root; 32 fs->root = *path; 33 path_get_longterm(path); 34 write_seqcount_end(&fs->seq); 35 spin_unlock(&fs->lock); 36 if (old_root.dentry) 37 path_put_longterm(&old_root); 38 } 39 40 /* 41 * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. 42 * It can block. 43 */ 44 void set_fs_pwd(struct fs_struct *fs, struct path *path) 45 { 46 struct path old_pwd; 47 48 spin_lock(&fs->lock); 49 write_seqcount_begin(&fs->seq); 50 old_pwd = fs->pwd; 51 fs->pwd = *path; 52 path_get_longterm(path); 53 write_seqcount_end(&fs->seq); 54 spin_unlock(&fs->lock); 55 56 if (old_pwd.dentry) 57 path_put_longterm(&old_pwd); 58 } 59 60 void chroot_fs_refs(struct path *old_root, struct path *new_root) 61 { 62 struct task_struct *g, *p; 63 struct fs_struct *fs; 64 int count = 0; 65 66 read_lock(&tasklist_lock); 67 do_each_thread(g, p) { 68 task_lock(p); 69 fs = p->fs; 70 if (fs) { 71 spin_lock(&fs->lock); 72 write_seqcount_begin(&fs->seq); 73 if (fs->root.dentry == old_root->dentry 74 && fs->root.mnt == old_root->mnt) { 75 path_get_longterm(new_root); 76 fs->root = *new_root; 77 count++; 78 } 79 if (fs->pwd.dentry == old_root->dentry 80 && fs->pwd.mnt == old_root->mnt) { 81 path_get_longterm(new_root); 82 fs->pwd = *new_root; 83 count++; 84 } 85 write_seqcount_end(&fs->seq); 86 spin_unlock(&fs->lock); 87 } 88 task_unlock(p); 89 } while_each_thread(g, p); 90 read_unlock(&tasklist_lock); 91 while (count--) 92 path_put_longterm(old_root); 93 } 94 95 void free_fs_struct(struct fs_struct *fs) 96 { 97 path_put_longterm(&fs->root); 98 path_put_longterm(&fs->pwd); 99 kmem_cache_free(fs_cachep, fs); 100 } 101 102 void exit_fs(struct task_struct *tsk) 103 { 104 struct fs_struct *fs = tsk->fs; 105 106 if (fs) { 107 int kill; 108 task_lock(tsk); 109 spin_lock(&fs->lock); 110 write_seqcount_begin(&fs->seq); 111 tsk->fs = NULL; 112 kill = !--fs->users; 113 write_seqcount_end(&fs->seq); 114 spin_unlock(&fs->lock); 115 task_unlock(tsk); 116 if (kill) 117 free_fs_struct(fs); 118 } 119 } 120 121 struct fs_struct *copy_fs_struct(struct fs_struct *old) 122 { 123 struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); 124 /* We don't need to lock fs - think why ;-) */ 125 if (fs) { 126 fs->users = 1; 127 fs->in_exec = 0; 128 spin_lock_init(&fs->lock); 129 seqcount_init(&fs->seq); 130 fs->umask = old->umask; 131 132 spin_lock(&old->lock); 133 fs->root = old->root; 134 path_get_longterm(&fs->root); 135 fs->pwd = old->pwd; 136 path_get_longterm(&fs->pwd); 137 spin_unlock(&old->lock); 138 } 139 return fs; 140 } 141 142 int unshare_fs_struct(void) 143 { 144 struct fs_struct *fs = current->fs; 145 struct fs_struct *new_fs = copy_fs_struct(fs); 146 int kill; 147 148 if (!new_fs) 149 return -ENOMEM; 150 151 task_lock(current); 152 spin_lock(&fs->lock); 153 kill = !--fs->users; 154 current->fs = new_fs; 155 spin_unlock(&fs->lock); 156 task_unlock(current); 157 158 if (kill) 159 free_fs_struct(fs); 160 161 return 0; 162 } 163 EXPORT_SYMBOL_GPL(unshare_fs_struct); 164 165 int current_umask(void) 166 { 167 return current->fs->umask; 168 } 169 EXPORT_SYMBOL(current_umask); 170 171 /* to be mentioned only in INIT_TASK */ 172 struct fs_struct init_fs = { 173 .users = 1, 174 .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), 175 .seq = SEQCNT_ZERO, 176 .umask = 0022, 177 }; 178 179 void daemonize_fs_struct(void) 180 { 181 struct fs_struct *fs = current->fs; 182 183 if (fs) { 184 int kill; 185 186 task_lock(current); 187 188 spin_lock(&init_fs.lock); 189 init_fs.users++; 190 spin_unlock(&init_fs.lock); 191 192 spin_lock(&fs->lock); 193 current->fs = &init_fs; 194 kill = !--fs->users; 195 spin_unlock(&fs->lock); 196 197 task_unlock(current); 198 if (kill) 199 free_fs_struct(fs); 200 } 201 } 202