From b5c67280c349e9341bfaa9d0e6bbfa176344bb2e Mon Sep 17 00:00:00 2001 From: Sridhar Samudrala Date: Wed, 27 Aug 2003 01:02:04 -0700 Subject: [SCTP] SCTP_SET_PEER_PRIMARY socket option support. (Kevin Gao) --- include/linux/sctp.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sctp.h b/include/linux/sctp.h index 6ebaff34570c..6131e3c9aa45 100644 --- a/include/linux/sctp.h +++ b/include/linux/sctp.h @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation + * (C) Copyright IBM Corp. 2001, 2003 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001-2002 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll @@ -42,6 +42,8 @@ * randall@sctp.chicago.il.us * kmorneau@cisco.com * qxie1@email.mot.com + * Sridhar Samudrala + * Kevin Gao * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -507,6 +509,11 @@ typedef struct sctp_cwr_chunk { * The ASCONF Parameter Response is used in the ASCONF-ACK to * report status of ASCONF processing. */ +typedef struct sctp_addip_param { + sctp_paramhdr_t param_hdr; + __u32 crr_id; +}sctp_addip_param_t __attribute__((packed)); + typedef struct sctp_addiphdr { __u32 serial; __u8 params[0]; -- cgit v1.2.3 From e804252bee9e8c9463ff456f60e07f410eed1afb Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 3 Sep 2003 02:50:10 +0100 Subject: [CPUFREQ] Completely separate governors from policies. Governors are for CPUfreq drivers which have a ->target callback, Policies are for CPUfreq drivers which have a ->setpolicy callback. Also, the "hardwired" governors "powersave" and "performance" are removed. --- drivers/cpufreq/cpufreq.c | 102 +++++++++++++++++++------------------------- drivers/cpufreq/proc_intf.c | 26 +++++------ include/linux/cpufreq.h | 21 +++++++-- 3 files changed, 74 insertions(+), 75 deletions(-) (limited to 'include/linux') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7f80c321c785..1b037bf0f950 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -109,13 +109,18 @@ static void cpufreq_cpu_put(struct cpufreq_policy *data) int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor) { - if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { - *policy = CPUFREQ_POLICY_PERFORMANCE; - return 0; - } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { - *policy = CPUFREQ_POLICY_POWERSAVE; - return 0; - } else { + if (!cpufreq_driver) + return -EINVAL; + if (cpufreq_driver->setpolicy) { + if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { + *policy = CPUFREQ_POLICY_PERFORMANCE; + return 0; + } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { + *policy = CPUFREQ_POLICY_POWERSAVE; + return 0; + } + return -EINVAL; + } else { struct cpufreq_governor *t; down(&cpufreq_governor_sem); if (!cpufreq_driver || !cpufreq_driver->target) @@ -123,7 +128,6 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, list_for_each_entry(t, &cpufreq_governor_list, governor_list) { if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) { *governor = t; - *policy = CPUFREQ_POLICY_GOVERNOR; up(&cpufreq_governor_sem); return 0; } @@ -190,16 +194,13 @@ store_one(scaling_max_freq,max); */ static ssize_t show_scaling_governor (struct cpufreq_policy * policy, char *buf) { - switch (policy->policy) { - case CPUFREQ_POLICY_POWERSAVE: + if(policy->policy == CPUFREQ_POLICY_POWERSAVE) return sprintf(buf, "powersave\n"); - case CPUFREQ_POLICY_PERFORMANCE: + else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) return sprintf(buf, "performance\n"); - case CPUFREQ_POLICY_GOVERNOR: + else if (policy->governor) return snprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name); - default: - return -EINVAL; - } + return -EINVAL; } @@ -246,15 +247,15 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy, ssize_t i = 0; struct cpufreq_governor *t; - i += sprintf(buf, "performance powersave"); - - if (!cpufreq_driver->target) + if (!cpufreq_driver->target) { + i += sprintf(buf, "performance powersave"); goto out; + } list_for_each_entry(t, &cpufreq_governor_list, governor_list) { if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2))) goto out; - i += snprintf(&buf[i], CPUFREQ_NAME_LEN, " %s", t->name); + i += snprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); } out: i += sprintf(&buf[i], "\n"); @@ -396,10 +397,12 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) spin_lock_irqsave(&cpufreq_driver_lock, flags); cpufreq_cpu_data[cpu] = policy; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - + policy->governor = NULL; /* to assure that the starting sequence is + * run in cpufreq_set_policy */ up(&policy->lock); /* set default policy */ + ret = cpufreq_set_policy(&new_policy); if (ret) goto err_out_unregister; @@ -622,33 +625,18 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target); static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { - int ret = 0; + int ret = -EINVAL; - switch (policy->policy) { - case CPUFREQ_POLICY_POWERSAVE: - if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) { - ret = __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); - } - break; - case CPUFREQ_POLICY_PERFORMANCE: - if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) { - ret = __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - } - break; - case CPUFREQ_POLICY_GOVERNOR: - ret = -EINVAL; - if (!try_module_get(policy->governor->owner)) - break; - ret = policy->governor->governor(policy, event); - /* we keep one module reference alive for each CPU governed by this CPU */ - if ((event != CPUFREQ_GOV_START) || ret) - module_put(policy->governor->owner); - if ((event == CPUFREQ_GOV_STOP) && !ret) - module_put(policy->governor->owner); - break; - default: - ret = -EINVAL; - } + if (!try_module_get(policy->governor->owner)) + return -EINVAL; + + ret = policy->governor->governor(policy, event); + + /* we keep one module reference alive for each CPU governed by this CPU */ + if ((event != CPUFREQ_GOV_START) || ret) + module_put(policy->governor->owner); + if ((event == CPUFREQ_GOV_STOP) && !ret) + module_put(policy->governor->owner); return ret; } @@ -680,11 +668,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor) if (!governor) return -EINVAL; - if (!strnicmp(governor->name,"powersave",CPUFREQ_NAME_LEN)) - return -EBUSY; - if (!strnicmp(governor->name,"performance",CPUFREQ_NAME_LEN)) - return -EBUSY; - down(&cpufreq_governor_sem); list_for_each_entry(t, &cpufreq_governor_list, governor_list) { @@ -808,23 +791,24 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) data->policy = policy->policy; ret = cpufreq_driver->setpolicy(policy); } else { - if ((policy->policy != data->policy) || - ((policy->policy == CPUFREQ_POLICY_GOVERNOR) && (policy->governor != data->governor))) { + if (policy->governor != data->governor) { /* save old, working values */ - unsigned int old_pol = data->policy; struct cpufreq_governor *old_gov = data->governor; /* end old governor */ - __cpufreq_governor(data, CPUFREQ_GOV_STOP); + if (data->governor) + __cpufreq_governor(data, CPUFREQ_GOV_STOP); /* start new governor */ - data->policy = policy->policy; data->governor = policy->governor; if (__cpufreq_governor(data, CPUFREQ_GOV_START)) { /* new governor failed, so re-start old one */ - data->policy = old_pol; - data->governor = old_gov; - __cpufreq_governor(data, CPUFREQ_GOV_START); + if (old_gov) { + data->governor = old_gov; + __cpufreq_governor(data, CPUFREQ_GOV_START); + } + ret = -EINVAL; + goto error_out; } /* might be a policy change, too, so fall through */ } diff --git a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c index d314e526af9c..b8d6b056051a 100644 --- a/drivers/cpufreq/proc_intf.c +++ b/drivers/cpufreq/proc_intf.c @@ -126,20 +126,20 @@ static int cpufreq_proc_read ( p += sprintf(p, "CPU%3d %9d kHz (%3d %%) - %9d kHz (%3d %%) - ", i , policy.min, min_pctg, policy.max, max_pctg); - switch (policy.policy) { - case CPUFREQ_POLICY_POWERSAVE: - p += sprintf(p, "powersave\n"); - break; - case CPUFREQ_POLICY_PERFORMANCE: - p += sprintf(p, "performance\n"); - break; - case CPUFREQ_POLICY_GOVERNOR: + if (policy.policy) { + switch (policy.policy) { + case CPUFREQ_POLICY_POWERSAVE: + p += sprintf(p, "powersave\n"); + break; + case CPUFREQ_POLICY_PERFORMANCE: + p += sprintf(p, "performance\n"); + break; + default: + p += sprintf(p, "INVALID\n"); + break; + } + } else p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name); - break; - default: - p += sprintf(p, "INVALID\n"); - break; - } } end: len = (p - page); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 3d466f6680cb..f920b0a8e83e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -36,11 +36,13 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); #define CPUFREQ_POLICY_NOTIFIER (1) -/********************** cpufreq policy notifiers *********************/ +/* if (cpufreq_driver->target) exists, the ->governor decides what frequency + * within the limits is used. If (cpufreq_driver->setpolicy> exists, these + * two generic policies are available: + */ #define CPUFREQ_POLICY_POWERSAVE (1) #define CPUFREQ_POLICY_PERFORMANCE (2) -#define CPUFREQ_POLICY_GOVERNOR (3) /* Frequency values here are CPU kHz so that hardware which doesn't run * with some frequencies can complain without having to guess what per @@ -151,6 +153,7 @@ int cpufreq_governor(unsigned int cpu, unsigned int event); int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); + /********************************************************************* * CPUFREQ DRIVER INTERFACE * *********************************************************************/ @@ -221,7 +224,6 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpu /********************************************************************* * CPUFREQ USERSPACE GOVERNOR * *********************************************************************/ -extern struct cpufreq_governor cpufreq_gov_userspace; int cpufreq_gov_userspace_init(void); int cpufreq_setmax(unsigned int cpu); @@ -279,6 +281,19 @@ enum { #endif /* CONFIG_CPU_FREQ_GOV_USERSPACE */ +/********************************************************************* + * CPUFREQ DEFAULT GOVERNOR * + *********************************************************************/ + + +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE +extern struct cpufreq_governor cpufreq_gov_performance; +#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance +#elif CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE +extern struct cpufreq_governor cpufreq_gov_userspace; +#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace +#endif + /********************************************************************* * FREQUENCY TABLE HELPERS * *********************************************************************/ -- cgit v1.2.3 From c2d0c666a4683fb5c06de6b9ebf470bd97c1430b Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 3 Sep 2003 04:19:46 +0100 Subject: [CPUFREQ] new cpufreq_driver->resume callback, needed (at least) for speedstep-smi. --- Documentation/cpu-freq/cpu-drivers.txt | 6 ++++++ drivers/cpufreq/cpufreq.c | 13 +++++++++++++ include/linux/cpufreq.h | 1 + 3 files changed, 20 insertions(+) (limited to 'include/linux') diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index bf4c682bc696..43c743903dd7 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt @@ -64,6 +64,12 @@ And optionally cpufreq_driver.exit - A pointer to a per-CPU cleanup function. +cpufreq_driver.resume - A pointer to a per-CPU resume function + which is called with interrupts disabled + and _before_ the pre-suspend frequency + and/or policy is restored by a call to + ->target or ->setpolicy. + cpufreq_driver.attr - A pointer to a NULL-terminated list of "struct freq_attr" which allow to export values to sysfs. diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1b037bf0f950..04cfcc54fa1f 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -495,6 +495,13 @@ static int cpufreq_resume(struct sys_device * sysdev) if (!cpu_policy) return -EINVAL; + if (cpufreq_driver->resume) + ret = cpufreq_driver->resume(cpu_policy); + if (ret) { + printk(KERN_ERR "cpufreq: resume failed in ->resume step on CPU %u\n", cpu_policy->cpu); + goto out; + } + if (cpufreq_driver->setpolicy) ret = cpufreq_driver->setpolicy(cpu_policy); else @@ -503,6 +510,12 @@ static int cpufreq_resume(struct sys_device * sysdev) */ ret = cpufreq_driver->target(cpu_policy, cpu_policy->cur, CPUFREQ_RELATION_H); + if (ret) { + printk(KERN_ERR "cpufreq: resume failed in ->setpolicy/target step on CPU %u\n", cpu_policy->cpu); + goto out; + } + + out: cpufreq_cpu_put(cpu_policy); return ret; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index f920b0a8e83e..f747117285f4 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -179,6 +179,7 @@ struct cpufreq_driver { /* optional */ int (*exit) (struct cpufreq_policy *policy); + int (*resume) (struct cpufreq_policy *policy); struct freq_attr **attr; }; -- cgit v1.2.3 From 8697648c34930bb48cfc40785688cd73a3e7269c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 4 Sep 2003 09:02:39 -0700 Subject: [CRYPTO]: Use try_then_request_module(). try_then_request_module() does what crypto/autoload.c is doing, so replace it. Fix try_then_request_module(), too (thanks James). --- crypto/Makefile | 3 +-- crypto/autoload.c | 37 ------------------------------------- crypto/internal.h | 10 ++++------ include/linux/kmod.h | 2 +- 4 files changed, 6 insertions(+), 46 deletions(-) delete mode 100644 crypto/autoload.c (limited to 'include/linux') diff --git a/crypto/Makefile b/crypto/Makefile index f3325db1ee76..8326b4fb5be4 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -2,11 +2,10 @@ # Cryptographic API # -autoload-crypto-$(CONFIG_KMOD) = autoload.o proc-crypto-$(CONFIG_PROC_FS) = proc.o obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \ - $(autoload-crypto-y) $(proc-crypto-y) + $(proc-crypto-y) obj-$(CONFIG_CRYPTO_HMAC) += hmac.o obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o diff --git a/crypto/autoload.c b/crypto/autoload.c deleted file mode 100644 index 7cda40b39ddf..000000000000 --- a/crypto/autoload.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Cryptographic API. - * - * Algorithm autoloader. - * - * Copyright (c) 2002 James Morris - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - */ -#include -#include -#include -#include -#include "internal.h" - -/* - * A far more intelligent version of this is planned. For now, just - * try an exact match on the name of the algorithm. - */ -void crypto_alg_autoload(const char *name) -{ - request_module("%s", name); -} - -struct crypto_alg *crypto_alg_mod_lookup(const char *name) -{ - struct crypto_alg *alg = crypto_alg_lookup(name); - if (alg == NULL) { - crypto_alg_autoload(name); - alg = crypto_alg_lookup(name); - } - return alg; -} diff --git a/crypto/internal.h b/crypto/internal.h index 10880d149afe..8ba30b772ee3 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -48,15 +49,12 @@ static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) struct crypto_alg *crypto_alg_lookup(const char *name); -#ifdef CONFIG_KMOD -void crypto_alg_autoload(const char *name); -struct crypto_alg *crypto_alg_mod_lookup(const char *name); -#else +/* A far more intelligent version of this is planned. For now, just + * try an exact match on the name of the algorithm. */ static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) { - return crypto_alg_lookup(name); + return try_then_request_module(crypto_alg_lookup(name), name); } -#endif #ifdef CONFIG_CRYPTO_HMAC int crypto_alloc_hmac_block(struct crypto_tfm *tfm); diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 7fa02a737518..8412faeea0f7 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -29,7 +29,7 @@ extern int request_module(const char * name, ...) __attribute__ ((format (printf static inline int request_module(const char * name, ...) { return -ENOSYS; } #endif -#define try_then_request_module(x, mod...) ((x) ?: request_module(mod), (x)) +#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x))) extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait); #ifdef CONFIG_HOTPLUG -- cgit v1.2.3 From c81eb7f2446ad21be044121f2b7a500a7c506526 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 4 Sep 2003 13:40:24 -0700 Subject: [NET]: Kill more verbose init msgs and unused RTNL_DEBUG define. --- include/linux/rtnetlink.h | 3 --- net/core/dv.c | 1 - net/core/rtnetlink.c | 3 --- net/ipv4/ipmr.c | 1 - 4 files changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 3e3a26916a12..fd8b35209ccc 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -3,9 +3,6 @@ #include -#define RTNL_DEBUG 1 - - /**** * Routing/neighbour discovery messages. ****/ diff --git a/net/core/dv.c b/net/core/dv.c index 62352d7c9bcc..e7de41f94f9c 100644 --- a/net/core/dv.c +++ b/net/core/dv.c @@ -40,7 +40,6 @@ const char sysctl_divert_version[32]="0.46"; /* Current version */ static int __init dv_init(void) { - printk(KERN_INFO "NET4: Frame Diverter %s\n", sysctl_divert_version); return 0; } module_init(dv_init); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 4215e4a7dcd0..444f07e51e27 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -559,9 +559,6 @@ struct notifier_block rtnetlink_dev_notifier = { void __init rtnetlink_init(void) { -#ifdef RTNL_DEBUG - printk("Initializing RT netlink socket\n"); -#endif rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv); if (rtnl == NULL) panic("rtnetlink_init: cannot initialize rtnetlink\n"); diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 3f671efed9e6..9f5a0485e0a7 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1744,7 +1744,6 @@ static struct inet_protocol pim_protocol = { void __init ip_mr_init(void) { - printk(KERN_INFO "Linux IP multicast router 0.06 plus PIM-SM\n"); mrt_cachep = kmem_cache_create("ip_mrt_cache", sizeof(struct mfc_cache), 0, SLAB_HWCACHE_ALIGN, -- cgit v1.2.3 From cadf0417e85b74d296178c7d158ef20716b82b63 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 4 Sep 2003 17:13:17 -0700 Subject: [PATCH] fix IO hangs The "insert_here" list pointer logic was broken, and unnecessary. Kill it and its associated logic off completely - just tell the IO scheduler what kind of insert it is. This also makes the *_insert_request strategies much easier to follow, imo. --- drivers/block/as-iosched.c | 55 ++++++++++++------------------ drivers/block/deadline-iosched.c | 73 +++++++++++++++------------------------- drivers/block/elevator.c | 26 ++++++-------- drivers/block/ll_rw_blk.c | 32 +++++++----------- drivers/block/noop-iosched.c | 19 ++++++----- drivers/block/scsi_ioctl.c | 2 +- drivers/ide/ide-io.c | 6 ++-- include/linux/blkdev.h | 2 +- include/linux/elevator.h | 16 +++++---- 9 files changed, 100 insertions(+), 131 deletions(-) (limited to 'include/linux') diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c index 27384d27b566..3d9c58788373 100644 --- a/drivers/block/as-iosched.c +++ b/drivers/block/as-iosched.c @@ -255,7 +255,7 @@ static void as_remove_merge_hints(request_queue_t *q, struct as_rq *arq) { as_del_arq_hash(arq); - if (q->last_merge == &arq->request->queuelist) + if (q->last_merge == arq->request) q->last_merge = NULL; } @@ -1347,50 +1347,39 @@ static void as_requeue_request(request_queue_t *q, struct request *rq) } static void -as_insert_request(request_queue_t *q, struct request *rq, - struct list_head *insert_here) +as_insert_request(request_queue_t *q, struct request *rq, int where) { struct as_data *ad = q->elevator.elevator_data; struct as_rq *arq = RQ_DATA(rq); - if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) { - q->last_merge = NULL; - - if (insert_here != ad->dispatch) { + switch (where) { + case ELEVATOR_INSERT_BACK: while (ad->next_arq[REQ_SYNC]) as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); while (ad->next_arq[REQ_ASYNC]) as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); - } - - if (!insert_here) - insert_here = ad->dispatch->prev; - } - - if (unlikely(!blk_fs_request(rq))) { - if (!insert_here) - insert_here = ad->dispatch; - } - - if (insert_here) { - list_add(&rq->queuelist, insert_here); - - /* Stop anticipating - let this request get through */ - if (list_empty(ad->dispatch)) + list_add_tail(&rq->queuelist, ad->dispatch); + break; + case ELEVATOR_INSERT_FRONT: + list_add(&rq->queuelist, ad->dispatch); as_antic_stop(ad); - - return; + break; + case ELEVATOR_INSERT_SORT: + BUG_ON(!blk_fs_request(rq)); + as_add_request(ad, arq); + break; + default: + printk("%s: bad insert point %d\n", __FUNCTION__,where); + return; } if (rq_mergeable(rq)) { as_add_arq_hash(ad, arq); if (!q->last_merge) - q->last_merge = &rq->queuelist; + q->last_merge = rq; } - - as_add_request(ad, arq); } /* @@ -1438,7 +1427,7 @@ as_latter_request(request_queue_t *q, struct request *rq) } static int -as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio) +as_merge(request_queue_t *q, struct request **req, struct bio *bio) { struct as_data *ad = q->elevator.elevator_data; sector_t rb_key = bio->bi_sector + bio_sectors(bio); @@ -1450,7 +1439,7 @@ as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio) */ ret = elv_try_last_merge(q, bio); if (ret != ELEVATOR_NO_MERGE) { - __rq = list_entry_rq(q->last_merge); + __rq = q->last_merge; goto out_insert; } @@ -1482,11 +1471,11 @@ as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio) return ELEVATOR_NO_MERGE; out: - q->last_merge = &__rq->queuelist; + q->last_merge = __rq; out_insert: if (ret) as_hot_arq_hash(ad, RQ_DATA(__rq)); - *insert = &__rq->queuelist; + *req = __rq; return ret; } @@ -1514,7 +1503,7 @@ static void as_merged_request(request_queue_t *q, struct request *req) */ } - q->last_merge = &req->queuelist; + q->last_merge = req; } static void diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c index dc2b121a9239..8bb37f65d536 100644 --- a/drivers/block/deadline-iosched.c +++ b/drivers/block/deadline-iosched.c @@ -33,13 +33,7 @@ static const int deadline_hash_shift = 5; #define DL_HASH_ENTRIES (1 << deadline_hash_shift) #define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) #define list_entry_hash(ptr) list_entry((ptr), struct deadline_rq, hash) -#define ON_HASH(drq) (drq)->hash_valid_count - -#define DL_INVALIDATE_HASH(dd) \ - do { \ - if (!++(dd)->hash_valid_count) \ - (dd)->hash_valid_count = 1; \ - } while (0) +#define ON_HASH(drq) (drq)->on_hash struct deadline_data { /* @@ -58,7 +52,6 @@ struct deadline_data { struct deadline_rq *next_drq[2]; struct list_head *dispatch; /* driver dispatch queue */ struct list_head *hash; /* request hash */ - unsigned long hash_valid_count; /* barrier hash count */ unsigned int batching; /* number of sequential requests made */ sector_t last_sector; /* head position */ unsigned int starved; /* times reads have starved writes */ @@ -90,7 +83,7 @@ struct deadline_rq { * request hash, key is the ending offset (for back merge lookup) */ struct list_head hash; - unsigned long hash_valid_count; + char on_hash; /* * expire fifo @@ -110,7 +103,7 @@ static kmem_cache_t *drq_pool; */ static inline void __deadline_del_drq_hash(struct deadline_rq *drq) { - drq->hash_valid_count = 0; + drq->on_hash = 0; list_del_init(&drq->hash); } @@ -125,7 +118,7 @@ deadline_remove_merge_hints(request_queue_t *q, struct deadline_rq *drq) { deadline_del_drq_hash(drq); - if (q->last_merge == &drq->request->queuelist) + if (q->last_merge == drq->request) q->last_merge = NULL; } @@ -136,7 +129,7 @@ deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq) BUG_ON(ON_HASH(drq)); - drq->hash_valid_count = dd->hash_valid_count; + drq->on_hash = 1; list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]); } @@ -169,8 +162,7 @@ deadline_find_drq_hash(struct deadline_data *dd, sector_t offset) BUG_ON(!ON_HASH(drq)); - if (!rq_mergeable(__rq) - || drq->hash_valid_count != dd->hash_valid_count) { + if (!rq_mergeable(__rq)) { __deadline_del_drq_hash(drq); continue; } @@ -324,7 +316,7 @@ static void deadline_remove_request(request_queue_t *q, struct request *rq) } static int -deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio) +deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) { struct deadline_data *dd = q->elevator.elevator_data; struct request *__rq; @@ -335,7 +327,7 @@ deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio) */ ret = elv_try_last_merge(q, bio); if (ret != ELEVATOR_NO_MERGE) { - __rq = list_entry_rq(q->last_merge); + __rq = q->last_merge; goto out_insert; } @@ -371,11 +363,11 @@ deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio) return ELEVATOR_NO_MERGE; out: - q->last_merge = &__rq->queuelist; + q->last_merge = __rq; out_insert: if (ret) deadline_hot_drq_hash(dd, RQ_DATA(__rq)); - *insert = &__rq->queuelist; + *req = __rq; return ret; } @@ -398,7 +390,7 @@ static void deadline_merged_request(request_queue_t *q, struct request *req) deadline_add_drq_rb(dd, drq); } - q->last_merge = &req->queuelist; + q->last_merge = req; } static void @@ -621,43 +613,35 @@ dispatch: } static void -deadline_insert_request(request_queue_t *q, struct request *rq, - struct list_head *insert_here) +deadline_insert_request(request_queue_t *q, struct request *rq, int where) { struct deadline_data *dd = q->elevator.elevator_data; struct deadline_rq *drq = RQ_DATA(rq); - if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) { - DL_INVALIDATE_HASH(dd); - q->last_merge = NULL; - - if (insert_here != dd->dispatch) { + switch (where) { + case ELEVATOR_INSERT_BACK: while (deadline_dispatch_requests(dd)) ; - } - - if (!insert_here) - insert_here = dd->dispatch->prev; - } - - if (unlikely(!blk_fs_request(rq))) { - if (!insert_here) - insert_here = dd->dispatch; - } - - if (insert_here) { - list_add(&rq->queuelist, insert_here); - return; + list_add_tail(&rq->queuelist, dd->dispatch); + break; + case ELEVATOR_INSERT_FRONT: + list_add(&rq->queuelist, dd->dispatch); + break; + case ELEVATOR_INSERT_SORT: + BUG_ON(!blk_fs_request(rq)); + deadline_add_request(dd, drq); + break; + default: + printk("%s: bad insert point %d\n", __FUNCTION__,where); + return; } if (rq_mergeable(rq)) { deadline_add_drq_hash(dd, drq); if (!q->last_merge) - q->last_merge = &rq->queuelist; + q->last_merge = rq; } - - deadline_add_request(dd, drq); } static int deadline_queue_empty(request_queue_t *q) @@ -748,7 +732,6 @@ static int deadline_init(request_queue_t *q, elevator_t *e) dd->dispatch = &q->queue_head; dd->fifo_expire[READ] = read_expire; dd->fifo_expire[WRITE] = write_expire; - dd->hash_valid_count = 1; dd->writes_starved = writes_starved; dd->front_merges = 1; dd->fifo_batch = fifo_batch; @@ -779,7 +762,7 @@ deadline_set_request(request_queue_t *q, struct request *rq, int gfp_mask) drq->request = rq; INIT_LIST_HEAD(&drq->hash); - drq->hash_valid_count = 0; + drq->on_hash = 0; INIT_LIST_HEAD(&drq->fifo); diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c index 4654fddecd7d..fcb00cfa4fd7 100644 --- a/drivers/block/elevator.c +++ b/drivers/block/elevator.c @@ -81,7 +81,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio) inline int elv_try_last_merge(request_queue_t *q, struct bio *bio) { if (q->last_merge) - return elv_try_merge(list_entry_rq(q->last_merge), bio); + return elv_try_merge(q->last_merge, bio); return ELEVATOR_NO_MERGE; } @@ -117,12 +117,12 @@ int elevator_global_init(void) return 0; } -int elv_merge(request_queue_t *q, struct list_head **entry, struct bio *bio) +int elv_merge(request_queue_t *q, struct request **req, struct bio *bio) { elevator_t *e = &q->elevator; if (e->elevator_merge_fn) - return e->elevator_merge_fn(q, entry, bio); + return e->elevator_merge_fn(q, req, bio); return ELEVATOR_NO_MERGE; } @@ -140,7 +140,7 @@ void elv_merge_requests(request_queue_t *q, struct request *rq, { elevator_t *e = &q->elevator; - if (q->last_merge == &next->queuelist) + if (q->last_merge == next) q->last_merge = NULL; if (e->elevator_merge_req_fn) @@ -156,29 +156,25 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) if (q->elevator.elevator_requeue_req_fn) q->elevator.elevator_requeue_req_fn(q, rq); else - __elv_add_request(q, rq, 0, 0); + __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); } -void __elv_add_request(request_queue_t *q, struct request *rq, int at_end, +void __elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { - struct list_head *insert = NULL; - - if (!at_end) - insert = &q->queue_head; if (plug) blk_plug_device(q); - q->elevator.elevator_add_req_fn(q, rq, insert); + q->elevator.elevator_add_req_fn(q, rq, where); } -void elv_add_request(request_queue_t *q, struct request *rq, int at_end, +void elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - __elv_add_request(q, rq, at_end, plug); + __elv_add_request(q, rq, where, plug); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -200,7 +196,7 @@ struct request *elv_next_request(request_queue_t *q) */ rq->flags |= REQ_STARTED; - if (&rq->queuelist == q->last_merge) + if (rq == q->last_merge) q->last_merge = NULL; if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn) @@ -238,7 +234,7 @@ void elv_remove_request(request_queue_t *q, struct request *rq) * deleted without ever being given to driver (merged with another * request). */ - if (&rq->queuelist == q->last_merge) + if (rq == q->last_merge) q->last_merge = NULL; if (e->elevator_remove_req_fn) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index c57d8d0f42c2..541b45c519ef 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -703,7 +703,7 @@ void blk_queue_invalidate_tags(request_queue_t *q) blk_queue_end_tag(q, rq); rq->flags &= ~REQ_STARTED; - __elv_add_request(q, rq, 0, 0); + __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0); } } @@ -1632,11 +1632,16 @@ void blk_insert_request(request_queue_t *q, struct request *rq, if(reinsert) { blk_requeue_request(q, rq); } else { + int where = ELEVATOR_INSERT_BACK; + + if (at_head) + where = ELEVATOR_INSERT_FRONT; + if (blk_rq_tagged(rq)) blk_queue_end_tag(q, rq); drive_stat_acct(rq, rq->nr_sectors, 1); - __elv_add_request(q, rq, !at_head, 0); + __elv_add_request(q, rq, where, 0); } q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); @@ -1669,8 +1674,7 @@ void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) * queue lock is held and interrupts disabled, as we muck with the * request queue list. */ -static inline void add_request(request_queue_t * q, struct request * req, - struct list_head *insert_here) +static inline void add_request(request_queue_t * q, struct request * req) { drive_stat_acct(req, req->nr_sectors, 1); @@ -1681,7 +1685,7 @@ static inline void add_request(request_queue_t * q, struct request * req, * elevator indicated where it wants this request to be * inserted at elevator_merge time */ - __elv_add_request_pos(q, req, insert_here); + __elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0); } /* @@ -1880,7 +1884,6 @@ static int __make_request(request_queue_t *q, struct bio *bio) { struct request *req, *freereq = NULL; int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, ra; - struct list_head *insert_here; sector_t sector; sector = bio->bi_sector; @@ -1903,7 +1906,6 @@ static int __make_request(request_queue_t *q, struct bio *bio) ra = bio->bi_rw & (1 << BIO_RW_AHEAD); again: - insert_here = NULL; spin_lock_irq(q->queue_lock); if (elv_queue_empty(q)) { @@ -1913,17 +1915,13 @@ again: if (barrier) goto get_rq; - el_ret = elv_merge(q, &insert_here, bio); + el_ret = elv_merge(q, &req, bio); switch (el_ret) { case ELEVATOR_BACK_MERGE: - req = list_entry_rq(insert_here); - BUG_ON(!rq_mergeable(req)); - if (!q->back_merge_fn(q, req, bio)) { - insert_here = &req->queuelist; + if (!q->back_merge_fn(q, req, bio)) break; - } req->biotail->bi_next = bio; req->biotail = bio; @@ -1934,14 +1932,10 @@ again: goto out; case ELEVATOR_FRONT_MERGE: - req = list_entry_rq(insert_here); - BUG_ON(!rq_mergeable(req)); - if (!q->front_merge_fn(q, req, bio)) { - insert_here = req->queuelist.prev; + if (!q->front_merge_fn(q, req, bio)) break; - } bio->bi_next = req->bio; req->cbio = req->bio = bio; @@ -2029,7 +2023,7 @@ get_rq: req->rq_disk = bio->bi_bdev->bd_disk; req->start_time = jiffies; - add_request(q, req, insert_here); + add_request(q, req); out: if (freereq) __blk_put_request(q, freereq); diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c index 2eadd041914b..7511b955de70 100644 --- a/drivers/block/noop-iosched.c +++ b/drivers/block/noop-iosched.c @@ -17,17 +17,15 @@ /* * See if we can find a request that this buffer can be coalesced with. */ -int elevator_noop_merge(request_queue_t *q, struct list_head **insert, +int elevator_noop_merge(request_queue_t *q, struct request **req, struct bio *bio) { struct list_head *entry = &q->queue_head; struct request *__rq; int ret; - if ((ret = elv_try_last_merge(q, bio))) { - *insert = q->last_merge; + if ((ret = elv_try_last_merge(q, bio))) return ret; - } while ((entry = entry->prev) != &q->queue_head) { __rq = list_entry_rq(entry); @@ -41,8 +39,8 @@ int elevator_noop_merge(request_queue_t *q, struct list_head **insert, continue; if ((ret = elv_try_merge(__rq, bio))) { - *insert = &__rq->queuelist; - q->last_merge = &__rq->queuelist; + *req = __rq; + q->last_merge = __rq; return ret; } } @@ -57,8 +55,13 @@ void elevator_noop_merge_requests(request_queue_t *q, struct request *req, } void elevator_noop_add_request(request_queue_t *q, struct request *rq, - struct list_head *insert_here) + int where) { + struct list_head *insert = q->queue_head.prev; + + if (where == ELEVATOR_INSERT_FRONT) + insert = &q->queue_head; + list_add_tail(&rq->queuelist, &q->queue_head); /* @@ -67,7 +70,7 @@ void elevator_noop_add_request(request_queue_t *q, struct request *rq, if (rq->flags & REQ_HARDBARRIER) q->last_merge = NULL; else if (!q->last_merge) - q->last_merge = &rq->queuelist; + q->last_merge = rq; } struct request *elevator_noop_next_request(request_queue_t *q) diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c index 94574b14f30b..3d18a7a70108 100644 --- a/drivers/block/scsi_ioctl.c +++ b/drivers/block/scsi_ioctl.c @@ -68,7 +68,7 @@ static int blk_do_rq(request_queue_t *q, struct block_device *bdev, rq->flags |= REQ_NOMERGE; rq->waiting = &wait; - elv_add_request(q, rq, 1, 1); + elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1); generic_unplug_device(q); wait_for_completion(&wait); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2b94c9450336..0d9fff1f883d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1387,7 +1387,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio unsigned long flags; ide_hwgroup_t *hwgroup = HWGROUP(drive); DECLARE_COMPLETION(wait); - int insert_end = 1, err; + int where = ELEVATOR_INSERT_BACK, err; int must_wait = (action == ide_wait || action == ide_head_wait); #ifdef CONFIG_BLK_DEV_PDC4030 @@ -1419,10 +1419,10 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio spin_lock_irqsave(&ide_lock, flags); if (action == ide_preempt || action == ide_head_wait) { hwgroup->rq = NULL; - insert_end = 0; + where = ELEVATOR_INSERT_FRONT; rq->flags |= REQ_PREEMPT; } - __elv_add_request(drive->queue, rq, insert_end, 0); + __elv_add_request(drive->queue, rq, where, 0); ide_do_request(hwgroup, IDE_NO_IRQ); spin_unlock_irqrestore(&ide_lock, flags); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9c7e6d86e810..285fd86e2b48 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -270,7 +270,7 @@ struct request_queue * Together with queue_head for cacheline sharing */ struct list_head queue_head; - struct list_head *last_merge; + struct request *last_merge; elevator_t elevator; /* diff --git a/include/linux/elevator.h b/include/linux/elevator.h index ac30ae089069..e43d670c1371 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -1,7 +1,7 @@ #ifndef _LINUX_ELEVATOR_H #define _LINUX_ELEVATOR_H -typedef int (elevator_merge_fn) (request_queue_t *, struct list_head **, +typedef int (elevator_merge_fn) (request_queue_t *, struct request **, struct bio *); typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *); @@ -10,7 +10,7 @@ typedef void (elevator_merged_fn) (request_queue_t *, struct request *); typedef struct request *(elevator_next_req_fn) (request_queue_t *); -typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *); +typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, int); typedef int (elevator_queue_empty_fn) (request_queue_t *); typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *); typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *); @@ -62,7 +62,7 @@ struct elevator_s */ extern void elv_add_request(request_queue_t *, struct request *, int, int); extern void __elv_add_request(request_queue_t *, struct request *, int, int); -extern int elv_merge(request_queue_t *, struct list_head **, struct bio *); +extern int elv_merge(request_queue_t *, struct request **, struct bio *); extern void elv_merge_requests(request_queue_t *, struct request *, struct request *); extern void elv_merged_request(request_queue_t *, struct request *); @@ -79,9 +79,6 @@ extern void elv_completed_request(request_queue_t *, struct request *); extern int elv_set_request(request_queue_t *, struct request *, int); extern void elv_put_request(request_queue_t *, struct request *); -#define __elv_add_request_pos(q, rq, pos) \ - (q)->elevator.elevator_add_req_fn((q), (rq), (pos)) - /* * noop I/O scheduler. always merges, always inserts new request at tail */ @@ -111,4 +108,11 @@ extern inline int elv_try_last_merge(request_queue_t *, struct bio *); #define ELEVATOR_FRONT_MERGE 1 #define ELEVATOR_BACK_MERGE 2 +/* + * Insertion selection + */ +#define ELEVATOR_INSERT_FRONT 1 +#define ELEVATOR_INSERT_BACK 2 +#define ELEVATOR_INSERT_SORT 3 + #endif -- cgit v1.2.3 From 73790646259cc3e32e60efe27c02e7c7e8fd19ec Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 4 Sep 2003 17:15:28 -0700 Subject: [PATCH] Move MODULE_ALIAS_LDISC to tty_ldisc.h MODULE_ALIAS_LDISC() is not in any way architecture-specific, so don't put it in architecture header files. Here's a patch which moves it to a more sensible location. --- include/asm-i386/termios.h | 2 -- include/asm-sparc/termios.h | 3 --- include/asm-sparc64/termios.h | 3 --- include/linux/tty_ldisc.h | 3 +++ 4 files changed, 3 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h index c0fded995489..03f548536d6b 100644 --- a/include/asm-i386/termios.h +++ b/include/asm-i386/termios.h @@ -102,8 +102,6 @@ struct termio { #define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) #define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) -#define MODULE_ALIAS_LDISC(ldisc) \ - MODULE_ALIAS("tty-ldisc-" __stringify(ldisc)) #endif /* __KERNEL__ */ #endif /* _I386_TERMIOS_H */ diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h index 48ba080c0794..0a8ad4cac125 100644 --- a/include/asm-sparc/termios.h +++ b/include/asm-sparc/termios.h @@ -169,9 +169,6 @@ struct winsize { 0; \ }) -#define MODULE_ALIAS_LDISC(ldisc) \ - MODULE_ALIAS("tty-ldisc-" __stringify(ldisc)) - #endif /* __KERNEL__ */ #endif /* _SPARC_TERMIOS_H */ diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h index 4e7fef518a25..8effce0da087 100644 --- a/include/asm-sparc64/termios.h +++ b/include/asm-sparc64/termios.h @@ -168,9 +168,6 @@ struct winsize { 0; \ }) -#define MODULE_ALIAS_LDISC(ldisc) \ - MODULE_ALIAS("tty-ldisc-" __stringify(ldisc)) - #endif /* __KERNEL__ */ #endif /* _SPARC64_TERMIOS_H */ diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index ac8ac46845ba..c851b7dc997e 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -138,4 +138,7 @@ struct tty_ldisc { #define LDISC_FLAG_DEFINED 0x00000001 +#define MODULE_ALIAS_LDISC(ldisc) \ + MODULE_ALIAS("tty-ldisc-" __stringify(ldisc)) + #endif /* _LINUX_TTY_LDISC_H */ -- cgit v1.2.3 From 968f11a8688e1be78719154d05bcab061bbfde2b Mon Sep 17 00:00:00 2001 From: Jamie Lokier Date: Thu, 4 Sep 2003 18:00:45 -0700 Subject: [PATCH] Unpinned futexes v2: indexing changes This changes the way futexes are indexed, so that they don't pin pages. It also fixes some bugs with private mappings and COW pages. Currently, all futexes look up the page at the userspace address and pin it, using the pair (page,offset) as an index into a table of waiting futexes. Any page with a futex waiting on it remains pinned in RAM, which is a problem when many futexes are used, especially with FUTEX_FD. Another problem is that the page is not always the correct one, if it can be changed later by a COW (copy on write) operation. This can happen when waiting on a futex without writing to it after fork(), exec() or mmap(), if the page is then written to before attempting to wake a futex at the same adress. There are two symptoms of the COW problem: - The wrong process can receive wakeups - A process can fail to receive required wakeups. This patch fixes both by changing the indexing so that VM_SHARED mappings use the triple (inode,offset,index), and private mappings use the pair (mm,virtual_address). The former correctly handles all shared mappings, including tmpfs and therefore all kinds of shared memory (IPC shm, /dev/shm and MAP_ANON|MAP_SHARED). This works because every mapping which is VM_SHARED has an associated non-zero vma->vm_file, and hence inode. (This is ensured in do_mmap_pgoff, where it calls shmem_zero_setup). The latter handles all private mappings, both files and anonymous. It isn't affected by COW, because it doesn't care about the actual pages, just the virtual address. The patch has a few bonuses: 1. It removes the vcache implementation, as only futexes were using it, and they don't any more. 2. Removing the vcache should make COW page faults a bit faster. 3. Futex operations no longer take the page table lock, walk the page table, fault in pages that aren't mapped in the page table, or do a vcache hash lookup - they are mostly a simple offset calculation with one hash for the futex table. So they should be noticably faster. Special thanks to Hugh Dickins, Andrew Morton and Rusty Russell for insightful feedback. All suggestions are included. --- include/linux/mm.h | 1 + include/linux/vcache.h | 26 --- kernel/futex.c | 427 ++++++++++++++++++++++++++----------------------- mm/Makefile | 2 +- mm/fremap.c | 31 +++- mm/memory.c | 2 - mm/vcache.c | 90 ----------- 7 files changed, 249 insertions(+), 330 deletions(-) delete mode 100644 include/linux/vcache.h delete mode 100644 mm/vcache.c (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 445fc58751c7..9f9743146b54 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -110,6 +110,7 @@ struct vm_area_struct { #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */ #define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */ #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ +#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS diff --git a/include/linux/vcache.h b/include/linux/vcache.h deleted file mode 100644 index 5708fe6a908a..000000000000 --- a/include/linux/vcache.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * virtual => physical mapping cache support. - */ -#ifndef _LINUX_VCACHE_H -#define _LINUX_VCACHE_H - -typedef struct vcache_s { - unsigned long address; - struct mm_struct *mm; - struct list_head hash_entry; - void (*callback)(struct vcache_s *data, struct page *new_page); -} vcache_t; - -extern spinlock_t vcache_lock; - -extern void __attach_vcache(vcache_t *vcache, - unsigned long address, - struct mm_struct *mm, - void (*callback)(struct vcache_s *data, struct page *new_page)); - -extern void __detach_vcache(vcache_t *vcache); - -extern void invalidate_vcache(unsigned long address, struct mm_struct *mm, - struct page *new_page); - -#endif diff --git a/kernel/futex.c b/kernel/futex.c index 4557addfc6d6..a4feceee661a 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -5,6 +5,9 @@ * Generalized futexes, futex requeueing, misc fixes by Ingo Molnar * (C) Copyright 2003 Red Hat Inc, All Rights Reserved * + * Removed page pinning, fix privately mapped COW pages and other cleanups + * (C) Copyright 2003 Jamie Lokier + * * Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly * enough at me, Linus for the original (flawed) idea, Matthew * Kirkwood for proof-of-concept implementation. @@ -33,11 +36,31 @@ #include #include #include -#include #include +#include #define FUTEX_HASHBITS 8 +/* + * Futexes are matched on equal values of this key. + * The key type depends on whether it's a shared or private mapping. + */ +union futex_key { + struct { + unsigned long pgoff; + struct inode *inode; + } shared; + struct { + unsigned long uaddr; + struct mm_struct *mm; + } private; + struct { + unsigned long word; + void *ptr; + } both; + int offset; +}; + /* * We use this hashed waitqueue instead of a normal wait_queue_t, so * we can wake only the relevant ones (hashed queues may be shared): @@ -46,12 +69,8 @@ struct futex_q { struct list_head list; wait_queue_head_t waiters; - /* Page struct and offset within it. */ - struct page *page; - int offset; - - /* the virtual => physical COW-safe cache */ - vcache_t vcache; + /* Key which the futex is hashed on. */ + union futex_key key; /* For fd, sigio sent using these. */ int fd; @@ -66,111 +85,149 @@ static spinlock_t futex_lock = SPIN_LOCK_UNLOCKED; static struct vfsmount *futex_mnt; /* - * These are all locks that are necessery to look up a physical - * mapping safely, and modify/search the futex hash, atomically: + * We hash on the keys returned from get_futex_key (see below). */ -static inline void lock_futex_mm(void) +static inline struct list_head *hash_futex(union futex_key *key) { - spin_lock(¤t->mm->page_table_lock); - spin_lock(&vcache_lock); - spin_lock(&futex_lock); -} - -static inline void unlock_futex_mm(void) -{ - spin_unlock(&futex_lock); - spin_unlock(&vcache_lock); - spin_unlock(¤t->mm->page_table_lock); + return &futex_queues[hash_long(key->both.word + + (unsigned long) key->both.ptr + + key->offset, FUTEX_HASHBITS)]; } /* - * The physical page is shared, so we can hash on its address: + * Return 1 if two futex_keys are equal, 0 otherwise. */ -static inline struct list_head *hash_futex(struct page *page, int offset) +static inline int match_futex(union futex_key *key1, union futex_key *key2) { - return &futex_queues[hash_long((unsigned long)page + offset, - FUTEX_HASHBITS)]; + return (key1->both.word == key2->both.word + && key1->both.ptr == key2->both.ptr + && key1->offset == key2->offset); } /* - * Get kernel address of the user page and pin it. + * Get parameters which are the keys for a futex. + * + * For shared mappings, it's (page->index, vma->vm_file->f_dentry->d_inode, + * offset_within_page). For private mappings, it's (uaddr, current->mm). + * We can usually work out the index without swapping in the page. * - * Must be called with (and returns with) all futex-MM locks held. + * Returns: 0, or negative error code. + * The key words are stored in *key on success. + * + * Should be called with ¤t->mm->mmap_sem, + * but NOT &futex_lock or ¤t->mm->page_table_lock. */ -static inline struct page *__pin_page_atomic (struct page *page) -{ - if (!PageReserved(page)) - get_page(page); - return page; -} - -static struct page *__pin_page(unsigned long addr) +static int get_futex_key(unsigned long uaddr, union futex_key *key) { struct mm_struct *mm = current->mm; - struct page *page, *tmp; + struct vm_area_struct *vma; + struct page *page; int err; /* - * Do a quick atomic lookup first - this is the fastpath. + * The futex address must be "naturally" aligned. + */ + key->offset = uaddr % PAGE_SIZE; + if (unlikely((key->offset % sizeof(u32)) != 0)) + return -EINVAL; + uaddr -= key->offset; + + /* + * The futex is hashed differently depending on whether + * it's in a shared or private mapping. So check vma first. + */ + vma = find_extend_vma(mm, uaddr); + if (unlikely(!vma)) + return -EFAULT; + + /* + * Permissions. */ - page = follow_page(mm, addr, 0); - if (likely(page != NULL)) - return __pin_page_atomic(page); + if (unlikely((vma->vm_flags & (VM_IO|VM_READ)) != VM_READ)) + return (vma->vm_flags & VM_IO) ? -EPERM : -EACCES; /* - * No luck - need to fault in the page: + * Private mappings are handled in a simple way. + * + * NOTE: When userspace waits on a MAP_SHARED mapping, even if + * it's a read-only handle, it's expected that futexes attach to + * the object not the particular process. Therefore we use + * VM_MAYSHARE here, not VM_SHARED which is restricted to shared + * mappings of _writable_ handles. */ -repeat_lookup: + if (likely(!(vma->vm_flags & VM_MAYSHARE))) { + key->private.mm = mm; + key->private.uaddr = uaddr; + return 0; + } - unlock_futex_mm(); + /* + * Linear mappings are also simple. + */ + key->shared.inode = vma->vm_file->f_dentry->d_inode; + if (likely(!(vma->vm_flags & VM_NONLINEAR))) { + key->shared.pgoff = (((uaddr - vma->vm_start) >> PAGE_SHIFT) + + vma->vm_pgoff); + return 0; + } - down_read(&mm->mmap_sem); - err = get_user_pages(current, mm, addr, 1, 0, 0, &page, NULL); - up_read(&mm->mmap_sem); + /* + * We could walk the page table to read the non-linear + * pte, and get the page index without fetching the page + * from swap. But that's a lot of code to duplicate here + * for a rare case, so we simply fetch the page. + */ - lock_futex_mm(); + /* + * Do a quick atomic lookup first - this is the fastpath. + */ + spin_lock(¤t->mm->page_table_lock); + page = follow_page(mm, uaddr, 0); + if (likely(page != NULL)) { + key->shared.pgoff = + page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); + spin_unlock(¤t->mm->page_table_lock); + return 0; + } + spin_unlock(¤t->mm->page_table_lock); - if (err < 0) - return NULL; /* - * Since the faulting happened with locks released, we have to - * check for races: + * Do it the general way. */ - tmp = follow_page(mm, addr, 0); - if (tmp != page) { + err = get_user_pages(current, mm, uaddr, 1, 0, 0, &page, NULL); + if (err >= 0) { + key->shared.pgoff = + page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); put_page(page); - goto repeat_lookup; } - - return page; + return err; } + /* * Wake up all waiters hashed on the physical page that is mapped * to this virtual address: */ -static inline int futex_wake(unsigned long uaddr, int offset, int num) +static inline int futex_wake(unsigned long uaddr, int num) { struct list_head *i, *next, *head; - struct page *page; - int ret = 0; + union futex_key key; + int ret; - lock_futex_mm(); + down_read(¤t->mm->mmap_sem); - page = __pin_page(uaddr - offset); - if (!page) { - unlock_futex_mm(); - return -EFAULT; - } + ret = get_futex_key(uaddr, &key); + if (unlikely(ret != 0)) + goto out; - head = hash_futex(page, offset); + head = hash_futex(&key); + spin_lock(&futex_lock); list_for_each_safe(i, next, head) { struct futex_q *this = list_entry(i, struct futex_q, list); - if (this->page == page && this->offset == offset) { + if (match_futex (&this->key, &key)) { list_del_init(i); - __detach_vcache(&this->vcache); wake_up_all(&this->waiters); if (this->filp) send_sigio(&this->filp->f_owner, this->fd, POLL_IN); @@ -179,113 +236,74 @@ static inline int futex_wake(unsigned long uaddr, int offset, int num) break; } } + spin_unlock(&futex_lock); - unlock_futex_mm(); - put_page(page); - +out: + up_read(¤t->mm->mmap_sem); return ret; } -/* - * This gets called by the COW code, we have to rehash any - * futexes that were pending on the old physical page, and - * rehash it to the new physical page. The pagetable_lock - * and vcache_lock is already held: - */ -static void futex_vcache_callback(vcache_t *vcache, struct page *new_page) -{ - struct futex_q *q = container_of(vcache, struct futex_q, vcache); - struct list_head *head = hash_futex(new_page, q->offset); - - spin_lock(&futex_lock); - - if (!list_empty(&q->list)) { - put_page(q->page); - q->page = new_page; - __pin_page_atomic(new_page); - list_del(&q->list); - list_add_tail(&q->list, head); - } - - spin_unlock(&futex_lock); -} - /* * Requeue all waiters hashed on one physical page to another * physical page. */ -static inline int futex_requeue(unsigned long uaddr1, int offset1, - unsigned long uaddr2, int offset2, int nr_wake, int nr_requeue) +static inline int futex_requeue(unsigned long uaddr1, unsigned long uaddr2, + int nr_wake, int nr_requeue) { struct list_head *i, *next, *head1, *head2; - struct page *page1 = NULL, *page2 = NULL; - int ret = 0; + union futex_key key1, key2; + int ret; - lock_futex_mm(); + down_read(¤t->mm->mmap_sem); - page1 = __pin_page(uaddr1 - offset1); - if (!page1) + ret = get_futex_key(uaddr1, &key1); + if (unlikely(ret != 0)) goto out; - page2 = __pin_page(uaddr2 - offset2); - if (!page2) + ret = get_futex_key(uaddr2, &key2); + if (unlikely(ret != 0)) goto out; - head1 = hash_futex(page1, offset1); - head2 = hash_futex(page2, offset2); + head1 = hash_futex(&key1); + head2 = hash_futex(&key2); + spin_lock(&futex_lock); list_for_each_safe(i, next, head1) { struct futex_q *this = list_entry(i, struct futex_q, list); - if (this->page == page1 && this->offset == offset1) { + if (match_futex (&this->key, &key1)) { list_del_init(i); - __detach_vcache(&this->vcache); if (++ret <= nr_wake) { wake_up_all(&this->waiters); if (this->filp) send_sigio(&this->filp->f_owner, this->fd, POLL_IN); } else { - put_page(this->page); - __pin_page_atomic (page2); list_add_tail(i, head2); - __attach_vcache(&this->vcache, uaddr2, - current->mm, futex_vcache_callback); - this->offset = offset2; - this->page = page2; + this->key = key2; if (ret - nr_wake >= nr_requeue) break; } } } + spin_unlock(&futex_lock); out: - unlock_futex_mm(); - - if (page1) - put_page(page1); - if (page2) - put_page(page2); - + up_read(¤t->mm->mmap_sem); return ret; } -static inline void __queue_me(struct futex_q *q, struct page *page, - unsigned long uaddr, int offset, - int fd, struct file *filp) +static inline void queue_me(struct futex_q *q, union futex_key *key, + int fd, struct file *filp) { - struct list_head *head = hash_futex(page, offset); + struct list_head *head = hash_futex(key); - q->offset = offset; + q->key = *key; q->fd = fd; q->filp = filp; - q->page = page; + spin_lock(&futex_lock); list_add_tail(&q->list, head); - /* - * We register a futex callback to this virtual address, - * to make sure a COW properly rehashes the futex-queue. - */ - __attach_vcache(&q->vcache, uaddr, current->mm, futex_vcache_callback); + spin_unlock(&futex_lock); } /* Return 1 if we were still queued (ie. 0 means we were woken) */ @@ -293,83 +311,107 @@ static inline int unqueue_me(struct futex_q *q) { int ret = 0; - spin_lock(&vcache_lock); spin_lock(&futex_lock); if (!list_empty(&q->list)) { list_del(&q->list); - __detach_vcache(&q->vcache); ret = 1; } spin_unlock(&futex_lock); - spin_unlock(&vcache_lock); return ret; } -static inline int futex_wait(unsigned long uaddr, - int offset, - int val, - unsigned long time) +static inline int futex_wait(unsigned long uaddr, int val, unsigned long time) { DECLARE_WAITQUEUE(wait, current); - int ret = 0, curval; - struct page *page; + int ret, curval; + union futex_key key; struct futex_q q; + try_again: init_waitqueue_head(&q.waiters); - lock_futex_mm(); + down_read(¤t->mm->mmap_sem); - page = __pin_page(uaddr - offset); - if (!page) { - unlock_futex_mm(); - return -EFAULT; - } - __queue_me(&q, page, uaddr, offset, -1, NULL); + ret = get_futex_key(uaddr, &key); + if (unlikely(ret != 0)) + goto out_release_sem; + + queue_me(&q, &key, -1, NULL); /* - * Page is pinned, but may no longer be in this address space. - * It cannot schedule, so we access it with the spinlock held. + * Access the page after the futex is queued. + * We hold the mmap semaphore, so the mapping cannot have changed + * since we looked it up. */ if (get_user(curval, (int *)uaddr) != 0) { - unlock_futex_mm(); ret = -EFAULT; - goto out; + goto out_unqueue; } if (curval != val) { - unlock_futex_mm(); ret = -EWOULDBLOCK; - goto out; + goto out_unqueue; } + + /* + * Now the futex is queued and we have checked the data, we + * don't want to hold mmap_sem while we sleep. + */ + up_read(¤t->mm->mmap_sem); + /* - * The get_user() above might fault and schedule so we - * cannot just set TASK_INTERRUPTIBLE state when queueing - * ourselves into the futex hash. This code thus has to + * There might have been scheduling since the queue_me(), as we + * cannot hold a spinlock across the get_user() in case it + * faults. So we cannot just set TASK_INTERRUPTIBLE state when + * queueing ourselves into the futex hash. This code thus has to * rely on the futex_wake() code doing a wakeup after removing * the waiter from the list. */ add_wait_queue(&q.waiters, &wait); + spin_lock(&futex_lock); set_current_state(TASK_INTERRUPTIBLE); - if (!list_empty(&q.list)) { - unlock_futex_mm(); - time = schedule_timeout(time); + + if (unlikely(list_empty(&q.list))) { + /* + * We were woken already. + */ + spin_unlock(&futex_lock); + set_current_state(TASK_RUNNING); + return 0; } + + spin_unlock(&futex_lock); + time = schedule_timeout(time); set_current_state(TASK_RUNNING); + /* * NOTE: we don't remove ourselves from the waitqueue because * we are the only user of it. */ - if (time == 0) { - ret = -ETIMEDOUT; - goto out; - } + + /* + * Were we woken or interrupted for a valid reason? + */ + ret = unqueue_me(&q); + if (ret == 0) + return 0; + if (time == 0) + return -ETIMEDOUT; if (signal_pending(current)) - ret = -EINTR; -out: - /* Were we woken up anyway? */ + return -EINTR; + + /* + * No, it was a spurious wakeup. Try again. Should never happen. :) + */ + goto try_again; + + out_unqueue: + /* + * Were we unqueued anyway? + */ if (!unqueue_me(&q)) ret = 0; - put_page(q.page); - + out_release_sem: + up_read(¤t->mm->mmap_sem); return ret; } @@ -378,7 +420,6 @@ static int futex_close(struct inode *inode, struct file *filp) struct futex_q *q = filp->private_data; unqueue_me(q); - put_page(q->page); kfree(filp->private_data); return 0; } @@ -406,12 +447,12 @@ static struct file_operations futex_fops = { /* Signal allows caller to avoid the race which would occur if they set the sigio stuff up afterwards. */ -static int futex_fd(unsigned long uaddr, int offset, int signal) +static int futex_fd(unsigned long uaddr, int signal) { - struct page *page = NULL; struct futex_q *q; + union futex_key key; struct file *filp; - int ret; + int ret, err; ret = -EINVAL; if (signal < 0 || signal > _NSIG) @@ -450,69 +491,47 @@ static int futex_fd(unsigned long uaddr, int offset, int signal) goto out; } - lock_futex_mm(); - - page = __pin_page(uaddr - offset); - if (!page) { - unlock_futex_mm(); + down_read(¤t->mm->mmap_sem); + err = get_futex_key(uaddr, &key); + up_read(¤t->mm->mmap_sem); + if (unlikely(err != 0)) { put_unused_fd(ret); put_filp(filp); kfree(q); - return -EFAULT; + return err; } init_waitqueue_head(&q->waiters); filp->private_data = q; - __queue_me(q, page, uaddr, offset, ret, filp); - - unlock_futex_mm(); + queue_me(q, &key, ret, filp); /* Now we map fd to filp, so userspace can access it */ fd_install(ret, filp); - page = NULL; out: - if (page) - put_page(page); return ret; } long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout, unsigned long uaddr2, int val2) { - unsigned long pos_in_page; int ret; - pos_in_page = uaddr % PAGE_SIZE; - - /* Must be "naturally" aligned */ - if (pos_in_page % sizeof(u32)) - return -EINVAL; - switch (op) { case FUTEX_WAIT: - ret = futex_wait(uaddr, pos_in_page, val, timeout); + ret = futex_wait(uaddr, val, timeout); break; case FUTEX_WAKE: - ret = futex_wake(uaddr, pos_in_page, val); + ret = futex_wake(uaddr, val); break; case FUTEX_FD: /* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */ - ret = futex_fd(uaddr, pos_in_page, val); + ret = futex_fd(uaddr, val); break; case FUTEX_REQUEUE: - { - unsigned long pos_in_page2 = uaddr2 % PAGE_SIZE; - - /* Must be "naturally" aligned */ - if (pos_in_page2 % sizeof(u32)) - return -EINVAL; - - ret = futex_requeue(uaddr, pos_in_page, uaddr2, pos_in_page2, - val, val2); + ret = futex_requeue(uaddr, uaddr2, val, val2); break; - } default: ret = -ENOSYS; } diff --git a/mm/Makefile b/mm/Makefile index a8de64ff3525..c66aba5886f8 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -9,6 +9,6 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ page_alloc.o page-writeback.o pdflush.o readahead.o \ - slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y) + slab.o swap.o truncate.o vmscan.o $(mmu-y) obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o diff --git a/mm/fremap.c b/mm/fremap.c index 8f96af82b4e8..b19bdde07bb6 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -144,9 +144,10 @@ long sys_remap_file_pages(unsigned long start, unsigned long size, return err; #endif - down_read(&mm->mmap_sem); - + /* We need down_write() to change vma->vm_flags. */ + down_write(&mm->mmap_sem); vma = find_vma(mm, start); + /* * Make sure the vma is shared, that it supports prefaulting, * and that the remapped range is valid and fully within @@ -155,11 +156,27 @@ long sys_remap_file_pages(unsigned long start, unsigned long size, if (vma && (vma->vm_flags & VM_SHARED) && vma->vm_ops && vma->vm_ops->populate && end > start && start >= vma->vm_start && - end <= vma->vm_end) - err = vma->vm_ops->populate(vma, start, size, vma->vm_page_prot, - pgoff, flags & MAP_NONBLOCK); - - up_read(&mm->mmap_sem); + end <= vma->vm_end) { + + /* Must set VM_NONLINEAR before any pages are populated. */ + if (pgoff != ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff) + vma->vm_flags |= VM_NONLINEAR; + + /* ->populate can take a long time, so downgrade the lock. */ + downgrade_write(&mm->mmap_sem); + err = vma->vm_ops->populate(vma, start, size, + vma->vm_page_prot, + pgoff, flags & MAP_NONBLOCK); + + /* + * We can't clear VM_NONLINEAR because we'd have to do + * it after ->populate completes, and that would prevent + * downgrading the lock. (Locks can't be upgraded). + */ + up_read(&mm->mmap_sem); + } else { + up_write(&mm->mmap_sem); + } return err; } diff --git a/mm/memory.c b/mm/memory.c index 61b782f40df9..980953dbbfb4 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -962,7 +961,6 @@ static inline void establish_pte(struct vm_area_struct * vma, unsigned long addr static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address, pte_t *page_table) { - invalidate_vcache(address, vma->vm_mm, new_page); flush_cache_page(vma, address); establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)))); } diff --git a/mm/vcache.c b/mm/vcache.c deleted file mode 100644 index 599e0f25490d..000000000000 --- a/mm/vcache.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * linux/mm/vcache.c - * - * virtual => physical page mapping cache. Users of this mechanism - * register callbacks for a given (virt,mm,phys) page mapping, and - * the kernel guarantees to call back when this mapping is invalidated. - * (ie. upon COW or unmap.) - * - * Started by Ingo Molnar, Copyright (C) 2002 - */ - -#include -#include -#include -#include - -#define VCACHE_HASHBITS 8 -#define VCACHE_HASHSIZE (1 << VCACHE_HASHBITS) - -spinlock_t vcache_lock = SPIN_LOCK_UNLOCKED; - -static struct list_head hash[VCACHE_HASHSIZE]; - -static struct list_head *hash_vcache(unsigned long address, - struct mm_struct *mm) -{ - return &hash[hash_long(address + (unsigned long)mm, VCACHE_HASHBITS)]; -} - -void __attach_vcache(vcache_t *vcache, - unsigned long address, - struct mm_struct *mm, - void (*callback)(struct vcache_s *data, struct page *new)) -{ - struct list_head *hash_head; - - address &= PAGE_MASK; - vcache->address = address; - vcache->mm = mm; - vcache->callback = callback; - - hash_head = hash_vcache(address, mm); - - list_add_tail(&vcache->hash_entry, hash_head); -} - -void __detach_vcache(vcache_t *vcache) -{ - list_del_init(&vcache->hash_entry); -} - -void invalidate_vcache(unsigned long address, struct mm_struct *mm, - struct page *new_page) -{ - struct list_head *l, *hash_head; - vcache_t *vcache; - - address &= PAGE_MASK; - - hash_head = hash_vcache(address, mm); - /* - * This is safe, because this path is called with the pagetable - * lock held. So while other mm's might add new entries in - * parallel, *this* mm is locked out, so if the list is empty - * now then we do not have to take the vcache lock to see it's - * really empty. - */ - if (likely(list_empty(hash_head))) - return; - - spin_lock(&vcache_lock); - list_for_each(l, hash_head) { - vcache = list_entry(l, vcache_t, hash_entry); - if (vcache->address != address || vcache->mm != mm) - continue; - vcache->callback(vcache, new_page); - } - spin_unlock(&vcache_lock); -} - -static int __init vcache_init(void) -{ - unsigned int i; - - for (i = 0; i < VCACHE_HASHSIZE; i++) - INIT_LIST_HEAD(hash + i); - return 0; -} -__initcall(vcache_init); - -- cgit v1.2.3 From 25a6ca892403f9d5dc2e1ed28db13e31b9fea2d2 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Thu, 4 Sep 2003 20:53:47 -0700 Subject: [PATCH] large dev_t - second series (5/15) cdevname() killed, there was only one remaining user (tty_paranoia_check()) and in that case cdevname() was worse than plain major:minor (basically, it's "you've got corrupted inode that was supposed to belong to tty device; here's what I'd found in ->i_rdev") --- drivers/char/tty_io.c | 13 ++++++------- fs/char_dev.c | 21 --------------------- include/linux/fs.h | 1 - kernel/ksyms.c | 1 - 4 files changed, 6 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 5b4693c5f990..83640a923209 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -181,17 +181,16 @@ inline int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, const char *routine) { #ifdef TTY_PARANOIA_CHECK - static const char badmagic[] = KERN_WARNING - "Warning: bad magic number for tty struct (%s) in %s\n"; - static const char badtty[] = KERN_WARNING - "Warning: null TTY for (%s) in %s\n"; - if (!tty) { - printk(badtty, cdevname(inode->i_rdev), routine); + printk(KERN_WARNING + "null TTY for (%d:%d) in %s\n", + imajor(inode), iminor(inode), routine); return 1; } if (tty->magic != TTY_MAGIC) { - printk(badmagic, cdevname(inode->i_rdev), routine); + printk(KERN_WARNING + "bad magic number for tty struct (%d:%d) in %s\n", + imajor(inode), iminor(inode), routine); return 1; } #endif diff --git a/fs/char_dev.c b/fs/char_dev.c index 3c6258c73384..e41bf7caa5ee 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -328,27 +328,6 @@ struct file_operations def_chr_fops = { .open = chrdev_open, }; -const char *cdevname(kdev_t dev) -{ - static char buffer[40]; - const char *name = "unknown-char"; - unsigned int major = major(dev); - unsigned int minor = minor(dev); - int i = major_to_index(major); - struct char_device_struct *cd; - - read_lock(&chrdevs_lock); - for (cd = chrdevs[i]; cd; cd = cd->next) - if (cd->major == major) - break; - if (cd) - name = cd->name; - sprintf(buffer, "%s(%d,%d)", name, major, minor); - read_unlock(&chrdevs_lock); - - return buffer; -} - static struct kobject *exact_match(dev_t dev, int *part, void *data) { struct cdev *p = data; diff --git a/include/linux/fs.h b/include/linux/fs.h index 87ae270bf96c..fa2bd2dd7600 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1156,7 +1156,6 @@ extern struct block_device *lookup_bdev(const char *); extern struct block_device *open_bdev_excl(const char *, int, int, void *); extern void close_bdev_excl(struct block_device *, int); -extern const char * cdevname(kdev_t); extern void init_special_inode(struct inode *, umode_t, dev_t); /* Invalid inode operations -- fs/bad_inode.c */ diff --git a/kernel/ksyms.c b/kernel/ksyms.c index e503bd8b0349..9f61a0496c2a 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -511,7 +511,6 @@ EXPORT_SYMBOL(vsnprintf); EXPORT_SYMBOL(vsscanf); EXPORT_SYMBOL(__bdevname); EXPORT_SYMBOL(bdevname); -EXPORT_SYMBOL(cdevname); EXPORT_SYMBOL(simple_strtoull); EXPORT_SYMBOL(simple_strtoul); EXPORT_SYMBOL(simple_strtol); -- cgit v1.2.3 From cbac67b10e48a7a76485d405fc723084fdafb6a1 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Thu, 4 Sep 2003 20:53:56 -0700 Subject: [PATCH] large dev_t - second series (6/15) tty redirect handling sanitized. Such ttys (/dev/tty and /dev/console) get a different file_operations; its ->write() handles redirects; checks for file->f_op == &tty_fops updated, checks for major:minor being that of a redirector replaced with check for ->f_op->write value. Piece of code in tty_io.c that had been #if 0 since 0.99 had been finally put out of its misery. kdev_val() is gone. --- drivers/char/n_tty.c | 13 ++--- drivers/char/tty_io.c | 126 ++++++++++++++++++++++--------------------------- include/linux/kdev_t.h | 10 ---- 3 files changed, 61 insertions(+), 88 deletions(-) (limited to 'include/linux') diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 883066efbd72..6cc938bbbf30 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -50,9 +50,6 @@ #include #include -#define IS_CONSOLE_DEV(dev) (kdev_val(dev) == __mkdev(TTY_MAJOR,0)) -#define IS_SYSCONS_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,1)) - /* number of characters left in xmit buffer before select has we have room */ #define WAKEUP_CHARS 256 @@ -951,6 +948,8 @@ static inline int copy_from_read_buf(struct tty_struct *tty, return retval; } +extern ssize_t redirected_tty_write(struct file *,const char *,size_t,loff_t *); + static ssize_t read_chan(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr) { @@ -975,9 +974,7 @@ do_it_again: /* NOTE: not yet done after every sleep pending a thorough check of the logic of this change. -- jlc */ /* don't stop on /dev/console */ - if (!IS_CONSOLE_DEV(file->f_dentry->d_inode->i_rdev) && - !IS_SYSCONS_DEV(file->f_dentry->d_inode->i_rdev) && - current->tty == tty) { + if (file->f_op->write != redirected_tty_write && current->tty == tty) { if (tty->pgrp <= 0) printk("read_chan: tty->pgrp <= 0!\n"); else if (current->pgrp != tty->pgrp) { @@ -1168,9 +1165,7 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file, ssize_t retval = 0; /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */ - if (L_TOSTOP(tty) && - !IS_CONSOLE_DEV(file->f_dentry->d_inode->i_rdev) && - !IS_SYSCONS_DEV(file->f_dentry->d_inode->i_rdev)) { + if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) { retval = tty_check_change(tty); if (retval) return retval; diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 83640a923209..a1888c4dc0d9 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -103,11 +103,6 @@ #include -#define IS_CONSOLE_DEV(dev) (kdev_val(dev) == __mkdev(TTY_MAJOR,0)) -#define IS_TTY_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,0)) -#define IS_SYSCONS_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,1)) -#define IS_PTMX_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,2)) - #undef TTY_DEBUG_HANGUP #define TTY_PARANOIA_CHECK 1 @@ -136,6 +131,7 @@ static void initialize_tty_struct(struct tty_struct *tty); static ssize_t tty_read(struct file *, char *, size_t, loff_t *); static ssize_t tty_write(struct file *, const char *, size_t, loff_t *); +ssize_t redirected_tty_write(struct file *, const char *, size_t, loff_t *); static unsigned int tty_poll(struct file *, poll_table *); static int tty_open(struct inode *, struct file *); static int tty_release(struct inode *, struct file *); @@ -382,6 +378,17 @@ static struct file_operations tty_fops = { .fasync = tty_fasync, }; +static struct file_operations console_fops = { + .llseek = no_llseek, + .read = tty_read, + .write = redirected_tty_write, + .poll = tty_poll, + .ioctl = tty_ioctl, + .open = tty_open, + .release = tty_release, + .fasync = tty_fasync, +}; + static struct file_operations hung_up_tty_fops = { .llseek = no_llseek, .read = hung_up_tty_read, @@ -425,12 +432,9 @@ void do_tty_hangup(void *data) check_tty_count(tty, "do_tty_hangup"); file_list_lock(); list_for_each_entry(filp, &tty->tty_files, f_list) { - if (IS_CONSOLE_DEV(filp->f_dentry->d_inode->i_rdev) || - IS_SYSCONS_DEV(filp->f_dentry->d_inode->i_rdev)) { + if (filp->f_op->write == redirected_tty_write) cons_filp = filp; - continue; - } - if (filp->f_op != &tty_fops) + if (filp->f_op->write != tty_write) continue; closecount++; tty_fasync(-1, filp, 0); /* can't block */ @@ -650,22 +654,6 @@ static ssize_t tty_read(struct file * file, char * buf, size_t count, if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) return -EIO; - /* This check not only needs to be done before reading, but also - whenever read_chan() gets woken up after sleeping, so I've - moved it to there. This should only be done for the N_TTY - line discipline, anyway. Same goes for write_chan(). -- jlc. */ -#if 0 - if (!IS_CONSOLE_DEV(inode->i_rdev) && /* don't stop on /dev/console */ - (tty->pgrp > 0) && - (current->tty == tty) && - (tty->pgrp != current->pgrp)) - if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp)) - return -EIO; - else { - (void) kill_pg(current->pgrp, SIGTTIN, 1); - return -ERESTARTSYS; - } -#endif lock_kernel(); if (tty->ldisc.read) i = (tty->ldisc.read)(tty,file,buf,count); @@ -730,37 +718,13 @@ static inline ssize_t do_tty_write( static ssize_t tty_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { - int is_console; struct tty_struct * tty; struct inode *inode = file->f_dentry->d_inode; - /* - * For now, we redirect writes from /dev/console as - * well as /dev/tty0. - */ - is_console = IS_SYSCONS_DEV(inode->i_rdev) || - IS_CONSOLE_DEV(inode->i_rdev); /* Can't seek (pwrite) on ttys. */ if (ppos != &file->f_pos) return -ESPIPE; - if (is_console) { - struct file *p = NULL; - - spin_lock(&redirect_lock); - if (redirect) { - get_file(redirect); - p = redirect; - } - spin_unlock(&redirect_lock); - - if (p) { - ssize_t res = vfs_write(p, buf, count, &p->f_pos); - fput(p); - return res; - } - } - tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode, "tty_write")) return -EIO; @@ -772,6 +736,31 @@ static ssize_t tty_write(struct file * file, const char * buf, size_t count, (const unsigned char *)buf, count); } +ssize_t redirected_tty_write(struct file * file, const char * buf, size_t count, + loff_t *ppos) +{ + struct file *p = NULL; + + spin_lock(&redirect_lock); + if (redirect) { + get_file(redirect); + p = redirect; + } + spin_unlock(&redirect_lock); + + if (p) { + ssize_t res; + /* Can't seek (pwrite) on ttys. */ + if (ppos != &file->f_pos) + return -ESPIPE; + res = vfs_write(p, buf, count, &p->f_pos); + fput(p); + return res; + } + + return tty_write(file, buf, count, ppos); +} + /* Semaphore to protect creating and releasing a tty */ static DECLARE_MUTEX(tty_sem); @@ -1306,14 +1295,11 @@ static int tty_open(struct inode * inode, struct file * filp) int noctty, retval; struct tty_driver *driver; int index; - kdev_t device; - unsigned short saved_flags; - - saved_flags = filp->f_flags; + dev_t device = kdev_t_to_nr(inode->i_rdev); + unsigned short saved_flags = filp->f_flags; retry_open: noctty = filp->f_flags & O_NOCTTY; - device = inode->i_rdev; - if (IS_TTY_DEV(device)) { + if (device == MKDEV(TTYAUX_MAJOR,0)) { if (!current->tty) return -ENXIO; driver = current->tty->driver; @@ -1323,7 +1309,7 @@ retry_open: goto got_driver; } #ifdef CONFIG_VT - if (IS_CONSOLE_DEV(device)) { + if (device == MKDEV(TTY_MAJOR,0)) { extern int fg_console; extern struct tty_driver *console_driver; driver = console_driver; @@ -1332,7 +1318,7 @@ retry_open: goto got_driver; } #endif - if (IS_SYSCONS_DEV(device)) { + if (device == MKDEV(TTYAUX_MAJOR,1)) { struct console *c = console_drivers; for (c = console_drivers; c; c = c->next) { if (!c->device) @@ -1348,7 +1334,7 @@ retry_open: return -ENODEV; } - if (IS_PTMX_DEV(device)) { + if (device == MKDEV(TTYAUX_MAJOR,2)) { #ifdef CONFIG_UNIX98_PTYS /* find a device that is not in use. */ retval = -1; @@ -1365,7 +1351,7 @@ retry_open: return -ENODEV; #endif /* CONFIG_UNIX_98_PTYS */ } else { - driver = get_tty_driver(kdev_t_to_nr(device), &index); + driver = get_tty_driver(device, &index); if (!driver) return -ENODEV; got_driver: @@ -1407,7 +1393,8 @@ got_driver: /* * Need to reset f_op in case a hangup happened. */ - filp->f_op = &tty_fops; + if (filp->f_op == &hung_up_tty_fops) + filp->f_op = &tty_fops; goto retry_open; } if (!noctty && @@ -1516,10 +1503,9 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, return 0; } -static int tioccons(struct inode *inode, struct file *file) +static int tioccons(struct file *file) { - if (IS_SYSCONS_DEV(inode->i_rdev) || - IS_CONSOLE_DEV(inode->i_rdev)) { + if (file->f_op->write == redirected_tty_write) { struct file *f; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1786,7 +1772,7 @@ int tty_ioctl(struct inode * inode, struct file * file, case TIOCSWINSZ: return tiocswinsz(tty, real_tty, (struct winsize *) arg); case TIOCCONS: - return real_tty!=tty ? -EINVAL : tioccons(inode, file); + return real_tty!=tty ? -EINVAL : tioccons(file); case FIONBIO: return fionbio(file, (int *) arg); case TIOCEXCL: @@ -1917,8 +1903,10 @@ static void __do_SAK(void *arg) spin_lock(&p->files->file_lock); for (i=0; i < p->files->max_fds; i++) { filp = fcheck_files(p->files, i); - if (filp && (filp->f_op == &tty_fops) && - (filp->private_data == tty)) { + if (!filp) + continue; + if (filp->f_op->read == tty_read && + filp->private_data == tty) { printk(KERN_NOTICE "SAK: killed process %d" " (%s): fd#%d opened to the tty\n", p->pid, p->comm, i); @@ -2446,7 +2434,7 @@ void __init tty_init(void) tty_add_class_device ("tty", MKDEV(TTYAUX_MAJOR, 0), NULL); strcpy(console_cdev.kobj.name, "dev.console"); - cdev_init(&console_cdev, &tty_fops); + cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn't register /dev/console driver\n"); @@ -2468,7 +2456,7 @@ void __init tty_init(void) #ifdef CONFIG_VT strcpy(vc0_cdev.kobj.name, "dev.vc0"); - cdev_init(&vc0_cdev, &tty_fops); + cdev_init(&vc0_cdev, &console_fops); if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) panic("Couldn't register /dev/tty0 driver\n"); diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h index 900a4a1e1282..64a88b3b194a 100644 --- a/include/linux/kdev_t.h +++ b/include/linux/kdev_t.h @@ -80,16 +80,6 @@ typedef struct { #define mk_kdev(major, minor) ((kdev_t) { __mkdev(major,minor) } ) -/* - * The "values" are just _cookies_, usable for - * internal equality comparisons and for things - * like NFS filehandle conversion. - */ -static inline unsigned int kdev_val(kdev_t dev) -{ - return dev.value; -} - #define NODEV (mk_kdev(0,0)) /* Mask off the high bits for now.. */ -- cgit v1.2.3 From ad1da81a8a2acf7ceda4e8aa67e159ff223dc337 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Thu, 4 Sep 2003 20:54:08 -0700 Subject: [PATCH] large dev_t - second series (7/15) the last kdev_t object is gone; ->i_rdev switched to dev_t. --- drivers/char/tty_io.c | 2 +- drivers/md/dm-table.c | 2 +- fs/block_dev.c | 4 ++-- fs/char_dev.c | 2 +- fs/cifs/file.c | 4 ++-- fs/cifs/inode.c | 4 ++-- fs/devfs/base.c | 4 ++-- fs/ext2/inode.c | 2 +- fs/ext3/inode.c | 2 +- fs/hpfs/inode.c | 2 +- fs/inode.c | 6 +++--- fs/intermezzo/vfs.c | 2 +- fs/isofs/inode.c | 3 +-- fs/isofs/rock.c | 4 ++-- fs/jffs2/super.c | 6 +++--- fs/jfs/inode.c | 3 +-- fs/jfs/jfs_imap.c | 4 ++-- fs/minix/inode.c | 4 ++-- fs/nfsd/nfsproc.c | 4 ++-- fs/reiserfs/inode.c | 4 ++-- fs/stat.c | 2 +- fs/sysv/inode.c | 2 +- fs/udf/inode.c | 4 ++-- fs/ufs/inode.c | 2 +- fs/xfs/linux/xfs_iops.c | 2 +- fs/xfs/linux/xfs_super.c | 4 ++-- fs/xfs/xfs_types.h | 2 +- fs/xfs/xfsidbg.c | 2 +- include/linux/fs.h | 6 +++--- 29 files changed, 46 insertions(+), 48 deletions(-) (limited to 'include/linux') diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index a1888c4dc0d9..8d1f8c6d3c23 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1295,7 +1295,7 @@ static int tty_open(struct inode * inode, struct file * filp) int noctty, retval; struct tty_driver *driver; int index; - dev_t device = kdev_t_to_nr(inode->i_rdev); + dev_t device = inode->i_rdev; unsigned short saved_flags = filp->f_flags; retry_open: noctty = filp->f_flags & O_NOCTTY; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 5d0e4c662599..aae61522d1f7 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -312,7 +312,7 @@ static int lookup_device(const char *path, dev_t *dev) goto out; } - *dev = kdev_t_to_nr(inode->i_rdev); + *dev = inode->i_rdev; out: path_release(&nd); diff --git a/fs/block_dev.c b/fs/block_dev.c index ddfcb6284b5a..e08095251aab 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -345,7 +345,7 @@ struct block_device *bdget(dev_t dev) bdev->bd_part_count = 0; bdev->bd_invalidated = 0; inode->i_mode = S_IFBLK; - inode->i_rdev = to_kdev_t(dev); + inode->i_rdev = dev; inode->i_bdev = bdev; inode->i_data.a_ops = &def_blk_aops; mapping_set_gfp_mask(&inode->i_data, GFP_USER); @@ -386,7 +386,7 @@ int bd_acquire(struct inode *inode) return 0; } spin_unlock(&bdev_lock); - bdev = bdget(kdev_t_to_nr(inode->i_rdev)); + bdev = bdget(inode->i_rdev); if (!bdev) return -ENOMEM; spin_lock(&bdev_lock); diff --git a/fs/char_dev.c b/fs/char_dev.c index e41bf7caa5ee..44303f85e624 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -265,7 +265,7 @@ int chrdev_open(struct inode * inode, struct file * filp) struct kobject *kobj; int idx; spin_unlock(&cdev_lock); - kobj = kobj_lookup(cdev_map, kdev_t_to_nr(inode->i_rdev), &idx); + kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx); if (!kobj) return -ENODEV; new = container_of(kobj, struct cdev, kobj); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 247a39b899b3..5e223961e9fb 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1024,7 +1024,7 @@ fill_in_inode(struct inode *tmp_inode, } else { cFYI(1, (" Init special inode ")); init_special_inode(tmp_inode, tmp_inode->i_mode, - kdev_t_to_nr(tmp_inode->i_rdev)); + tmp_inode->i_rdev); } } @@ -1094,7 +1094,7 @@ unix_fill_in_inode(struct inode *tmp_inode, } else { cFYI(1, (" Init special inode ")); init_special_inode(tmp_inode, tmp_inode->i_mode, - kdev_t_to_nr(tmp_inode->i_rdev)); + tmp_inode->i_rdev); } } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 3625916ca351..6524d6d1f883 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -154,7 +154,7 @@ cifs_get_inode_info_unix(struct inode **pinode, } else { cFYI(1, (" Init special inode ")); init_special_inode(inode, inode->i_mode, - kdev_t_to_nr(inode->i_rdev)); + inode->i_rdev); } } FreeXid(xid); @@ -298,7 +298,7 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, inode->i_op = &cifs_symlink_inode_ops; } else { init_special_inode(inode, inode->i_mode, - kdev_t_to_nr(inode->i_rdev)); + inode->i_rdev); } } if(buf) diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 3df3c5dc1697..fda21d6af987 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -2012,11 +2012,11 @@ static struct inode *_devfs_get_vfs_inode (struct super_block *sb, inode->i_fop = &devfs_fops; if ( S_ISCHR (de->mode) ) { - inode->i_rdev = to_kdev_t(de->u.cdev.dev); + inode->i_rdev = de->u.cdev.dev; } else if ( S_ISBLK (de->mode) ) { - inode->i_rdev = to_kdev_t(de->u.bdev.dev); + inode->i_rdev = de->u.bdev.dev; if (bd_acquire (inode) != 0) PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino); } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 8a009a159469..c9d6cf4a3869 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1216,7 +1216,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync) raw_inode->i_generation = cpu_to_le32(inode->i_generation); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev)); + raw_inode->i_block[0] = cpu_to_le32(inode->i_rdev); else for (n = 0; n < EXT2_N_BLOCKS; n++) raw_inode->i_block[n] = ei->i_data[n]; mark_buffer_dirty(bh); diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 84f41589a02a..24bd9d1fc7de 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -2668,7 +2668,7 @@ static int ext3_do_update_inode(handle_t *handle, raw_inode->i_generation = cpu_to_le32(inode->i_generation); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) raw_inode->i_block[0] = - cpu_to_le32(kdev_t_to_nr(inode->i_rdev)); + cpu_to_le32(inode->i_rdev); else for (block = 0; block < EXT3_N_BLOCKS; block++) raw_inode->i_block[block] = ei->i_data[block]; diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 2d4042ac2ae0..94293028a9ec 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -225,7 +225,7 @@ void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode) hpfs_inode->i_ea_mode = 1; } if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode)) { - int d = kdev_t_to_nr(i->i_rdev); + dev_t d = i->i_rdev; ea[0] = d & 0xff; ea[1] = (d >> 8) & 0xff; ea[2] = (d >> 16) & 0xff; diff --git a/fs/inode.c b/fs/inode.c index bd116dc1fadc..df29026f21c1 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -130,7 +130,7 @@ static struct inode *alloc_inode(struct super_block *sb) inode->i_pipe = NULL; inode->i_bdev = NULL; inode->i_cdev = NULL; - inode->i_rdev = to_kdev_t(0); + inode->i_rdev = 0; inode->i_security = NULL; if (security_inode_alloc(inode)) { if (inode->i_sb->s_op->destroy_inode) @@ -1363,10 +1363,10 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) inode->i_mode = mode; if (S_ISCHR(mode)) { inode->i_fop = &def_chr_fops; - inode->i_rdev = to_kdev_t(rdev); + inode->i_rdev = rdev; } else if (S_ISBLK(mode)) { inode->i_fop = &def_blk_fops; - inode->i_rdev = to_kdev_t(rdev); + inode->i_rdev = rdev; } else if (S_ISFIFO(mode)) inode->i_fop = &def_fifo_fops; else if (S_ISSOCK(mode)) diff --git a/fs/intermezzo/vfs.c b/fs/intermezzo/vfs.c index 920ba2773961..469a463c8752 100644 --- a/fs/intermezzo/vfs.c +++ b/fs/intermezzo/vfs.c @@ -290,7 +290,7 @@ int presto_settime(struct presto_file_set *fset, void izo_get_rollback_data(struct inode *inode, struct izo_rollback_data *rb) { rb->rb_mode = (__u32)inode->i_mode; - rb->rb_rdev = (__u32)kdev_t_to_nr(inode->i_rdev); + rb->rb_rdev = (__u32)inode->i_rdev; rb->rb_uid = (__u64)inode->i_uid; rb->rb_gid = (__u64)inode->i_gid; } diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index a28d5f174b9b..bbff5798e2d3 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1329,8 +1329,7 @@ static void isofs_read_inode(struct inode * inode) inode->i_data.a_ops = &isofs_symlink_aops; } else /* XXX - parse_rock_ridge_inode() had already set i_rdev. */ - init_special_inode(inode, inode->i_mode, - kdev_t_to_nr(inode->i_rdev)); + init_special_inode(inode, inode->i_mode, inode->i_rdev); out: if (tmpde) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 8d66d202f04e..ec218349feb1 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -228,9 +228,9 @@ int parse_rock_ridge_inode_internal(struct iso_directory_record * de, * stored in the low field, and use that. */ if((low & ~0xff) && high == 0) { - inode->i_rdev = mk_kdev(low >> 8, low & 0xff); + inode->i_rdev = MKDEV(low >> 8, low & 0xff); } else { - inode->i_rdev = mk_kdev(high, low); + inode->i_rdev = MKDEV(high, low); } } break; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 8bc53c400875..991dcaf15c72 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -174,7 +174,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, int err; struct nameidata nd; int mtdnr; - kdev_t dev; + dev_t dev; if (!dev_name) return ERR_PTR(-EINVAL); @@ -240,14 +240,14 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, dev = nd.dentry->d_inode->i_rdev; path_release(&nd); - if (major(dev) != MTD_BLOCK_MAJOR) { + if (MAJOR(dev) != MTD_BLOCK_MAJOR) { if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */ printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n", dev_name); return ERR_PTR(-EINVAL); } - return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, minor(dev)); + return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, MINOR(dev)); } diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 4ad780e83e73..989621a380b6 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -61,8 +61,7 @@ void jfs_read_inode(struct inode *inode) inode->i_op = &jfs_symlink_inode_operations; } else { inode->i_op = &jfs_file_inode_operations; - init_special_inode(inode, inode->i_mode, - kdev_t_to_nr(inode->i_rdev)); + init_special_inode(inode, inode->i_mode, inode->i_rdev); } } diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 847afd3030d8..7ee8f04862cc 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -3043,7 +3043,7 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) jfs_ip->acltype = le32_to_cpu(dip->di_acltype); if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) - ip->i_rdev = to_kdev_t(le32_to_cpu(dip->di_rdev)); + ip->i_rdev = le32_to_cpu(dip->di_rdev); if (S_ISDIR(ip->i_mode)) { memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384); @@ -3102,7 +3102,7 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip) dip->di_acltype = cpu_to_le32(jfs_ip->acltype); if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) - dip->di_rdev = cpu_to_le32(kdev_t_to_nr(ip->i_rdev)); + dip->di_rdev = cpu_to_le32(ip->i_rdev); } #ifdef _JFS_DEBUG_IMAP diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 710e46886609..1c98d1103729 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -460,7 +460,7 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode) raw_inode->i_size = inode->i_size; raw_inode->i_time = inode->i_mtime.tv_sec; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev); + raw_inode->i_zone[0] = inode->i_rdev; else for (i = 0; i < 9; i++) raw_inode->i_zone[i] = minix_inode->u.i1_data[i]; mark_buffer_dirty(bh); @@ -489,7 +489,7 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode) raw_inode->i_atime = inode->i_atime.tv_sec; raw_inode->i_ctime = inode->i_ctime.tv_sec; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev); + raw_inode->i_zone[0] = inode->i_rdev; else for (i = 0; i < 10; i++) raw_inode->i_zone[i] = minix_inode->u.i2_data[i]; mark_buffer_dirty(bh); diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index b41f63972df7..d0dda80f9c47 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -242,7 +242,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, case S_IFCHR: case S_IFBLK: /* reserve rdev for later checking */ - attr->ia_size = kdev_t_to_nr(inode->i_rdev); + attr->ia_size = inode->i_rdev; attr->ia_valid |= ATTR_SIZE; /* FALLTHROUGH */ @@ -300,7 +300,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, /* Make sure the type and device matches */ nfserr = nfserr_exist; if (inode && (type != (inode->i_mode & S_IFMT) || - (is_borc && kdev_t_to_nr(inode->i_rdev) != rdev))) + (is_borc && inode->i_rdev != rdev))) goto out_unlock; } diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 3f621de0ba22..d18538e49f21 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1024,7 +1024,7 @@ static void inode2sd (void * sd, struct inode * inode) set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec ); set_sd_v2_blocks(sd_v2, inode->i_blocks ); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - set_sd_v2_rdev(sd_v2, kdev_t_to_nr(inode->i_rdev) ); + set_sd_v2_rdev(sd_v2, inode->i_rdev); else set_sd_v2_generation(sd_v2, inode->i_generation); flags = REISERFS_I(inode)->i_attrs; @@ -1048,7 +1048,7 @@ static void inode2sd_v1 (void * sd, struct inode * inode) set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec ); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - set_sd_v1_rdev(sd_v1, kdev_t_to_nr(inode->i_rdev) ); + set_sd_v1_rdev(sd_v1, inode->i_rdev); else set_sd_v1_blocks(sd_v1, inode->i_blocks ); diff --git a/fs/stat.c b/fs/stat.c index 7f034fa65d88..a1f3d7d874fa 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -24,7 +24,7 @@ void generic_fillattr(struct inode *inode, struct kstat *stat) stat->nlink = inode->i_nlink; stat->uid = inode->i_uid; stat->gid = inode->i_gid; - stat->rdev = kdev_t_to_nr(inode->i_rdev); + stat->rdev = inode->i_rdev; stat->atime = inode->i_atime; stat->mtime = inode->i_mtime; stat->ctime = inode->i_ctime; diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 9a4564610aae..60fca2128567 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -241,7 +241,7 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) si = SYSV_I(inode); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - si->i_data[0] = cpu_to_fs32(sbi, kdev_t_to_nr(inode->i_rdev)); + si->i_data[0] = cpu_to_fs32(sbi, inode->i_rdev); for (block = 0; block < 10+1+1+1; block++) write3byte(sbi, (u8 *)&si->i_data[block], &raw_inode->i_data[3*block]); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 2fa65ab370d7..1c2fba3d5655 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1392,8 +1392,8 @@ udf_update_inode(struct inode *inode, int do_sync) strcpy(eid->ident, UDF_ID_DEVELOPER); eid->identSuffix[0] = UDF_OS_CLASS_UNIX; eid->identSuffix[1] = UDF_OS_ID_LINUX; - dsea->majorDeviceIdent = kdev_t_to_nr(inode->i_rdev) >> 8; - dsea->minorDeviceIdent = kdev_t_to_nr(inode->i_rdev) & 0xFF; + dsea->majorDeviceIdent = inode->i_rdev >> 8; + dsea->minorDeviceIdent = inode->i_rdev & 0xFF; mark_buffer_dirty_inode(tbh, inode); udf_release_data(tbh); } diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 442c28e17739..f8c113bd3677 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -619,7 +619,7 @@ static int ufs_update_inode(struct inode * inode, int do_sync) } if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, kdev_t_to_nr(inode->i_rdev)); + ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); else if (inode->i_blocks) { for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.i_data[i]; diff --git a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c index 11eac5784afa..5f316085b1b9 100644 --- a/fs/xfs/linux/xfs_iops.c +++ b/fs/xfs/linux/xfs_iops.c @@ -178,7 +178,7 @@ linvfs_mknod( ip = LINVFS_GET_IP(vp); if (S_ISCHR(mode) || S_ISBLK(mode)) - ip->i_rdev = to_kdev_t(rdev); + ip->i_rdev = rdev; else if (S_ISDIR(mode)) validate_fields(ip); d_instantiate(dentry, ip); diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c index 49c173f9e5d0..1bd4b3a4a604 100644 --- a/fs/xfs/linux/xfs_super.c +++ b/fs/xfs/linux/xfs_super.c @@ -154,7 +154,7 @@ xfs_set_inodeops( } else { inode->i_op = &linvfs_file_inode_operations; init_special_inode(inode, inode->i_mode, - kdev_t_to_nr(inode->i_rdev)); + inode->i_rdev); } } @@ -171,7 +171,7 @@ xfs_revalidate_inode( inode->i_uid = ip->i_d.di_uid; inode->i_gid = ip->i_d.di_gid; if (((1 << vp->v_type) & ((1<i_rdev = NODEV; + inode->i_rdev = 0; } else { xfs_dev_t dev = ip->i_df.if_u2.if_rdev; inode->i_rdev = XFS_DEV_TO_KDEVT(dev); diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index bdb7ca141927..3c163b46160e 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h @@ -210,6 +210,6 @@ typedef enum { #define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<i_mode, ip->i_nlink, - kdev_t_to_nr(ip->i_rdev), ip->i_state); + ip->i_rdev, ip->i_state); kdb_printf(" i_hash.nxt = 0x%p i_hash.prv = 0x%p\n", ip->i_hash.next, ip->i_hash.prev); diff --git a/include/linux/fs.h b/include/linux/fs.h index fa2bd2dd7600..fe2bfd295802 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -373,7 +373,7 @@ struct inode { unsigned int i_nlink; uid_t i_uid; gid_t i_gid; - kdev_t i_rdev; + dev_t i_rdev; loff_t i_size; struct timespec i_atime; struct timespec i_mtime; @@ -469,12 +469,12 @@ static inline void i_size_write(struct inode *inode, loff_t i_size) static inline unsigned iminor(struct inode *inode) { - return minor(inode->i_rdev); + return MINOR(inode->i_rdev); } static inline unsigned imajor(struct inode *inode) { - return major(inode->i_rdev); + return MAJOR(inode->i_rdev); } struct fown_struct { -- cgit v1.2.3 From 5900b09861dd856ca475dd444793ff6c671acc84 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Thu, 4 Sep 2003 20:54:18 -0700 Subject: [PATCH] large dev_t - second series (8/15) kdev_t, to_kdev_t(), etc. are gone - there is no more objects of that type and no remaining callers of these functions. --- drivers/s390/char/tape_core.c | 2 +- drivers/s390/char/tape_proc.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/scsi/sr.c | 2 +- include/linux/kdev_t.h | 99 ------------------------------------------- net/unix/af_unix.c | 2 +- 6 files changed, 5 insertions(+), 104 deletions(-) (limited to 'include/linux') diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 7656f1eddc6e..48fb7e002944 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -178,7 +178,7 @@ tape_assign_minor(struct tape_device *device) break; minor += TAPE_MINORS_PER_DEV; } - if (minor >= (1 << KDEV_MINOR_BITS)) { + if (minor >= 256) { write_unlock(&tape_device_lock); return -ENODEV; } diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index da3a4d3ed310..5857f846101f 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c @@ -80,7 +80,7 @@ static int tape_proc_show(struct seq_file *m, void *v) static void *tape_proc_start(struct seq_file *m, loff_t *pos) { - if (*pos >= (1 << KDEV_MINOR_BITS) / TAPE_MINORS_PER_DEV) + if (*pos >= 256 / TAPE_MINORS_PER_DEV) return NULL; return (void *)((unsigned long) *pos + 1); } diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 0a5497ea2389..facb6f9fee35 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -83,7 +83,7 @@ static void sg_proc_cleanup(void); #define SG_ALLOW_DIO_DEF 0 #define SG_ALLOW_DIO_CODE /* compile out by commenting this define */ -#define SG_MAX_DEVS_MASK ((1U << KDEV_MINOR_BITS) - 1) +#define SG_MAX_DEVS_MASK (256 - 1) /* * Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 089510b7a819..d3a646260380 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -59,7 +59,7 @@ MODULE_PARM(xa_test, "i"); /* see sr_ioctl.c */ -#define SR_DISKS (1 << KDEV_MINOR_BITS) +#define SR_DISKS 256 #define MAX_RETRIES 3 #define SR_TIMEOUT (30 * HZ) diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h index 64a88b3b194a..f60508da024d 100644 --- a/include/linux/kdev_t.h +++ b/include/linux/kdev_t.h @@ -1,91 +1,6 @@ #ifndef _LINUX_KDEV_T_H #define _LINUX_KDEV_T_H #ifdef __KERNEL__ -/* -As a preparation for the introduction of larger device numbers, -we introduce a type kdev_t to hold them. No information about -this type is known outside of this include file. - -Objects of type kdev_t designate a device. Outside of the kernel -the corresponding things are objects of type dev_t - usually an -integral type with the device major and minor in the high and low -bits, respectively. Conversion is done by - -extern kdev_t to_kdev_t(int); - -It is up to the various file systems to decide how objects of type -dev_t are stored on disk. -The only other point of contact between kernel and outside world -are the system calls stat and mknod, new versions of which will -eventually have to be used in libc. - -[Unfortunately, the floppy control ioctls fail to hide the internal -kernel structures, and the fd_device field of a struct floppy_drive_struct -is user-visible. So, it remains a dev_t for the moment, with some ugly -conversions in floppy.c.] - -Inside the kernel, we aim for a kdev_t type that is a pointer -to a structure with information about the device (like major, -minor, size, blocksize, sectorsize, name, read-only flag, -struct file_operations etc.). - -However, for the time being we let kdev_t be almost the same as dev_t: - -typedef struct { unsigned short major, minor; } kdev_t; - -Admissible operations on an object of type kdev_t: -- passing it along -- comparing it for equality with another such object -- storing it in inode->i_rdev or tty->device -- using its bit pattern as argument in a hash function -- finding its major and minor -- complaining about it - -An object of type kdev_t is created only by the function MKDEV(), -with the single exception of the constant 0 (no device). - -Right now the other information mentioned above is usually found -in static arrays indexed by major or major,minor. - -An obstacle to immediately using - typedef struct { ... (* lots of information *) } *kdev_t -is the case of mknod used to create a block device that the -kernel doesn't know about at present (but first learns about -when some module is inserted). - -aeb - 950811 -*/ - - -/* - * NOTE NOTE NOTE! - * - * The kernel-internal "kdev_t" will eventually have - * 20 bits for minor numbers, and 12 bits for majors. - * - * HOWEVER, the external representation is still 8+8 - * bits, and there is no way to generate the extended - * "kdev_t" format yet. Which is just as well, since - * we still use "minor" as an index into various - * static arrays, and they are sized for a 8-bit index. - */ -typedef struct { - unsigned short value; -} kdev_t; - -#define KDEV_MINOR_BITS 8 -#define KDEV_MAJOR_BITS 8 - -#define __mkdev(major,minor) (((major) << KDEV_MINOR_BITS) + (minor)) - -#define mk_kdev(major, minor) ((kdev_t) { __mkdev(major,minor) } ) - -#define NODEV (mk_kdev(0,0)) - -/* Mask off the high bits for now.. */ -#define minor(dev) ((dev).value & 0xff) -#define major(dev) (((dev).value >> KDEV_MINOR_BITS) & 0xff) - /* These are for user-level "dev_t" */ #define MINORBITS 8 #define MINORMASK ((1U << MINORBITS) - 1) @@ -94,20 +9,6 @@ typedef struct { #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) -/* - * Conversion functions - */ - -static inline int kdev_t_to_nr(kdev_t dev) -{ - return MKDEV(major(dev), minor(dev)); -} - -static inline kdev_t to_kdev_t(int dev) -{ - return mk_kdev(MAJOR(dev),MINOR(dev)); -} - #define print_dev_t(buffer, dev) \ sprintf((buffer), "%u:%u\n", MAJOR(dev), MINOR(dev)) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 549c7e303144..61ea1a9f2a2b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -57,7 +57,7 @@ * [TO FIX] * ECONNREFUSED is not returned from one end of a connected() socket to the * other the moment one end closes. - * fstat() doesn't return st_dev=NODEV, and give the blksize as high water mark + * fstat() doesn't return st_dev=0, and give the blksize as high water mark * and a fake inode identifier (nor the BSD first socket fstat twice bug). * [NOT TO FIX] * accept() returns a path name even if the connecting socket has closed -- cgit v1.2.3 From b418f8807a80fe7d7cf60067b57ddcd6f2fc42c3 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Thu, 4 Sep 2003 20:54:27 -0700 Subject: [PATCH] large dev_t - second series (9/15) beginning of fs side work: * new helpers - old_valid_dev(), old_encode_dev() and old_decode_dev() * old_valid_dev() checks if dev_t value is OK for old filesystems (i.e. both major and minor are below 256). * old_valid_dev() calls are added in ->mknod() instances that care about dev_t values (disk-backed and network ones). * old_encode_dev() and old_decode_dev() convert dev_t -> u16 and u16 -> dev_t resp; currently these are no-ops, places that use current formar (minor in bits 0--7, major in bits 8--15) will switch to these before we widen dev_t. --- fs/cifs/dir.c | 3 +++ fs/coda/dir.c | 3 +++ fs/ext2/namei.c | 10 ++++++++-- fs/ext3/namei.c | 3 +++ fs/hpfs/namei.c | 2 ++ fs/intermezzo/dir.c | 3 +++ fs/jffs/inode-v23.c | 2 ++ fs/jffs2/dir.c | 3 +++ fs/jfs/namei.c | 3 +++ fs/libfs.c | 20 ++++++++++++++++++++ fs/minix/namei.c | 7 ++++++- fs/ncpfs/dir.c | 2 ++ fs/nfs/dir.c | 3 +++ fs/reiserfs/namei.c | 3 +++ fs/smbfs/dir.c | 3 +++ fs/sysv/namei.c | 10 ++++++++-- fs/udf/namei.c | 3 +++ fs/ufs/namei.c | 5 ++++- fs/xfs/linux/xfs_iops.c | 3 +++ include/linux/fs.h | 3 +++ 20 files changed, 88 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 8873ca0447c9..b1245a53db80 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -265,6 +265,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev char *full_path = NULL; struct inode * newinode = NULL; + if (!old_valid_dev(device_number)) + return -EINVAL; + xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 2917ab9f4976..4c75d774e0dd 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -242,6 +242,9 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, dev_t rdev if ( coda_hasmknod == 0 ) return -EIO; + if (!old_valid_dev(rdev)) + return -EINVAL; + lock_kernel(); coda_vfs_stat.create++; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 72d5690b2450..8079e2ee4684 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -139,8 +139,14 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { - struct inode * inode = ext2_new_inode (dir, mode); - int err = PTR_ERR(inode); + struct inode * inode; + int err; + + if (!old_valid_dev(rdev)) + return -EINVAL; + + inode = ext2_new_inode (dir, mode); + err = PTR_ERR(inode); if (!IS_ERR(inode)) { init_special_inode(inode, inode->i_mode, rdev); #ifdef CONFIG_EXT2_FS_XATTR diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 78daed5cee0f..769392cf8ea9 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1659,6 +1659,9 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry, struct inode *inode; int err; + if (!old_valid_dev(rdev)) + return -EINVAL; + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); if (IS_ERR(handle)) diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 18f8b1c00e93..030d3de7d01f 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -194,6 +194,8 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) int err; if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err; if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM; + if (!old_valid_dev(rdev)) + return -EINVAL; lock_kernel(); if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail; memset(&dee, 0, sizeof dee); diff --git a/fs/intermezzo/dir.c b/fs/intermezzo/dir.c index 4794ee0a3822..b07d6ae8bb74 100644 --- a/fs/intermezzo/dir.c +++ b/fs/intermezzo/dir.c @@ -726,6 +726,9 @@ static int presto_mknod(struct inode * dir, struct dentry * dentry, int mode, de struct dentry *parent = dentry->d_parent; struct lento_vfs_context info; + if (!old_valid_dev(rdev)) + return -EINVAL; + ENTRY; error = presto_check_set_fsdata(dentry); if ( error ) { diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 480a5ba41972..cad1a1f36e15 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -1086,6 +1086,8 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) D1(printk("***jffs_mknod()\n")); + if (!old_valid_dev(rdev)) + return -EINVAL; lock_kernel(); dir_f = (struct jffs_file *)dir->u.generic_ip; c = dir_f->c; diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 9a2df58cb486..068084e7893e 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -594,6 +594,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk uint32_t writtenlen; int ret; + if (!old_valid_dev(rdev)) + return -EINVAL; + ri = jffs2_alloc_raw_inode(); if (!ri) return -ENOMEM; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 5062dc50b02d..ee62b39ee46c 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1311,6 +1311,9 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) tid_t tid; struct tblock *tblk; + if (!old_valid_dev(rdev)) + return -EINVAL; + jfs_info("jfs_mknod: %s", dentry->d_name.name); if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab))) diff --git a/fs/libfs.c b/fs/libfs.c index befcf41b0e30..fbf1d0e6e3e4 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -3,6 +3,7 @@ * Library for filesystems writers. */ +#include #include #include #include @@ -428,3 +429,22 @@ void simple_release_fs(struct vfsmount **mount, int *count) spin_unlock(&pin_fs_lock); mntput(mnt); } + +/* acceptable for old filesystems */ +int old_valid_dev(dev_t dev) +{ + return MAJOR(dev) < 256 && MINOR(dev) < 256; +} +EXPORT_SYMBOL(old_valid_dev); + +u16 old_encode_dev(dev_t dev) +{ + return (MAJOR(dev) << 8) | MINOR(dev); +} +EXPORT_SYMBOL(old_encode_dev); + +dev_t old_decode_dev(u16 val) +{ + return MKDEV((val >> 8) & 255, val & 255); +} +EXPORT_SYMBOL(old_decode_dev); diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 2b9e6c64d25a..9f2682641f7f 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -78,7 +78,12 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, st static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { int error; - struct inode * inode = minix_new_inode(dir, &error); + struct inode *inode; + + if (!old_valid_dev(rdev)) + return -EINVAL; + + inode = minix_new_inode(dir, &error); if (inode) { inode->i_mode = mode; diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index f10460e559a5..ce75e852e757 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -1170,6 +1170,8 @@ out: static int ncp_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { + if (!old_valid_dev(rdev)) + return -EINVAL; if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) { DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode); return ncp_create_new(dir, dentry, mode, rdev, 0); diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e7ba8d084182..f9f494a60e4b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -859,6 +859,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); + if (!old_valid_dev(rdev)) + return -EINVAL; + attr.ia_mode = mode; attr.ia_valid = ATTR_MODE; diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 85dddb7a83b3..8c1485504ffe 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -613,6 +613,9 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, struct reiserfs_transaction_handle th ; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; + if (!old_valid_dev(rdev)) + return -EINVAL; + if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM ; } diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index f0b62740ae89..aa5974edc203 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -661,6 +661,9 @@ smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) attr.ia_uid = current->euid; attr.ia_gid = current->egid; + if (!old_valid_dev(dev)) + return -EINVAL; + smb_invalid_dir_cache(dir); error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev)); if (!error) { diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index cbf08f04d07c..c24d0be87e74 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -85,8 +85,14 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, st static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev) { - struct inode * inode = sysv_new_inode(dir, mode); - int err = PTR_ERR(inode); + struct inode * inode; + int err; + + if (!old_valid_dev(rdev)) + return -EINVAL; + + inode = sysv_new_inode(dir, mode); + err = PTR_ERR(inode); if (!IS_ERR(inode)) { sysv_set_inode(inode, rdev); diff --git a/fs/udf/namei.c b/fs/udf/namei.c index d2ac88dae447..a7350413f9b8 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -677,6 +677,9 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t int err; struct fileIdentDesc cfi, *fi; + if (!old_valid_dev(rdev)) + return -EINVAL; + lock_kernel(); err = -EIO; inode = udf_new_inode(dir, mode, &err); diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 82f391298c48..e59b6a81e558 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -111,7 +111,10 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { - struct inode * inode = ufs_new_inode(dir, mode); + struct inode * inode; + if (!old_valid_dev(rdev)) + return -EINVAL; + inode = ufs_new_inode(dir, mode); int err = PTR_ERR(inode); if (!IS_ERR(inode)) { init_special_inode(inode, mode, rdev); diff --git a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c index 5f316085b1b9..cb9bcdda6d01 100644 --- a/fs/xfs/linux/xfs_iops.c +++ b/fs/xfs/linux/xfs_iops.c @@ -113,6 +113,9 @@ linvfs_mknod( xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS; int error; + if (!old_valid_dev(rdev)) + return -EINVAL; + if (test_default_acl && test_default_acl(dvp)) { if (!_ACL_ALLOC(default_acl)) return -ENOMEM; diff --git a/include/linux/fs.h b/include/linux/fs.h index fe2bfd295802..d10db09f6164 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1389,6 +1389,9 @@ struct tree_descr { char *name; struct file_operations *ops; int mode; }; extern int simple_fill_super(struct super_block *, int, struct tree_descr *); extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count); extern void simple_release_fs(struct vfsmount **mount, int *count); +extern int old_valid_dev(dev_t); +extern u16 old_encode_dev(dev_t); +extern dev_t old_decode_dev(u16); extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_setattr(struct inode *, struct iattr *); -- cgit v1.2.3 From 0dbd0f6805c0febd2f080e6aa82e24d864be5c27 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Thu, 4 Sep 2003 20:55:10 -0700 Subject: [PATCH] large dev_t - second series (14/15) nfs_fattr->rdev switched to dev_t; code that unpacks on-the-wire attributes does explicit conversion now. --- fs/nfs/nfs2xdr.c | 6 ++++-- include/linux/nfs_xdr.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 1461252f66fe..d5f552dd7f4e 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -106,6 +106,7 @@ xdr_decode_time(u32 *p, struct timespec *timep) static u32 * xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) { + u32 rdev; fattr->type = (enum nfs_ftype) ntohl(*p++); fattr->mode = ntohl(*p++); fattr->nlink = ntohl(*p++); @@ -113,7 +114,7 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) fattr->gid = ntohl(*p++); fattr->size = ntohl(*p++); fattr->du.nfs2.blocksize = ntohl(*p++); - fattr->rdev = ntohl(*p++); + rdev = ntohl(*p++); fattr->du.nfs2.blocks = ntohl(*p++); fattr->fsid_u.nfs3 = ntohl(*p++); fattr->fileid = ntohl(*p++); @@ -121,7 +122,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) p = xdr_decode_time(p, &fattr->mtime); p = xdr_decode_time(p, &fattr->ctime); fattr->valid |= NFS_ATTR_FATTR; - if (fattr->type == NFCHR && fattr->rdev == NFS2_FIFO_DEV) { + fattr->rdev = old_decode_dev(rdev); + if (fattr->type == NFCHR && rdev == NFS2_FIFO_DEV) { fattr->type = NFFIFO; fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO; fattr->rdev = 0; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 3d46a2caaade..88b705d8cefe 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -23,7 +23,7 @@ struct nfs_fattr { __u64 used; } nfs3; } du; - __u32 rdev; + dev_t rdev; union { __u64 nfs3; /* also nfs2 */ struct { -- cgit v1.2.3 From d04668a76d3780540b30bcbc2bc638f3f31d577d Mon Sep 17 00:00:00 2001 From: Jamie Lokier Date: Thu, 4 Sep 2003 21:42:15 -0700 Subject: [PATCH] Common PROT_xxx -> VM_xxx mapping This moves the mapping of PROT_* bits to VM_* bits from mmap.c to the common header file . The mapping is needed for mprotect too. --- include/linux/mman.h | 29 +++++++++++++++++++++++++++++ mm/mmap.c | 27 ++------------------------- 2 files changed, 31 insertions(+), 25 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mman.h b/include/linux/mman.h index a8956f6588ad..cfb6ac61bbde 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -2,6 +2,7 @@ #define _LINUX_MMAN_H #include +#include #include #include @@ -27,4 +28,32 @@ static inline void vm_unacct_memory(long pages) vm_acct_memory(-pages); } +/* Optimisation macro. */ +#define _calc_vm_trans(x,bit1,bit2) \ + ((bit1) <= (bit2) ? ((x) & (bit1)) * ((bit2) / (bit1)) \ + : ((x) & (bit1)) / ((bit1) / (bit2))) + +/* + * Combine the mmap "prot" argument into "vm_flags" used internally. + */ +static inline unsigned long +calc_vm_prot_bits(unsigned long prot) +{ + return _calc_vm_trans(prot, PROT_READ, VM_READ ) | + _calc_vm_trans(prot, PROT_WRITE, VM_WRITE) | + _calc_vm_trans(prot, PROT_EXEC, VM_EXEC ); +} + +/* + * Combine the mmap "flags" argument into "vm_flags" used internally. + */ +static inline unsigned long +calc_vm_flag_bits(unsigned long flags) +{ + return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) | + _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) | + _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) | + _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ); +} + #endif /* _LINUX_MMAN_H */ diff --git a/mm/mmap.c b/mm/mmap.c index bcc28864eab6..61c9f5ca5f82 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -136,29 +136,6 @@ out: return retval; } -/* Combine the mmap "prot" and "flags" argument into one "vm_flags" used - * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits - * into "VM_xxx". - */ -static inline unsigned long -calc_vm_flags(unsigned long prot, unsigned long flags) -{ -#define _trans(x,bit1,bit2) \ -((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0) - - unsigned long prot_bits, flag_bits; - prot_bits = - _trans(prot, PROT_READ, VM_READ) | - _trans(prot, PROT_WRITE, VM_WRITE) | - _trans(prot, PROT_EXEC, VM_EXEC); - flag_bits = - _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) | - _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) | - _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE); - return prot_bits | flag_bits; -#undef _trans -} - #ifdef DEBUG_MM_RB static int browse_rb(struct rb_node * rb_node) { int i = 0; @@ -500,8 +477,8 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, * to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */ - vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) | + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; if (flags & MAP_LOCKED) { if (!capable(CAP_IPC_LOCK)) -- cgit v1.2.3