VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
457c899653991 (Thomas Gleixner  2019-05-19 13:08:55 +0100   1) // SPDX-License-Identifier: GPL-2.0-only
630d9c47274aa (Paul Gortmaker   2011-11-16 23:57:37 -0500   2) #include <linux/export.h>
3f07c0144132e (Ingo Molnar      2017-02-08 18:51:30 +0100   3) #include <linux/sched/signal.h>
299300258d1bc (Ingo Molnar      2017-02-08 18:51:36 +0100   4) #include <linux/sched/task.h>
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400   5) #include <linux/fs.h>
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400   6) #include <linux/path.h>
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400   7) #include <linux/slab.h>
5ad4e53bd5406 (Al Viro          2009-03-29 19:50:06 -0400   8) #include <linux/fs_struct.h>
f03c65993b98e (Al Viro          2011-01-14 22:30:21 -0500   9) #include "internal.h"
f03c65993b98e (Al Viro          2011-01-14 22:30:21 -0500  10) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  11) /*
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  12)  * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  13)  * It can block.
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  14)  */
dcf787f39162c (Al Viro          2013-03-01 23:51:07 -0500  15) void set_fs_root(struct fs_struct *fs, const struct path *path)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  16) {
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  17) 	struct path old_root;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  18) 
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  19) 	path_get(path);
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000  20) 	spin_lock(&fs->lock);
c28cc36469554 (Nicholas Piggin  2011-01-07 17:49:53 +1100  21) 	write_seqcount_begin(&fs->seq);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  22) 	old_root = fs->root;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  23) 	fs->root = *path;
c28cc36469554 (Nicholas Piggin  2011-01-07 17:49:53 +1100  24) 	write_seqcount_end(&fs->seq);
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000  25) 	spin_unlock(&fs->lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  26) 	if (old_root.dentry)
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  27) 		path_put(&old_root);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  28) }
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  29) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  30) /*
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  31)  * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  32)  * It can block.
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  33)  */
dcf787f39162c (Al Viro          2013-03-01 23:51:07 -0500  34) void set_fs_pwd(struct fs_struct *fs, const struct path *path)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  35) {
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  36) 	struct path old_pwd;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  37) 
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  38) 	path_get(path);
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000  39) 	spin_lock(&fs->lock);
c28cc36469554 (Nicholas Piggin  2011-01-07 17:49:53 +1100  40) 	write_seqcount_begin(&fs->seq);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  41) 	old_pwd = fs->pwd;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  42) 	fs->pwd = *path;
c28cc36469554 (Nicholas Piggin  2011-01-07 17:49:53 +1100  43) 	write_seqcount_end(&fs->seq);
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000  44) 	spin_unlock(&fs->lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  45) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  46) 	if (old_pwd.dentry)
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  47) 		path_put(&old_pwd);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  48) }
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  49) 
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  50) static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  51) {
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  52) 	if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  53) 		return 0;
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  54) 	*p = *new;
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  55) 	return 1;
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  56) }
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  57) 
dcf787f39162c (Al Viro          2013-03-01 23:51:07 -0500  58) void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  59) {
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  60) 	struct task_struct *g, *p;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  61) 	struct fs_struct *fs;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  62) 	int count = 0;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  63) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  64) 	read_lock(&tasklist_lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  65) 	do_each_thread(g, p) {
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  66) 		task_lock(p);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  67) 		fs = p->fs;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  68) 		if (fs) {
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  69) 			int hits = 0;
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000  70) 			spin_lock(&fs->lock);
c28cc36469554 (Nicholas Piggin  2011-01-07 17:49:53 +1100  71) 			write_seqcount_begin(&fs->seq);
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  72) 			hits += replace_path(&fs->root, old_root, new_root);
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  73) 			hits += replace_path(&fs->pwd, old_root, new_root);
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  74) 			write_seqcount_end(&fs->seq);
82234e61a8fc7 (Al Viro          2012-03-15 14:48:55 -0400  75) 			while (hits--) {
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  76) 				count++;
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  77) 				path_get(new_root);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  78) 			}
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000  79) 			spin_unlock(&fs->lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  80) 		}
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  81) 		task_unlock(p);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  82) 	} while_each_thread(g, p);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  83) 	read_unlock(&tasklist_lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  84) 	while (count--)
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  85) 		path_put(old_root);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  86) }
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  87) 
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400  88) void free_fs_struct(struct fs_struct *fs)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  89) {
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  90) 	path_put(&fs->root);
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400  91) 	path_put(&fs->pwd);
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400  92) 	kmem_cache_free(fs_cachep, fs);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  93) }
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  94) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  95) void exit_fs(struct task_struct *tsk)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  96) {
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400  97) 	struct fs_struct *fs = tsk->fs;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  98) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400  99) 	if (fs) {
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 100) 		int kill;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 101) 		task_lock(tsk);
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000 102) 		spin_lock(&fs->lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 103) 		tsk->fs = NULL;
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 104) 		kill = !--fs->users;
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000 105) 		spin_unlock(&fs->lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 106) 		task_unlock(tsk);
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 107) 		if (kill)
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 108) 			free_fs_struct(fs);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 109) 	}
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 110) }
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 111) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 112) struct fs_struct *copy_fs_struct(struct fs_struct *old)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 113) {
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 114) 	struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 115) 	/* We don't need to lock fs - think why ;-) */
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 116) 	if (fs) {
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 117) 		fs->users = 1;
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 118) 		fs->in_exec = 0;
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000 119) 		spin_lock_init(&fs->lock);
26475371976c6 (Ahmed S. Darwish 2020-07-20 17:55:24 +0200 120) 		seqcount_spinlock_init(&fs->seq, &fs->lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 121) 		fs->umask = old->umask;
b3e19d924b6ea (Nicholas Piggin  2011-01-07 17:50:11 +1100 122) 
b3e19d924b6ea (Nicholas Piggin  2011-01-07 17:50:11 +1100 123) 		spin_lock(&old->lock);
b3e19d924b6ea (Nicholas Piggin  2011-01-07 17:50:11 +1100 124) 		fs->root = old->root;
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400 125) 		path_get(&fs->root);
b3e19d924b6ea (Nicholas Piggin  2011-01-07 17:50:11 +1100 126) 		fs->pwd = old->pwd;
f7a99c5b7c8bd (Al Viro          2012-06-09 00:59:08 -0400 127) 		path_get(&fs->pwd);
b3e19d924b6ea (Nicholas Piggin  2011-01-07 17:50:11 +1100 128) 		spin_unlock(&old->lock);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 129) 	}
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 130) 	return fs;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 131) }
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 132) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 133) int unshare_fs_struct(void)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 134) {
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 135) 	struct fs_struct *fs = current->fs;
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 136) 	struct fs_struct *new_fs = copy_fs_struct(fs);
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 137) 	int kill;
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 138) 
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 139) 	if (!new_fs)
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 140) 		return -ENOMEM;
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 141) 
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 142) 	task_lock(current);
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000 143) 	spin_lock(&fs->lock);
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 144) 	kill = !--fs->users;
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 145) 	current->fs = new_fs;
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000 146) 	spin_unlock(&fs->lock);
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 147) 	task_unlock(current);
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 148) 
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 149) 	if (kill)
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 150) 		free_fs_struct(fs);
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 151) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 152) 	return 0;
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 153) }
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 154) EXPORT_SYMBOL_GPL(unshare_fs_struct);
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 155) 
ce3b0f8d5c220 (Al Viro          2009-03-29 19:08:22 -0400 156) int current_umask(void)
ce3b0f8d5c220 (Al Viro          2009-03-29 19:08:22 -0400 157) {
ce3b0f8d5c220 (Al Viro          2009-03-29 19:08:22 -0400 158) 	return current->fs->umask;
ce3b0f8d5c220 (Al Viro          2009-03-29 19:08:22 -0400 159) }
ce3b0f8d5c220 (Al Viro          2009-03-29 19:08:22 -0400 160) EXPORT_SYMBOL(current_umask);
ce3b0f8d5c220 (Al Viro          2009-03-29 19:08:22 -0400 161) 
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 162) /* to be mentioned only in INIT_TASK */
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 163) struct fs_struct init_fs = {
498052bba55ec (Al Viro          2009-03-30 07:20:30 -0400 164) 	.users		= 1,
2a4419b5b2a77 (Nicholas Piggin  2010-08-18 04:37:33 +1000 165) 	.lock		= __SPIN_LOCK_UNLOCKED(init_fs.lock),
26475371976c6 (Ahmed S. Darwish 2020-07-20 17:55:24 +0200 166) 	.seq		= SEQCNT_SPINLOCK_ZERO(init_fs.seq, &init_fs.lock),
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 167) 	.umask		= 0022,
3e93cd671813e (Al Viro          2009-03-29 19:00:13 -0400 168) };