diff options
| author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-02-14 20:13:19 +0400 |
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-02-14 20:13:19 +0400 |
| commit | f2e5d078f7f02d4289db31f5f63e23e39914075e (patch) | |
| tree | c739a3e70846284ae2ce3d98cecc2be1ffebe2e2 /ipc/util.c | |
| parent | c66a566afbe6e2c94b1ae70f70cc1e3d4c73639b (diff) | |
| parent | 836dc9e3fbbab0c30aa6e664417225f5c1fb1c39 (diff) | |
| download | linux-f2e5d078f7f02d4289db31f5f63e23e39914075e.tar.xz | |
Merge tag 'v3.8-rc7' into regulator-core
Linux 3.8-rc7
Diffstat (limited to 'ipc/util.c')
| -rw-r--r-- | ipc/util.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/ipc/util.c b/ipc/util.c index 72fd0785ac94..74e1d9c7a98a 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -122,6 +122,7 @@ void ipc_init_ids(struct ipc_ids *ids) ids->in_use = 0; ids->seq = 0; + ids->next_id = -1; { int seq_limit = INT_MAX/SEQ_MULTIPLIER; if (seq_limit > USHRT_MAX) @@ -252,6 +253,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) kuid_t euid; kgid_t egid; int id, err; + int next_id = ids->next_id; if (size > IPCMNI) size = IPCMNI; @@ -264,7 +266,8 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) rcu_read_lock(); spin_lock(&new->lock); - err = idr_get_new(&ids->ipcs_idr, new, &id); + err = idr_get_new_above(&ids->ipcs_idr, new, + (next_id < 0) ? 0 : ipcid_to_idx(next_id), &id); if (err) { spin_unlock(&new->lock); rcu_read_unlock(); @@ -277,9 +280,14 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) new->cuid = new->uid = euid; new->gid = new->cgid = egid; - new->seq = ids->seq++; - if(ids->seq > ids->seq_max) - ids->seq = 0; + if (next_id < 0) { + new->seq = ids->seq++; + if (ids->seq > ids->seq_max) + ids->seq = 0; + } else { + new->seq = ipcid_to_seqx(next_id); + ids->next_id = -1; + } new->id = ipc_buildid(id, new->seq); return id; |
