View | Details | Raw Unified | Return to bug 132293
Collapse All | Expand All

(-)current/arch/s390/appldata/appldata_base.c (-2 / +5 lines)
Lines 592-603 Link Here
592
 */
592
 */
593
void appldata_unregister_ops(struct appldata_ops *ops)
593
void appldata_unregister_ops(struct appldata_ops *ops)
594
{
594
{
595
	void *table;
595
	spin_lock(&appldata_ops_lock);
596
	spin_lock(&appldata_ops_lock);
596
	unregister_sysctl_table(ops->sysctl_header);
597
	list_del(&ops->list);
597
	list_del(&ops->list);
598
	kfree(ops->ctl_table);
598
	/* at that point any incoming access will fail */
599
	table = ops->ctl_table;
599
	ops->ctl_table = NULL;
600
	ops->ctl_table = NULL;
600
	spin_unlock(&appldata_ops_lock);
601
	spin_unlock(&appldata_ops_lock);
602
	unregister_sysctl_table(ops->sysctl_header);
603
	kfree(table);
601
	P_INFO("%s-ops unregistered!\n", ops->name);
604
	P_INFO("%s-ops unregistered!\n", ops->name);
602
}
605
}
603
/********************** module-ops management <END> **************************/
606
/********************** module-ops management <END> **************************/
(-)current/include/linux/proc_fs.h (+1 lines)
Lines 66-71 Link Here
66
	write_proc_t *write_proc;
66
	write_proc_t *write_proc;
67
	atomic_t count;		/* use count */
67
	atomic_t count;		/* use count */
68
	int deleted;		/* delete flag */
68
	int deleted;		/* delete flag */
69
	void *set;
69
};
70
};
70
71
71
struct kcore_list {
72
struct kcore_list {
(-)current/include/linux/sysctl.h (+3 lines)
Lines 24-29 Link Here
24
#include <linux/compiler.h>
24
#include <linux/compiler.h>
25
25
26
struct file;
26
struct file;
27
struct completion;
27
28
28
#define CTL_MAXNAME 10		/* how many path components do we allow in a
29
#define CTL_MAXNAME 10		/* how many path components do we allow in a
29
				   call to sysctl?   In other words, what is
30
				   call to sysctl?   In other words, what is
Lines 925-930 Link Here
925
{
926
{
926
	ctl_table *ctl_table;
927
	ctl_table *ctl_table;
927
	struct list_head ctl_entry;
928
	struct list_head ctl_entry;
929
	int used;
930
	struct completion *unregistering;
928
};
931
};
929
932
930
struct ctl_table_header * register_sysctl_table(ctl_table * table, 
933
struct ctl_table_header * register_sysctl_table(ctl_table * table, 
(-)current/kernel/sysctl.c (-29 / +107 lines)
Lines 169-175 Link Here
169
169
170
extern struct proc_dir_entry *proc_sys_root;
170
extern struct proc_dir_entry *proc_sys_root;
171
171
172
static void register_proc_table(ctl_table *, struct proc_dir_entry *);
172
static void register_proc_table(ctl_table *, struct proc_dir_entry *, void *);
173
static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
173
static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
174
#endif
174
#endif
175
175
Lines 992-1001 Link Here
992
992
993
extern void init_irq_proc (void);
993
extern void init_irq_proc (void);
994
994
995
static DEFINE_SPINLOCK(sysctl_lock);
996
997
/* called under sysctl_lock */
998
static int use_table(struct ctl_table_header *p)
999
{
1000
	if (unlikely(p->unregistering))
1001
		return 0;
1002
	p->used++;
1003
	return 1;
1004
}
1005
1006
/* called under sysctl_lock */
1007
static void unuse_table(struct ctl_table_header *p)
1008
{
1009
	if (!--p->used)
1010
		if (unlikely(p->unregistering))
1011
			complete(p->unregistering);
1012
}
1013
1014
/* called under sysctl_lock, will reacquire if has to wait */
1015
static void start_unregistering(struct ctl_table_header *p)
1016
{
1017
	/*
1018
	 * if p->used is 0, nobody will ever touch that entry again;
1019
	 * we'll eliminate all paths to it before dropping sysctl_lock
1020
	 */
1021
	if (unlikely(p->used)) {
1022
		struct completion wait;
1023
		init_completion(&wait);
1024
		p->unregistering = &wait;
1025
		spin_unlock(&sysctl_lock);
1026
		wait_for_completion(&wait);
1027
		spin_lock(&sysctl_lock);
1028
	}
1029
	/*
1030
	 * do not remove from the list until nobody holds it; walking the
1031
	 * list in do_sysctl() relies on that.
1032
	 */
1033
	list_del_init(&p->ctl_entry);
1034
}
1035
995
void __init sysctl_init(void)
1036
void __init sysctl_init(void)
996
{
1037
{
997
#ifdef CONFIG_PROC_FS
1038
#ifdef CONFIG_PROC_FS
998
	register_proc_table(root_table, proc_sys_root);
1039
	register_proc_table(root_table, proc_sys_root, &root_table_header);
999
	init_irq_proc();
1040
	init_irq_proc();
1000
#endif
1041
#endif
1001
}
1042
}
Lines 1004-1009 Link Here
1004
	       void __user *newval, size_t newlen)
1045
	       void __user *newval, size_t newlen)
1005
{
1046
{
1006
	struct list_head *tmp;
1047
	struct list_head *tmp;
1048
	int error = -ENOTDIR;
1007
1049
1008
	if (nlen <= 0 || nlen >= CTL_MAXNAME)
1050
	if (nlen <= 0 || nlen >= CTL_MAXNAME)
1009
		return -ENOTDIR;
1051
		return -ENOTDIR;
Lines 1012-1031 Link Here
1012
		if (!oldlenp || get_user(old_len, oldlenp))
1054
		if (!oldlenp || get_user(old_len, oldlenp))
1013
			return -EFAULT;
1055
			return -EFAULT;
1014
	}
1056
	}
1057
	spin_lock(&sysctl_lock);
1015
	tmp = &root_table_header.ctl_entry;
1058
	tmp = &root_table_header.ctl_entry;
1016
	do {
1059
	do {
1017
		struct ctl_table_header *head =
1060
		struct ctl_table_header *head =
1018
			list_entry(tmp, struct ctl_table_header, ctl_entry);
1061
			list_entry(tmp, struct ctl_table_header, ctl_entry);
1019
		void *context = NULL;
1062
		void *context = NULL;
1020
		int error = parse_table(name, nlen, oldval, oldlenp, 
1063
1064
		if (!use_table(head))
1065
			continue;
1066
1067
		spin_unlock(&sysctl_lock);
1068
1069
		error = parse_table(name, nlen, oldval, oldlenp, 
1021
					newval, newlen, head->ctl_table,
1070
					newval, newlen, head->ctl_table,
1022
					&context);
1071
					&context);
1023
		kfree(context);
1072
		kfree(context);
1073
1074
		spin_lock(&sysctl_lock);
1075
		unuse_table(head);
1024
		if (error != -ENOTDIR)
1076
		if (error != -ENOTDIR)
1025
			return error;
1077
			break;
1026
		tmp = tmp->next;
1078
	} while ((tmp = tmp->next) != &root_table_header.ctl_entry);
1027
	} while (tmp != &root_table_header.ctl_entry);
1079
	spin_unlock(&sysctl_lock);
1028
	return -ENOTDIR;
1080
	return error;
1029
}
1081
}
1030
1082
1031
asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
1083
asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
Lines 1236-1247 Link Here
1236
		return NULL;
1288
		return NULL;
1237
	tmp->ctl_table = table;
1289
	tmp->ctl_table = table;
1238
	INIT_LIST_HEAD(&tmp->ctl_entry);
1290
	INIT_LIST_HEAD(&tmp->ctl_entry);
1291
	tmp->used = 0;
1292
	tmp->unregistering = NULL;
1293
	spin_lock(&sysctl_lock);
1239
	if (insert_at_head)
1294
	if (insert_at_head)
1240
		list_add(&tmp->ctl_entry, &root_table_header.ctl_entry);
1295
		list_add(&tmp->ctl_entry, &root_table_header.ctl_entry);
1241
	else
1296
	else
1242
		list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
1297
		list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
1298
	spin_unlock(&sysctl_lock);
1243
#ifdef CONFIG_PROC_FS
1299
#ifdef CONFIG_PROC_FS
1244
	register_proc_table(table, proc_sys_root);
1300
	register_proc_table(table, proc_sys_root, tmp);
1245
#endif
1301
#endif
1246
	return tmp;
1302
	return tmp;
1247
}
1303
}
Lines 1255-1264 Link Here
1255
 */
1311
 */
1256
void unregister_sysctl_table(struct ctl_table_header * header)
1312
void unregister_sysctl_table(struct ctl_table_header * header)
1257
{
1313
{
1258
	list_del(&header->ctl_entry);
1314
	might_sleep();
1315
	spin_lock(&sysctl_lock);
1316
	start_unregistering(header);
1259
#ifdef CONFIG_PROC_FS
1317
#ifdef CONFIG_PROC_FS
1260
	unregister_proc_table(header->ctl_table, proc_sys_root);
1318
	unregister_proc_table(header->ctl_table, proc_sys_root);
1261
#endif
1319
#endif
1320
	spin_unlock(&sysctl_lock);
1262
	kfree(header);
1321
	kfree(header);
1263
}
1322
}
1264
1323
Lines 1269-1275 Link Here
1269
#ifdef CONFIG_PROC_FS
1328
#ifdef CONFIG_PROC_FS
1270
1329
1271
/* Scan the sysctl entries in table and add them all into /proc */
1330
/* Scan the sysctl entries in table and add them all into /proc */
1272
static void register_proc_table(ctl_table * table, struct proc_dir_entry *root)
1331
static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, void *set)
1273
{
1332
{
1274
	struct proc_dir_entry *de;
1333
	struct proc_dir_entry *de;
1275
	int len;
1334
	int len;
Lines 1305-1317 Link Here
1305
			de = create_proc_entry(table->procname, mode, root);
1364
			de = create_proc_entry(table->procname, mode, root);
1306
			if (!de)
1365
			if (!de)
1307
				continue;
1366
				continue;
1367
			de->set = set;
1308
			de->data = (void *) table;
1368
			de->data = (void *) table;
1309
			if (table->proc_handler)
1369
			if (table->proc_handler)
1310
				de->proc_fops = &proc_sys_file_operations;
1370
				de->proc_fops = &proc_sys_file_operations;
1311
		}
1371
		}
1312
		table->de = de;
1372
		table->de = de;
1313
		if (de->mode & S_IFDIR)
1373
		if (de->mode & S_IFDIR)
1314
			register_proc_table(table->child, de);
1374
			register_proc_table(table->child, de, set);
1315
	}
1375
	}
1316
}
1376
}
1317
1377
Lines 1336-1341 Link Here
1336
				continue;
1396
				continue;
1337
		}
1397
		}
1338
1398
1399
		/*
1400
		 * In any case, mark the entry as goner; we'll keep it
1401
		 * around if it's busy, but we'll know to do nothing with
1402
		 * its fields.  We are under sysctl_lock here.
1403
		 */
1404
		de->data = NULL;
1405
1339
		/* Don't unregister proc entries that are still being used.. */
1406
		/* Don't unregister proc entries that are still being used.. */
1340
		if (atomic_read(&de->count))
1407
		if (atomic_read(&de->count))
1341
			continue;
1408
			continue;
Lines 1349-1375 Link Here
1349
			  size_t count, loff_t *ppos)
1416
			  size_t count, loff_t *ppos)
1350
{
1417
{
1351
	int op;
1418
	int op;
1352
	struct proc_dir_entry *de;
1419
	struct proc_dir_entry *de = PDE(file->f_dentry->d_inode);
1353
	struct ctl_table *table;
1420
	struct ctl_table *table;
1354
	size_t res;
1421
	size_t res;
1355
	ssize_t error;
1422
	ssize_t error = -ENOTDIR;
1356
	
1357
	de = PDE(file->f_dentry->d_inode);
1358
	if (!de || !de->data)
1359
		return -ENOTDIR;
1360
	table = (struct ctl_table *) de->data;
1361
	if (!table || !table->proc_handler)
1362
		return -ENOTDIR;
1363
	op = (write ? 002 : 004);
1364
	if (ctl_perm(table, op))
1365
		return -EPERM;
1366
	
1423
	
1367
	res = count;
1424
	spin_lock(&sysctl_lock);
1368
1425
	if (de && de->data && use_table(de->set)) {
1369
	error = (*table->proc_handler) (table, write, file, buf, &res, ppos);
1426
		/*
1370
	if (error)
1427
		 * at that point we know that sysctl was not unregistered
1371
		return error;
1428
		 * and won't be until we finish
1372
	return res;
1429
		 */
1430
		spin_unlock(&sysctl_lock);
1431
		table = (struct ctl_table *) de->data;
1432
		if (!table || !table->proc_handler)
1433
			goto out;
1434
		error = -EPERM;
1435
		op = (write ? 002 : 004);
1436
		if (ctl_perm(table, op))
1437
			goto out;
1438
		
1439
		/* careful: calling conventions are nasty here */
1440
		res = count;
1441
		error = (*table->proc_handler)(table, write, file,
1442
						buf, &res, ppos);
1443
		if (!error)
1444
			error = res;
1445
	out:
1446
		spin_lock(&sysctl_lock);
1447
		unuse_table(de->set);
1448
	}
1449
	spin_unlock(&sysctl_lock);
1450
	return error;
1373
}
1451
}
1374
1452
1375
static int proc_opensys(struct inode *inode, struct file *file)
1453
static int proc_opensys(struct inode *inode, struct file *file)

Return to bug 132293