Blame view
ipc/shm.c
31.5 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * linux/ipc/shm.c * Copyright (C) 1992, 1993 Krishna Balasubramanian * Many improvements/fixes by Bruno Haible. * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994. * Fixed the shm swap deallocation (shm_unuse()), August 1998 Andrea Arcangeli. * * /proc/sysvipc/shm support (c) 1999 Dragos Acostachioaie <dragos@iname.com> * BIGMEM support, Andrea Arcangeli <andrea@suse.de> * SMP thread shm, Jean-Luc Boyard <jean-luc.boyard@siemens.fr> * HIGHMEM support, Ingo Molnar <mingo@redhat.com> * Make shmmax, shmall, shmmni sysctl'able, Christoph Rohland <cr@sap.com> * Shared /dev/zero support, Kanoj Sarcar <kanoj@sgi.com> * Move the mm functionality over to mm/shmem.c, Christoph Rohland <cr@sap.com> * |
073115d6b [PATCH] Rework of... |
16 17 |
* support for audit of ipc object properties and permission changes * Dustin Kirkland <dustin.kirkland@us.ibm.com> |
4e9823111 [PATCH] IPC names... |
18 19 20 21 |
* * namespaces support * OpenVZ, SWsoft Inc. * Pavel Emelianov <xemul@openvz.org> |
bd58e2dc2 ipc,shm: shorten ... |
22 23 24 |
* * Better ipc lock (kern_ipc_perm.lock) handling * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013. |
1da177e4c Linux-2.6.12-rc2 |
25 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
26 27 28 29 30 31 32 |
#include <linux/slab.h> #include <linux/mm.h> #include <linux/hugetlb.h> #include <linux/shm.h> #include <linux/init.h> #include <linux/file.h> #include <linux/mman.h> |
1da177e4c Linux-2.6.12-rc2 |
33 34 35 36 |
#include <linux/shmem_fs.h> #include <linux/security.h> #include <linux/syscalls.h> #include <linux/audit.h> |
c59ede7b7 [PATCH] move capa... |
37 |
#include <linux/capability.h> |
7d87e14c2 [PATCH] consolida... |
38 |
#include <linux/ptrace.h> |
19b4946ca [PATCH] ipc: conv... |
39 |
#include <linux/seq_file.h> |
3e148c799 fix idr_find() lo... |
40 |
#include <linux/rwsem.h> |
4e9823111 [PATCH] IPC names... |
41 |
#include <linux/nsproxy.h> |
bc56bba8f [PATCH] shm: make... |
42 |
#include <linux/mount.h> |
ae5e1b22f namespaces: move ... |
43 |
#include <linux/ipc_namespace.h> |
7d87e14c2 [PATCH] consolida... |
44 |
|
1da177e4c Linux-2.6.12-rc2 |
45 46 47 |
#include <asm/uaccess.h> #include "util.h" |
bc56bba8f [PATCH] shm: make... |
48 49 50 51 52 53 54 55 |
struct shm_file_data { int id; struct ipc_namespace *ns; struct file *file; const struct vm_operations_struct *vm_ops; }; #define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data)) |
9a32144e9 [PATCH] mark stru... |
56 |
static const struct file_operations shm_file_operations; |
f0f37e2f7 const: mark struc... |
57 |
static const struct vm_operations_struct shm_vm_ops; |
1da177e4c Linux-2.6.12-rc2 |
58 |
|
ed2ddbf88 IPC: make struct ... |
59 |
#define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS]) |
1da177e4c Linux-2.6.12-rc2 |
60 |
|
4e9823111 [PATCH] IPC names... |
61 62 |
#define shm_unlock(shp) \ ipc_unlock(&(shp)->shm_perm) |
1da177e4c Linux-2.6.12-rc2 |
63 |
|
7748dbfaa ipc: unify the sy... |
64 |
static int newseg(struct ipc_namespace *, struct ipc_params *); |
bc56bba8f [PATCH] shm: make... |
65 66 |
static void shm_open(struct vm_area_struct *vma); static void shm_close(struct vm_area_struct *vma); |
4e9823111 [PATCH] IPC names... |
67 |
static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp); |
1da177e4c Linux-2.6.12-rc2 |
68 |
#ifdef CONFIG_PROC_FS |
19b4946ca [PATCH] ipc: conv... |
69 |
static int sysvipc_shm_proc_show(struct seq_file *s, void *it); |
1da177e4c Linux-2.6.12-rc2 |
70 |
#endif |
ed2ddbf88 IPC: make struct ... |
71 |
void shm_init_ns(struct ipc_namespace *ns) |
4e9823111 [PATCH] IPC names... |
72 |
{ |
4e9823111 [PATCH] IPC names... |
73 74 75 |
ns->shm_ctlmax = SHMMAX; ns->shm_ctlall = SHMALL; ns->shm_ctlmni = SHMMNI; |
b34a6b1da ipc: introduce sh... |
76 |
ns->shm_rmid_forced = 0; |
4e9823111 [PATCH] IPC names... |
77 |
ns->shm_tot = 0; |
e8148f758 ipc: clean up ipc... |
78 |
ipc_init_ids(&shm_ids(ns)); |
4e9823111 [PATCH] IPC names... |
79 |
} |
f4566f048 ipc: fix wrong co... |
80 |
/* |
33b746698 ipc: rename ids->... |
81 82 |
* Called with shm_ids.rwsem (writer) and the shp structure locked. * Only shm_ids.rwsem remains locked on exit. |
f4566f048 ipc: fix wrong co... |
83 |
*/ |
01b8b07a5 IPC: consolidate ... |
84 |
static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) |
4e9823111 [PATCH] IPC names... |
85 |
{ |
01b8b07a5 IPC: consolidate ... |
86 87 |
struct shmid_kernel *shp; shp = container_of(ipcp, struct shmid_kernel, shm_perm); |
4e9823111 [PATCH] IPC names... |
88 89 90 91 92 93 94 95 |
if (shp->shm_nattch){ shp->shm_perm.mode |= SHM_DEST; /* Do not find it any more */ shp->shm_perm.key = IPC_PRIVATE; shm_unlock(shp); } else shm_destroy(ns, shp); } |
ae5e1b22f namespaces: move ... |
96 |
#ifdef CONFIG_IPC_NS |
4e9823111 [PATCH] IPC names... |
97 98 |
void shm_exit_ns(struct ipc_namespace *ns) { |
01b8b07a5 IPC: consolidate ... |
99 |
free_ipcs(ns, &shm_ids(ns), do_shm_rmid); |
7d6feeb28 ipc ns: fix memor... |
100 |
idr_destroy(&ns->ids[IPC_SHM_IDS].ipcs_idr); |
4e9823111 [PATCH] IPC names... |
101 |
} |
ae5e1b22f namespaces: move ... |
102 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
103 |
|
140d0b210 Do 'shm_init_ns()... |
104 |
static int __init ipc_ns_init(void) |
1da177e4c Linux-2.6.12-rc2 |
105 |
{ |
ed2ddbf88 IPC: make struct ... |
106 |
shm_init_ns(&init_ipc_ns); |
140d0b210 Do 'shm_init_ns()... |
107 108 109 110 111 112 113 |
return 0; } pure_initcall(ipc_ns_init); void __init shm_init (void) { |
19b4946ca [PATCH] ipc: conv... |
114 |
ipc_init_proc_interface("sysvipc/shm", |
b79521807 ipc/shm.c: add RS... |
115 116 117 118 119 120 121 |
#if BITS_PER_LONG <= 32 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap ", #else " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap ", #endif |
4e9823111 [PATCH] IPC names... |
122 |
IPC_SHM_IDS, sysvipc_shm_proc_show); |
1da177e4c Linux-2.6.12-rc2 |
123 |
} |
1b2ad1674 ipc,shm: introduc... |
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
static inline struct shmid_kernel *shm_obtain_object(struct ipc_namespace *ns, int id) { struct kern_ipc_perm *ipcp = ipc_obtain_object(&shm_ids(ns), id); if (IS_ERR(ipcp)) return ERR_CAST(ipcp); return container_of(ipcp, struct shmid_kernel, shm_perm); } static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace *ns, int id) { struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&shm_ids(ns), id); if (IS_ERR(ipcp)) return ERR_CAST(ipcp); return container_of(ipcp, struct shmid_kernel, shm_perm); } |
3e148c799 fix idr_find() lo... |
143 |
/* |
33b746698 ipc: rename ids->... |
144 |
* shm_lock_(check_) routines are called in the paths where the rwsem |
00c2bf85d ipc: get rid of i... |
145 |
* is not necessarily held. |
3e148c799 fix idr_find() lo... |
146 |
*/ |
023a53557 ipc: integrate ip... |
147 |
static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id) |
1da177e4c Linux-2.6.12-rc2 |
148 |
{ |
03f02c765 Storing ipcs into... |
149 |
struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id); |
b1ed88b47 IPC: fix error ch... |
150 151 |
if (IS_ERR(ipcp)) return (struct shmid_kernel *)ipcp; |
03f02c765 Storing ipcs into... |
152 |
return container_of(ipcp, struct shmid_kernel, shm_perm); |
023a53557 ipc: integrate ip... |
153 |
} |
4c677e2ee shm: optimize loc... |
154 155 156 |
static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp) { rcu_read_lock(); |
115d40dbe ipc: close open c... |
157 |
ipc_lock_object(&ipcp->shm_perm); |
4c677e2ee shm: optimize loc... |
158 |
} |
e84ca3337 ipc: fix race wit... |
159 160 161 162 163 164 165 166 |
static void shm_rcu_free(struct rcu_head *head) { struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); struct shmid_kernel *shp = ipc_rcu_to_struct(p); security_shm_free(shp); ipc_rcu_free(head); } |
7ca7e564e ipc: store ipcs i... |
167 |
static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s) |
1da177e4c Linux-2.6.12-rc2 |
168 |
{ |
7ca7e564e ipc: store ipcs i... |
169 |
ipc_rmid(&shm_ids(ns), &s->shm_perm); |
1da177e4c Linux-2.6.12-rc2 |
170 |
} |
1da177e4c Linux-2.6.12-rc2 |
171 |
|
bc56bba8f [PATCH] shm: make... |
172 173 |
/* This is called by fork, once for every shm attach. */ static void shm_open(struct vm_area_struct *vma) |
4e9823111 [PATCH] IPC names... |
174 |
{ |
bc56bba8f [PATCH] shm: make... |
175 176 |
struct file *file = vma->vm_file; struct shm_file_data *sfd = shm_file_data(file); |
1da177e4c Linux-2.6.12-rc2 |
177 |
struct shmid_kernel *shp; |
bc56bba8f [PATCH] shm: make... |
178 |
shp = shm_lock(sfd->ns, sfd->id); |
023a53557 ipc: integrate ip... |
179 |
BUG_ON(IS_ERR(shp)); |
1da177e4c Linux-2.6.12-rc2 |
180 |
shp->shm_atim = get_seconds(); |
b488893a3 pid namespaces: c... |
181 |
shp->shm_lprid = task_tgid_vnr(current); |
1da177e4c Linux-2.6.12-rc2 |
182 183 184 |
shp->shm_nattch++; shm_unlock(shp); } |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 |
/* * shm_destroy - free the struct shmid_kernel * |
f4566f048 ipc: fix wrong co... |
188 |
* @ns: namespace |
1da177e4c Linux-2.6.12-rc2 |
189 190 |
* @shp: struct to free * |
33b746698 ipc: rename ids->... |
191 |
* It has to be called with shp and shm_ids.rwsem (writer) locked, |
1da177e4c Linux-2.6.12-rc2 |
192 193 |
* but returns with shp unlocked and freed. */ |
4e9823111 [PATCH] IPC names... |
194 |
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) |
1da177e4c Linux-2.6.12-rc2 |
195 |
{ |
4e9823111 [PATCH] IPC names... |
196 |
ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; |
7ca7e564e ipc: store ipcs i... |
197 |
shm_rmid(ns, shp); |
1da177e4c Linux-2.6.12-rc2 |
198 199 200 |
shm_unlock(shp); if (!is_file_hugepages(shp->shm_file)) shmem_lock(shp->shm_file, 0, shp->mlock_user); |
353d5c30c mm: fix hugetlb b... |
201 |
else if (shp->mlock_user) |
496ad9aa8 new helper: file_... |
202 |
user_shm_unlock(file_inode(shp->shm_file)->i_size, |
1da177e4c Linux-2.6.12-rc2 |
203 204 |
shp->mlock_user); fput (shp->shm_file); |
e84ca3337 ipc: fix race wit... |
205 |
ipc_rcu_putref(shp, shm_rcu_free); |
1da177e4c Linux-2.6.12-rc2 |
206 207 208 |
} /* |
b34a6b1da ipc: introduce sh... |
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
* shm_may_destroy - identifies whether shm segment should be destroyed now * * Returns true if and only if there are no active users of the segment and * one of the following is true: * * 1) shmctl(id, IPC_RMID, NULL) was called for this shp * * 2) sysctl kernel.shm_rmid_forced is set to 1. */ static bool shm_may_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) { return (shp->shm_nattch == 0) && (ns->shm_rmid_forced || (shp->shm_perm.mode & SHM_DEST)); } /* |
bc56bba8f [PATCH] shm: make... |
226 |
* remove the attach descriptor vma. |
1da177e4c Linux-2.6.12-rc2 |
227 228 229 230 |
* free memory for segment if it is marked destroyed. * The descriptor has already been removed from the current->mm->mmap list * and will later be kfree()d. */ |
bc56bba8f [PATCH] shm: make... |
231 |
static void shm_close(struct vm_area_struct *vma) |
1da177e4c Linux-2.6.12-rc2 |
232 |
{ |
bc56bba8f [PATCH] shm: make... |
233 234 |
struct file * file = vma->vm_file; struct shm_file_data *sfd = shm_file_data(file); |
1da177e4c Linux-2.6.12-rc2 |
235 |
struct shmid_kernel *shp; |
bc56bba8f [PATCH] shm: make... |
236 |
struct ipc_namespace *ns = sfd->ns; |
4e9823111 [PATCH] IPC names... |
237 |
|
33b746698 ipc: rename ids->... |
238 |
down_write(&shm_ids(ns).rwsem); |
1da177e4c Linux-2.6.12-rc2 |
239 |
/* remove from the list of attaches of the shm segment */ |
00c2bf85d ipc: get rid of i... |
240 |
shp = shm_lock(ns, sfd->id); |
023a53557 ipc: integrate ip... |
241 |
BUG_ON(IS_ERR(shp)); |
b488893a3 pid namespaces: c... |
242 |
shp->shm_lprid = task_tgid_vnr(current); |
1da177e4c Linux-2.6.12-rc2 |
243 244 |
shp->shm_dtim = get_seconds(); shp->shm_nattch--; |
b34a6b1da ipc: introduce sh... |
245 246 247 248 |
if (shm_may_destroy(ns, shp)) shm_destroy(ns, shp); else shm_unlock(shp); |
33b746698 ipc: rename ids->... |
249 |
up_write(&shm_ids(ns).rwsem); |
b34a6b1da ipc: introduce sh... |
250 |
} |
33b746698 ipc: rename ids->... |
251 |
/* Called with ns->shm_ids(ns).rwsem locked */ |
b34a6b1da ipc: introduce sh... |
252 253 254 |
static int shm_try_destroy_current(int id, void *p, void *data) { struct ipc_namespace *ns = data; |
4c677e2ee shm: optimize loc... |
255 256 |
struct kern_ipc_perm *ipcp = p; struct shmid_kernel *shp = container_of(ipcp, struct shmid_kernel, shm_perm); |
b34a6b1da ipc: introduce sh... |
257 |
|
4c677e2ee shm: optimize loc... |
258 |
if (shp->shm_creator != current) |
5774ed014 shm: handle separ... |
259 |
return 0; |
5774ed014 shm: handle separ... |
260 261 262 263 264 265 266 267 268 269 270 271 |
/* * Mark it as orphaned to destroy the segment when * kernel.shm_rmid_forced is changed. * It is noop if the following shm_may_destroy() returns true. */ shp->shm_creator = NULL; /* * Don't even try to destroy it. If shm_rmid_forced=0 and IPC_RMID * is not set, it shouldn't be deleted here. */ |
4c677e2ee shm: optimize loc... |
272 |
if (!ns->shm_rmid_forced) |
b34a6b1da ipc: introduce sh... |
273 |
return 0; |
b34a6b1da ipc: introduce sh... |
274 |
|
4c677e2ee shm: optimize loc... |
275 276 |
if (shm_may_destroy(ns, shp)) { shm_lock_by_ptr(shp); |
b34a6b1da ipc: introduce sh... |
277 |
shm_destroy(ns, shp); |
4c677e2ee shm: optimize loc... |
278 |
} |
b34a6b1da ipc: introduce sh... |
279 280 |
return 0; } |
33b746698 ipc: rename ids->... |
281 |
/* Called with ns->shm_ids(ns).rwsem locked */ |
b34a6b1da ipc: introduce sh... |
282 283 284 |
static int shm_try_destroy_orphaned(int id, void *p, void *data) { struct ipc_namespace *ns = data; |
4c677e2ee shm: optimize loc... |
285 286 |
struct kern_ipc_perm *ipcp = p; struct shmid_kernel *shp = container_of(ipcp, struct shmid_kernel, shm_perm); |
b34a6b1da ipc: introduce sh... |
287 288 289 290 |
/* * We want to destroy segments without users and with already * exit'ed originating process. |
4c677e2ee shm: optimize loc... |
291 |
* |
33b746698 ipc: rename ids->... |
292 |
* As shp->* are changed under rwsem, it's safe to skip shp locking. |
b34a6b1da ipc: introduce sh... |
293 |
*/ |
4c677e2ee shm: optimize loc... |
294 |
if (shp->shm_creator != NULL) |
b34a6b1da ipc: introduce sh... |
295 |
return 0; |
b34a6b1da ipc: introduce sh... |
296 |
|
4c677e2ee shm: optimize loc... |
297 298 |
if (shm_may_destroy(ns, shp)) { shm_lock_by_ptr(shp); |
4e9823111 [PATCH] IPC names... |
299 |
shm_destroy(ns, shp); |
4c677e2ee shm: optimize loc... |
300 |
} |
b34a6b1da ipc: introduce sh... |
301 302 303 304 305 |
return 0; } void shm_destroy_orphaned(struct ipc_namespace *ns) { |
33b746698 ipc: rename ids->... |
306 |
down_write(&shm_ids(ns).rwsem); |
33a30ed4b shm: fix wrong tests |
307 |
if (shm_ids(ns).in_use) |
4c677e2ee shm: optimize loc... |
308 |
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns); |
33b746698 ipc: rename ids->... |
309 |
up_write(&shm_ids(ns).rwsem); |
b34a6b1da ipc: introduce sh... |
310 311 312 313 314 |
} void exit_shm(struct task_struct *task) { |
4c677e2ee shm: optimize loc... |
315 |
struct ipc_namespace *ns = task->nsproxy->ipc_ns; |
b34a6b1da ipc: introduce sh... |
316 |
|
298507d4d shm: optimize exi... |
317 318 |
if (shm_ids(ns).in_use == 0) return; |
b34a6b1da ipc: introduce sh... |
319 |
/* Destroy all already created segments, but not mapped yet */ |
33b746698 ipc: rename ids->... |
320 |
down_write(&shm_ids(ns).rwsem); |
33a30ed4b shm: fix wrong tests |
321 |
if (shm_ids(ns).in_use) |
4c677e2ee shm: optimize loc... |
322 |
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns); |
33b746698 ipc: rename ids->... |
323 |
up_write(&shm_ids(ns).rwsem); |
1da177e4c Linux-2.6.12-rc2 |
324 |
} |
d0217ac04 mm: fault feedbac... |
325 |
static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
bc56bba8f [PATCH] shm: make... |
326 327 328 |
{ struct file *file = vma->vm_file; struct shm_file_data *sfd = shm_file_data(file); |
d0217ac04 mm: fault feedbac... |
329 |
return sfd->vm_ops->fault(vma, vmf); |
bc56bba8f [PATCH] shm: make... |
330 331 332 |
} #ifdef CONFIG_NUMA |
d823e3e75 ipc/shm.c: make 2... |
333 |
static int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new) |
bc56bba8f [PATCH] shm: make... |
334 335 336 337 338 339 340 341 |
{ struct file *file = vma->vm_file; struct shm_file_data *sfd = shm_file_data(file); int err = 0; if (sfd->vm_ops->set_policy) err = sfd->vm_ops->set_policy(vma, new); return err; } |
d823e3e75 ipc/shm.c: make 2... |
342 343 |
static struct mempolicy *shm_get_policy(struct vm_area_struct *vma, unsigned long addr) |
bc56bba8f [PATCH] shm: make... |
344 345 346 347 348 349 350 |
{ struct file *file = vma->vm_file; struct shm_file_data *sfd = shm_file_data(file); struct mempolicy *pol = NULL; if (sfd->vm_ops->get_policy) pol = sfd->vm_ops->get_policy(vma, addr); |
52cd3b074 mempolicy: rework... |
351 |
else if (vma->vm_policy) |
bc56bba8f [PATCH] shm: make... |
352 |
pol = vma->vm_policy; |
52cd3b074 mempolicy: rework... |
353 |
|
bc56bba8f [PATCH] shm: make... |
354 355 356 |
return pol; } #endif |
1da177e4c Linux-2.6.12-rc2 |
357 358 |
static int shm_mmap(struct file * file, struct vm_area_struct * vma) { |
bc56bba8f [PATCH] shm: make... |
359 |
struct shm_file_data *sfd = shm_file_data(file); |
b0e15190e [PATCH] NOMMU: Ma... |
360 |
int ret; |
bc56bba8f [PATCH] shm: make... |
361 362 363 364 |
ret = sfd->file->f_op->mmap(sfd->file, vma); if (ret != 0) return ret; sfd->vm_ops = vma->vm_ops; |
2e92a3bae NOMMU: Fix SYSV I... |
365 |
#ifdef CONFIG_MMU |
54cb8821d mm: merge populat... |
366 |
BUG_ON(!sfd->vm_ops->fault); |
2e92a3bae NOMMU: Fix SYSV I... |
367 |
#endif |
bc56bba8f [PATCH] shm: make... |
368 369 |
vma->vm_ops = &shm_vm_ops; shm_open(vma); |
b0e15190e [PATCH] NOMMU: Ma... |
370 371 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
372 |
} |
4e9823111 [PATCH] IPC names... |
373 374 |
static int shm_release(struct inode *ino, struct file *file) { |
bc56bba8f [PATCH] shm: make... |
375 |
struct shm_file_data *sfd = shm_file_data(file); |
4e9823111 [PATCH] IPC names... |
376 |
|
bc56bba8f [PATCH] shm: make... |
377 378 379 |
put_ipc_ns(sfd->ns); shm_file_data(file) = NULL; kfree(sfd); |
4e9823111 [PATCH] IPC names... |
380 381 |
return 0; } |
02c24a821 fs: push i_mutex ... |
382 |
static int shm_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
516dffdcd [PATCH] Fix get_u... |
383 |
{ |
516dffdcd [PATCH] Fix get_u... |
384 |
struct shm_file_data *sfd = shm_file_data(file); |
516dffdcd [PATCH] Fix get_u... |
385 |
|
7ea808591 drop unused dentr... |
386 387 |
if (!sfd->file->f_op->fsync) return -EINVAL; |
02c24a821 fs: push i_mutex ... |
388 |
return sfd->file->f_op->fsync(sfd->file, start, end, datasync); |
516dffdcd [PATCH] Fix get_u... |
389 |
} |
7d8a45695 ipc: shm: restore... |
390 391 392 393 394 395 396 397 398 |
static long shm_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { struct shm_file_data *sfd = shm_file_data(file); if (!sfd->file->f_op->fallocate) return -EOPNOTSUPP; return sfd->file->f_op->fallocate(file, mode, offset, len); } |
bc56bba8f [PATCH] shm: make... |
399 400 401 402 403 |
static unsigned long shm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { struct shm_file_data *sfd = shm_file_data(file); |
c4caa7781 file ->get_unmapp... |
404 405 |
return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len, pgoff, flags); |
bc56bba8f [PATCH] shm: make... |
406 |
} |
bc56bba8f [PATCH] shm: make... |
407 |
|
9a32144e9 [PATCH] mark stru... |
408 |
static const struct file_operations shm_file_operations = { |
4e9823111 [PATCH] IPC names... |
409 |
.mmap = shm_mmap, |
516dffdcd [PATCH] Fix get_u... |
410 |
.fsync = shm_fsync, |
4e9823111 [PATCH] IPC names... |
411 |
.release = shm_release, |
ed5e5894b nommu: fix SYSV S... |
412 413 414 |
#ifndef CONFIG_MMU .get_unmapped_area = shm_get_unmapped_area, #endif |
6038f373a llseek: automatic... |
415 |
.llseek = noop_llseek, |
7d8a45695 ipc: shm: restore... |
416 |
.fallocate = shm_fallocate, |
c4caa7781 file ->get_unmapp... |
417 418 419 420 421 422 |
}; static const struct file_operations shm_file_operations_huge = { .mmap = shm_mmap, .fsync = shm_fsync, .release = shm_release, |
bc56bba8f [PATCH] shm: make... |
423 |
.get_unmapped_area = shm_get_unmapped_area, |
6038f373a llseek: automatic... |
424 |
.llseek = noop_llseek, |
7d8a45695 ipc: shm: restore... |
425 |
.fallocate = shm_fallocate, |
1da177e4c Linux-2.6.12-rc2 |
426 |
}; |
c4caa7781 file ->get_unmapp... |
427 428 429 430 |
int is_file_shm_hugepages(struct file *file) { return file->f_op == &shm_file_operations_huge; } |
f0f37e2f7 const: mark struc... |
431 |
static const struct vm_operations_struct shm_vm_ops = { |
1da177e4c Linux-2.6.12-rc2 |
432 433 |
.open = shm_open, /* callback for a new vm-area open */ .close = shm_close, /* callback for when the vm-area is released */ |
54cb8821d mm: merge populat... |
434 |
.fault = shm_fault, |
bc56bba8f [PATCH] shm: make... |
435 436 437 |
#if defined(CONFIG_NUMA) .set_policy = shm_set_policy, .get_policy = shm_get_policy, |
1da177e4c Linux-2.6.12-rc2 |
438 439 |
#endif }; |
f4566f048 ipc: fix wrong co... |
440 441 442 443 444 |
/** * newseg - Create a new shared memory segment * @ns: namespace * @params: ptr to the structure that contains key, size and shmflg * |
33b746698 ipc: rename ids->... |
445 |
* Called with shm_ids.rwsem held as a writer. |
f4566f048 ipc: fix wrong co... |
446 |
*/ |
7748dbfaa ipc: unify the sy... |
447 |
static int newseg(struct ipc_namespace *ns, struct ipc_params *params) |
1da177e4c Linux-2.6.12-rc2 |
448 |
{ |
7748dbfaa ipc: unify the sy... |
449 450 451 |
key_t key = params->key; int shmflg = params->flg; size_t size = params->u.size; |
1da177e4c Linux-2.6.12-rc2 |
452 453 |
int error; struct shmid_kernel *shp; |
d69f3bad4 ipc: sysv shared ... |
454 |
size_t numpages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
455 456 457 |
struct file * file; char name[13]; int id; |
ca16d140a mm: don't access ... |
458 |
vm_flags_t acctflag = 0; |
1da177e4c Linux-2.6.12-rc2 |
459 |
|
4e9823111 [PATCH] IPC names... |
460 |
if (size < SHMMIN || size > ns->shm_ctlmax) |
1da177e4c Linux-2.6.12-rc2 |
461 |
return -EINVAL; |
f66d45e99 [PATCH] correct s... |
462 |
if (ns->shm_tot + numpages > ns->shm_ctlall) |
1da177e4c Linux-2.6.12-rc2 |
463 464 465 466 467 468 469 |
return -ENOSPC; shp = ipc_rcu_alloc(sizeof(*shp)); if (!shp) return -ENOMEM; shp->shm_perm.key = key; |
b33291c0b [PATCH] ipc: expa... |
470 |
shp->shm_perm.mode = (shmflg & S_IRWXUGO); |
1da177e4c Linux-2.6.12-rc2 |
471 472 473 474 475 |
shp->mlock_user = NULL; shp->shm_perm.security = NULL; error = security_shm_alloc(shp); if (error) { |
e84ca3337 ipc: fix race wit... |
476 |
ipc_rcu_putref(shp, ipc_rcu_free); |
1da177e4c Linux-2.6.12-rc2 |
477 478 |
return error; } |
9d66586f7 shm: fix the file... |
479 |
sprintf (name, "SYSV%08x", key); |
1da177e4c Linux-2.6.12-rc2 |
480 |
if (shmflg & SHM_HUGETLB) { |
af73e4d95 hugetlbfs: fix mm... |
481 482 |
struct hstate *hs = hstate_sizelog((shmflg >> SHM_HUGE_SHIFT) & SHM_HUGE_MASK); |
091d0d55b shm: fix null poi... |
483 484 485 486 487 488 489 |
size_t hugesize; if (!hs) { error = -EINVAL; goto no_file; } hugesize = ALIGN(size, huge_page_size(hs)); |
af73e4d95 hugetlbfs: fix mm... |
490 |
|
5a6fe1259 Do not account fo... |
491 492 493 |
/* hugetlb_file_setup applies strict accounting */ if (shmflg & SHM_NORESERVE) acctflag = VM_NORESERVE; |
af73e4d95 hugetlbfs: fix mm... |
494 |
file = hugetlb_file_setup(name, hugesize, acctflag, |
42d7395fe mm: support more ... |
495 496 |
&shp->mlock_user, HUGETLB_SHMFS_INODE, (shmflg >> SHM_HUGE_SHIFT) & SHM_HUGE_MASK); |
1da177e4c Linux-2.6.12-rc2 |
497 |
} else { |
bf8f972d3 [PATCH] SHM_NORES... |
498 499 500 501 502 503 |
/* * Do not allow no accounting for OVERCOMMIT_NEVER, even * if it's asked for. */ if ((shmflg & SHM_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER) |
fc8744adc Stop playing sill... |
504 |
acctflag = VM_NORESERVE; |
bf8f972d3 [PATCH] SHM_NORES... |
505 |
file = shmem_file_setup(name, size, acctflag); |
1da177e4c Linux-2.6.12-rc2 |
506 507 508 509 |
} error = PTR_ERR(file); if (IS_ERR(file)) goto no_file; |
48dea404e IPC: use ipc_buil... |
510 |
id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); |
283bb7fad IPC: fix error ca... |
511 512 |
if (id < 0) { error = id; |
1da177e4c Linux-2.6.12-rc2 |
513 |
goto no_id; |
283bb7fad IPC: fix error ca... |
514 |
} |
1da177e4c Linux-2.6.12-rc2 |
515 |
|
b488893a3 pid namespaces: c... |
516 |
shp->shm_cprid = task_tgid_vnr(current); |
1da177e4c Linux-2.6.12-rc2 |
517 518 519 520 521 |
shp->shm_lprid = 0; shp->shm_atim = shp->shm_dtim = 0; shp->shm_ctim = get_seconds(); shp->shm_segsz = size; shp->shm_nattch = 0; |
1da177e4c Linux-2.6.12-rc2 |
522 |
shp->shm_file = file; |
5774ed014 shm: handle separ... |
523 |
shp->shm_creator = current; |
34b209241 ipc: move rcu loc... |
524 |
|
30475cc12 Restore shmid as ... |
525 526 527 528 |
/* * shmid gets reported as "inode#" in /proc/pid/maps. * proc-ps tools use this. Changing this will break them. */ |
496ad9aa8 new helper: file_... |
529 |
file_inode(file)->i_ino = shp->shm_perm.id; |
551110a94 [PATCH] hugetlb: ... |
530 |
|
4e9823111 [PATCH] IPC names... |
531 |
ns->shm_tot += numpages; |
7ca7e564e ipc: store ipcs i... |
532 |
error = shp->shm_perm.id; |
34b209241 ipc: move rcu loc... |
533 |
|
115d40dbe ipc: close open c... |
534 |
ipc_unlock_object(&shp->shm_perm); |
34b209241 ipc: move rcu loc... |
535 |
rcu_read_unlock(); |
7ca7e564e ipc: store ipcs i... |
536 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
537 538 |
no_id: |
2195d2818 fix undefined ref... |
539 |
if (is_file_hugepages(file) && shp->mlock_user) |
353d5c30c mm: fix hugetlb b... |
540 |
user_shm_unlock(size, shp->mlock_user); |
1da177e4c Linux-2.6.12-rc2 |
541 542 |
fput(file); no_file: |
e84ca3337 ipc: fix race wit... |
543 |
ipc_rcu_putref(shp, shm_rcu_free); |
1da177e4c Linux-2.6.12-rc2 |
544 545 |
return error; } |
f4566f048 ipc: fix wrong co... |
546 |
/* |
33b746698 ipc: rename ids->... |
547 |
* Called with shm_ids.rwsem and ipcp locked. |
f4566f048 ipc: fix wrong co... |
548 |
*/ |
03f02c765 Storing ipcs into... |
549 |
static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) |
7748dbfaa ipc: unify the sy... |
550 |
{ |
03f02c765 Storing ipcs into... |
551 552 553 554 |
struct shmid_kernel *shp; shp = container_of(ipcp, struct shmid_kernel, shm_perm); return security_shm_associate(shp, shmflg); |
7748dbfaa ipc: unify the sy... |
555 |
} |
f4566f048 ipc: fix wrong co... |
556 |
/* |
33b746698 ipc: rename ids->... |
557 |
* Called with shm_ids.rwsem and ipcp locked. |
f4566f048 ipc: fix wrong co... |
558 |
*/ |
03f02c765 Storing ipcs into... |
559 560 |
static inline int shm_more_checks(struct kern_ipc_perm *ipcp, struct ipc_params *params) |
7748dbfaa ipc: unify the sy... |
561 |
{ |
03f02c765 Storing ipcs into... |
562 563 564 565 |
struct shmid_kernel *shp; shp = container_of(ipcp, struct shmid_kernel, shm_perm); if (shp->shm_segsz < params->u.size) |
7748dbfaa ipc: unify the sy... |
566 567 568 569 |
return -EINVAL; return 0; } |
d5460c997 [CVE-2009-0029] S... |
570 |
SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg) |
1da177e4c Linux-2.6.12-rc2 |
571 |
{ |
4e9823111 [PATCH] IPC names... |
572 |
struct ipc_namespace *ns; |
7748dbfaa ipc: unify the sy... |
573 574 |
struct ipc_ops shm_ops; struct ipc_params shm_params; |
4e9823111 [PATCH] IPC names... |
575 576 |
ns = current->nsproxy->ipc_ns; |
1da177e4c Linux-2.6.12-rc2 |
577 |
|
7748dbfaa ipc: unify the sy... |
578 579 580 |
shm_ops.getnew = newseg; shm_ops.associate = shm_security; shm_ops.more_checks = shm_more_checks; |
7ca7e564e ipc: store ipcs i... |
581 |
|
7748dbfaa ipc: unify the sy... |
582 583 584 |
shm_params.key = key; shm_params.flg = shmflg; shm_params.u.size = size; |
1da177e4c Linux-2.6.12-rc2 |
585 |
|
7748dbfaa ipc: unify the sy... |
586 |
return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params); |
1da177e4c Linux-2.6.12-rc2 |
587 588 589 590 591 592 593 594 595 596 |
} static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version) { switch(version) { case IPC_64: return copy_to_user(buf, in, sizeof(*in)); case IPC_OLD: { struct shmid_ds out; |
3af54c9bd ipc: shm: fix inf... |
597 |
memset(&out, 0, sizeof(out)); |
1da177e4c Linux-2.6.12-rc2 |
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm); out.shm_segsz = in->shm_segsz; out.shm_atime = in->shm_atime; out.shm_dtime = in->shm_dtime; out.shm_ctime = in->shm_ctime; out.shm_cpid = in->shm_cpid; out.shm_lpid = in->shm_lpid; out.shm_nattch = in->shm_nattch; return copy_to_user(buf, &out, sizeof(out)); } default: return -EINVAL; } } |
016d7132f IPC: get rid of t... |
613 614 |
static inline unsigned long copy_shmid_from_user(struct shmid64_ds *out, void __user *buf, int version) |
1da177e4c Linux-2.6.12-rc2 |
615 616 617 |
{ switch(version) { case IPC_64: |
016d7132f IPC: get rid of t... |
618 |
if (copy_from_user(out, buf, sizeof(*out))) |
1da177e4c Linux-2.6.12-rc2 |
619 |
return -EFAULT; |
1da177e4c Linux-2.6.12-rc2 |
620 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
621 622 623 624 625 626 |
case IPC_OLD: { struct shmid_ds tbuf_old; if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) return -EFAULT; |
016d7132f IPC: get rid of t... |
627 628 629 |
out->shm_perm.uid = tbuf_old.shm_perm.uid; out->shm_perm.gid = tbuf_old.shm_perm.gid; out->shm_perm.mode = tbuf_old.shm_perm.mode; |
1da177e4c Linux-2.6.12-rc2 |
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
return 0; } default: return -EINVAL; } } static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminfo64 *in, int version) { switch(version) { case IPC_64: return copy_to_user(buf, in, sizeof(*in)); case IPC_OLD: { struct shminfo out; if(in->shmmax > INT_MAX) out.shmmax = INT_MAX; else out.shmmax = (int)in->shmmax; out.shmmin = in->shmmin; out.shmmni = in->shmmni; out.shmseg = in->shmseg; out.shmall = in->shmall; return copy_to_user(buf, &out, sizeof(out)); } default: return -EINVAL; } } |
f4566f048 ipc: fix wrong co... |
663 |
/* |
b79521807 ipc/shm.c: add RS... |
664 |
* Calculate and add used RSS and swap pages of a shm. |
33b746698 ipc: rename ids->... |
665 |
* Called with shm_ids.rwsem held as a reader |
b79521807 ipc/shm.c: add RS... |
666 667 668 669 670 |
*/ static void shm_add_rss_swap(struct shmid_kernel *shp, unsigned long *rss_add, unsigned long *swp_add) { struct inode *inode; |
496ad9aa8 new helper: file_... |
671 |
inode = file_inode(shp->shm_file); |
b79521807 ipc/shm.c: add RS... |
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
if (is_file_hugepages(shp->shm_file)) { struct address_space *mapping = inode->i_mapping; struct hstate *h = hstate_file(shp->shm_file); *rss_add += pages_per_huge_page(h) * mapping->nrpages; } else { #ifdef CONFIG_SHMEM struct shmem_inode_info *info = SHMEM_I(inode); spin_lock(&info->lock); *rss_add += inode->i_mapping->nrpages; *swp_add += info->swapped; spin_unlock(&info->lock); #else *rss_add += inode->i_mapping->nrpages; #endif } } /* |
33b746698 ipc: rename ids->... |
691 |
* Called with shm_ids.rwsem held as a reader |
f4566f048 ipc: fix wrong co... |
692 |
*/ |
4e9823111 [PATCH] IPC names... |
693 694 |
static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, unsigned long *swp) |
1da177e4c Linux-2.6.12-rc2 |
695 |
{ |
7ca7e564e ipc: store ipcs i... |
696 697 |
int next_id; int total, in_use; |
1da177e4c Linux-2.6.12-rc2 |
698 699 700 |
*rss = 0; *swp = 0; |
7ca7e564e ipc: store ipcs i... |
701 702 703 |
in_use = shm_ids(ns).in_use; for (total = 0, next_id = 0; total < in_use; next_id++) { |
e562aebc6 ipc: make shm_get... |
704 |
struct kern_ipc_perm *ipc; |
1da177e4c Linux-2.6.12-rc2 |
705 |
struct shmid_kernel *shp; |
1da177e4c Linux-2.6.12-rc2 |
706 |
|
e562aebc6 ipc: make shm_get... |
707 708 |
ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id); if (ipc == NULL) |
1da177e4c Linux-2.6.12-rc2 |
709 |
continue; |
e562aebc6 ipc: make shm_get... |
710 |
shp = container_of(ipc, struct shmid_kernel, shm_perm); |
1da177e4c Linux-2.6.12-rc2 |
711 |
|
b79521807 ipc/shm.c: add RS... |
712 |
shm_add_rss_swap(shp, rss, swp); |
7ca7e564e ipc: store ipcs i... |
713 714 |
total++; |
1da177e4c Linux-2.6.12-rc2 |
715 716 |
} } |
8d4cc8b5c IPC/shared memory... |
717 |
/* |
33b746698 ipc: rename ids->... |
718 |
* This function handles some shmctl commands which require the rwsem |
8d4cc8b5c IPC/shared memory... |
719 |
* to be held in write mode. |
33b746698 ipc: rename ids->... |
720 |
* NOTE: no locks must be held, the rwsem is taken inside this function. |
8d4cc8b5c IPC/shared memory... |
721 722 723 |
*/ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, struct shmid_ds __user *buf, int version) |
1da177e4c Linux-2.6.12-rc2 |
724 |
{ |
8d4cc8b5c IPC/shared memory... |
725 |
struct kern_ipc_perm *ipcp; |
016d7132f IPC: get rid of t... |
726 |
struct shmid64_ds shmid64; |
1da177e4c Linux-2.6.12-rc2 |
727 |
struct shmid_kernel *shp; |
8d4cc8b5c IPC/shared memory... |
728 729 730 |
int err; if (cmd == IPC_SET) { |
016d7132f IPC: get rid of t... |
731 |
if (copy_shmid_from_user(&shmid64, buf, version)) |
8d4cc8b5c IPC/shared memory... |
732 733 |
return -EFAULT; } |
33b746698 ipc: rename ids->... |
734 |
down_write(&shm_ids(ns).rwsem); |
ac9bc6e39 ipc: move locking... |
735 |
rcu_read_lock(); |
b3b7b427f ipc,shm: shorten ... |
736 737 |
ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd, &shmid64.shm_perm, 0); |
ac9bc6e39 ipc: move locking... |
738 739 |
if (IS_ERR(ipcp)) { err = PTR_ERR(ipcp); |
ac9bc6e39 ipc: move locking... |
740 741 |
goto out_unlock1; } |
8d4cc8b5c IPC/shared memory... |
742 |
|
a5f75e7f2 IPC: consolidate ... |
743 |
shp = container_of(ipcp, struct shmid_kernel, shm_perm); |
8d4cc8b5c IPC/shared memory... |
744 745 746 |
err = security_shm_shmctl(shp, cmd); if (err) |
b3b7b427f ipc,shm: shorten ... |
747 |
goto out_unlock1; |
ac9bc6e39 ipc: move locking... |
748 |
|
8d4cc8b5c IPC/shared memory... |
749 750 |
switch (cmd) { case IPC_RMID: |
b3b7b427f ipc,shm: shorten ... |
751 |
ipc_lock_object(&shp->shm_perm); |
ac9bc6e39 ipc: move locking... |
752 |
/* do_shm_rmid unlocks the ipc object and rcu */ |
8d4cc8b5c IPC/shared memory... |
753 754 755 |
do_shm_rmid(ns, ipcp); goto out_up; case IPC_SET: |
b3b7b427f ipc,shm: shorten ... |
756 |
ipc_lock_object(&shp->shm_perm); |
1efdb69b0 userns: Convert i... |
757 758 |
err = ipc_update_perm(&shmid64.shm_perm, ipcp); if (err) |
ac9bc6e39 ipc: move locking... |
759 |
goto out_unlock0; |
8d4cc8b5c IPC/shared memory... |
760 761 762 763 |
shp->shm_ctim = get_seconds(); break; default: err = -EINVAL; |
b3b7b427f ipc,shm: shorten ... |
764 |
goto out_unlock1; |
8d4cc8b5c IPC/shared memory... |
765 |
} |
ac9bc6e39 ipc: move locking... |
766 767 768 769 770 |
out_unlock0: ipc_unlock_object(&shp->shm_perm); out_unlock1: rcu_read_unlock(); |
8d4cc8b5c IPC/shared memory... |
771 |
out_up: |
33b746698 ipc: rename ids->... |
772 |
up_write(&shm_ids(ns).rwsem); |
8d4cc8b5c IPC/shared memory... |
773 774 |
return err; } |
d6187ddfc ipc,shm: introduc... |
775 776 |
static int shmctl_nolock(struct ipc_namespace *ns, int shmid, int cmd, int version, void __user *buf) |
8d4cc8b5c IPC/shared memory... |
777 |
{ |
d6187ddfc ipc,shm: introduc... |
778 |
int err; |
8d4cc8b5c IPC/shared memory... |
779 |
struct shmid_kernel *shp; |
1da177e4c Linux-2.6.12-rc2 |
780 |
|
d6187ddfc ipc,shm: introduc... |
781 782 783 784 785 |
/* preliminary security checks for *_INFO */ if (cmd == IPC_INFO || cmd == SHM_INFO) { err = security_shm_shmctl(NULL, cmd); if (err) return err; |
1da177e4c Linux-2.6.12-rc2 |
786 |
} |
d6187ddfc ipc,shm: introduc... |
787 |
switch (cmd) { |
1da177e4c Linux-2.6.12-rc2 |
788 789 790 |
case IPC_INFO: { struct shminfo64 shminfo; |
e8148f758 ipc: clean up ipc... |
791 |
memset(&shminfo, 0, sizeof(shminfo)); |
4e9823111 [PATCH] IPC names... |
792 793 794 |
shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; shminfo.shmmax = ns->shm_ctlmax; shminfo.shmall = ns->shm_ctlall; |
1da177e4c Linux-2.6.12-rc2 |
795 796 797 798 |
shminfo.shmmin = SHMMIN; if(copy_shminfo_to_user (buf, &shminfo, version)) return -EFAULT; |
f4566f048 ipc: fix wrong co... |
799 |
|
33b746698 ipc: rename ids->... |
800 |
down_read(&shm_ids(ns).rwsem); |
7ca7e564e ipc: store ipcs i... |
801 |
err = ipc_get_maxid(&shm_ids(ns)); |
33b746698 ipc: rename ids->... |
802 |
up_read(&shm_ids(ns).rwsem); |
f4566f048 ipc: fix wrong co... |
803 |
|
1da177e4c Linux-2.6.12-rc2 |
804 805 806 807 808 809 810 |
if(err<0) err = 0; goto out; } case SHM_INFO: { struct shm_info shm_info; |
e8148f758 ipc: clean up ipc... |
811 |
memset(&shm_info, 0, sizeof(shm_info)); |
33b746698 ipc: rename ids->... |
812 |
down_read(&shm_ids(ns).rwsem); |
4e9823111 [PATCH] IPC names... |
813 814 815 |
shm_info.used_ids = shm_ids(ns).in_use; shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); shm_info.shm_tot = ns->shm_tot; |
1da177e4c Linux-2.6.12-rc2 |
816 817 |
shm_info.swap_attempts = 0; shm_info.swap_successes = 0; |
7ca7e564e ipc: store ipcs i... |
818 |
err = ipc_get_maxid(&shm_ids(ns)); |
33b746698 ipc: rename ids->... |
819 |
up_read(&shm_ids(ns).rwsem); |
e8148f758 ipc: clean up ipc... |
820 |
if (copy_to_user(buf, &shm_info, sizeof(shm_info))) { |
1da177e4c Linux-2.6.12-rc2 |
821 822 823 824 825 826 827 828 829 830 831 832 |
err = -EFAULT; goto out; } err = err < 0 ? 0 : err; goto out; } case SHM_STAT: case IPC_STAT: { struct shmid64_ds tbuf; int result; |
023a53557 ipc: integrate ip... |
833 |
|
c29c40392 ipc,shm: make shm... |
834 |
rcu_read_lock(); |
023a53557 ipc: integrate ip... |
835 |
if (cmd == SHM_STAT) { |
c29c40392 ipc,shm: make shm... |
836 |
shp = shm_obtain_object(ns, shmid); |
023a53557 ipc: integrate ip... |
837 838 |
if (IS_ERR(shp)) { err = PTR_ERR(shp); |
c29c40392 ipc,shm: make shm... |
839 |
goto out_unlock; |
023a53557 ipc: integrate ip... |
840 |
} |
7ca7e564e ipc: store ipcs i... |
841 |
result = shp->shm_perm.id; |
1da177e4c Linux-2.6.12-rc2 |
842 |
} else { |
c29c40392 ipc,shm: make shm... |
843 |
shp = shm_obtain_object_check(ns, shmid); |
023a53557 ipc: integrate ip... |
844 845 |
if (IS_ERR(shp)) { err = PTR_ERR(shp); |
c29c40392 ipc,shm: make shm... |
846 |
goto out_unlock; |
023a53557 ipc: integrate ip... |
847 |
} |
1da177e4c Linux-2.6.12-rc2 |
848 849 |
result = 0; } |
c29c40392 ipc,shm: make shm... |
850 |
|
e8148f758 ipc: clean up ipc... |
851 |
err = -EACCES; |
b0e77598f userns: user name... |
852 |
if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) |
1da177e4c Linux-2.6.12-rc2 |
853 |
goto out_unlock; |
c29c40392 ipc,shm: make shm... |
854 |
|
1da177e4c Linux-2.6.12-rc2 |
855 856 857 |
err = security_shm_shmctl(shp, cmd); if (err) goto out_unlock; |
c29c40392 ipc,shm: make shm... |
858 |
|
023a53557 ipc: integrate ip... |
859 |
memset(&tbuf, 0, sizeof(tbuf)); |
1da177e4c Linux-2.6.12-rc2 |
860 861 862 863 864 865 866 |
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm); tbuf.shm_segsz = shp->shm_segsz; tbuf.shm_atime = shp->shm_atim; tbuf.shm_dtime = shp->shm_dtim; tbuf.shm_ctime = shp->shm_ctim; tbuf.shm_cpid = shp->shm_cprid; tbuf.shm_lpid = shp->shm_lprid; |
bc56bba8f [PATCH] shm: make... |
867 |
tbuf.shm_nattch = shp->shm_nattch; |
c29c40392 ipc,shm: make shm... |
868 869 870 |
rcu_read_unlock(); if (copy_shmid_to_user(buf, &tbuf, version)) |
1da177e4c Linux-2.6.12-rc2 |
871 872 873 874 875 |
err = -EFAULT; else err = result; goto out; } |
d6187ddfc ipc,shm: introduc... |
876 877 878 879 880 |
default: return -EINVAL; } out_unlock: |
c29c40392 ipc,shm: make shm... |
881 |
rcu_read_unlock(); |
d6187ddfc ipc,shm: introduc... |
882 883 884 885 886 887 888 889 890 |
out: return err; } SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) { struct shmid_kernel *shp; int err, version; struct ipc_namespace *ns; |
00c88e695 ipc,shm: shorten ... |
891 892 |
if (cmd < 0 || shmid < 0) return -EINVAL; |
d6187ddfc ipc,shm: introduc... |
893 894 895 896 897 898 899 900 901 902 |
version = ipc_parse_version(&cmd); ns = current->nsproxy->ipc_ns; switch (cmd) { case IPC_INFO: case SHM_INFO: case SHM_STAT: case IPC_STAT: return shmctl_nolock(ns, shmid, cmd, version, buf); |
00c88e695 ipc,shm: shorten ... |
903 904 905 |
case IPC_RMID: case IPC_SET: return shmctl_down(ns, shmid, cmd, buf, version); |
1da177e4c Linux-2.6.12-rc2 |
906 907 908 |
case SHM_LOCK: case SHM_UNLOCK: { |
85046579b SHM_UNLOCK: fix l... |
909 |
struct file *shm_file; |
89e004ea5 SHM_LOCKED pages ... |
910 |
|
00c88e695 ipc,shm: shorten ... |
911 912 |
rcu_read_lock(); shp = shm_obtain_object_check(ns, shmid); |
023a53557 ipc: integrate ip... |
913 914 |
if (IS_ERR(shp)) { err = PTR_ERR(shp); |
00c88e695 ipc,shm: shorten ... |
915 |
goto out_unlock1; |
1da177e4c Linux-2.6.12-rc2 |
916 |
} |
1da177e4c Linux-2.6.12-rc2 |
917 |
|
a33e67510 sanitize audit_ip... |
918 |
audit_ipc_obj(&(shp->shm_perm)); |
00c88e695 ipc,shm: shorten ... |
919 920 921 |
err = security_shm_shmctl(shp, cmd); if (err) goto out_unlock1; |
073115d6b [PATCH] Rework of... |
922 |
|
00c88e695 ipc,shm: shorten ... |
923 |
ipc_lock_object(&shp->shm_perm); |
b0e77598f userns: user name... |
924 |
if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { |
1efdb69b0 userns: Convert i... |
925 |
kuid_t euid = current_euid(); |
1da177e4c Linux-2.6.12-rc2 |
926 |
err = -EPERM; |
1efdb69b0 userns: Convert i... |
927 928 |
if (!uid_eq(euid, shp->shm_perm.uid) && !uid_eq(euid, shp->shm_perm.cuid)) |
00c88e695 ipc,shm: shorten ... |
929 |
goto out_unlock0; |
f1eb1332b ipc: use rlimit h... |
930 |
if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) |
00c88e695 ipc,shm: shorten ... |
931 |
goto out_unlock0; |
1da177e4c Linux-2.6.12-rc2 |
932 |
} |
85046579b SHM_UNLOCK: fix l... |
933 934 |
shm_file = shp->shm_file; if (is_file_hugepages(shm_file)) |
00c88e695 ipc,shm: shorten ... |
935 |
goto out_unlock0; |
85046579b SHM_UNLOCK: fix l... |
936 937 |
if (cmd == SHM_LOCK) { |
86a264abe CRED: Wrap curren... |
938 |
struct user_struct *user = current_user(); |
85046579b SHM_UNLOCK: fix l... |
939 940 941 942 |
err = shmem_lock(shm_file, 1, user); if (!err && !(shp->shm_perm.mode & SHM_LOCKED)) { shp->shm_perm.mode |= SHM_LOCKED; shp->mlock_user = user; |
1da177e4c Linux-2.6.12-rc2 |
943 |
} |
00c88e695 ipc,shm: shorten ... |
944 |
goto out_unlock0; |
1da177e4c Linux-2.6.12-rc2 |
945 |
} |
85046579b SHM_UNLOCK: fix l... |
946 947 948 |
/* SHM_UNLOCK */ if (!(shp->shm_perm.mode & SHM_LOCKED)) |
00c88e695 ipc,shm: shorten ... |
949 |
goto out_unlock0; |
85046579b SHM_UNLOCK: fix l... |
950 951 952 953 |
shmem_lock(shm_file, 0, shp->mlock_user); shp->shm_perm.mode &= ~SHM_LOCKED; shp->mlock_user = NULL; get_file(shm_file); |
00c88e695 ipc,shm: shorten ... |
954 955 |
ipc_unlock_object(&shp->shm_perm); rcu_read_unlock(); |
245132643 SHM_UNLOCK: fix U... |
956 |
shmem_unlock_mapping(shm_file->f_mapping); |
00c88e695 ipc,shm: shorten ... |
957 |
|
85046579b SHM_UNLOCK: fix l... |
958 |
fput(shm_file); |
8d4cc8b5c IPC/shared memory... |
959 |
return err; |
00c88e695 ipc,shm: shorten ... |
960 |
} |
1da177e4c Linux-2.6.12-rc2 |
961 |
default: |
8d4cc8b5c IPC/shared memory... |
962 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
963 |
} |
00c88e695 ipc,shm: shorten ... |
964 965 966 967 |
out_unlock0: ipc_unlock_object(&shp->shm_perm); out_unlock1: rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
968 969 970 971 972 973 974 975 976 977 |
return err; } /* * Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists. * * NOTE! Despite the name, this is NOT a direct system call entrypoint. The * "raddr" thing points to kernel space, and there has to be a wrapper around * this. */ |
079a96ae3 ipc: add COMPAT_S... |
978 979 |
long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, unsigned long shmlba) |
1da177e4c Linux-2.6.12-rc2 |
980 981 982 983 984 985 986 987 |
{ struct shmid_kernel *shp; unsigned long addr; unsigned long size; struct file * file; int err; unsigned long flags; unsigned long prot; |
1da177e4c Linux-2.6.12-rc2 |
988 |
int acc_mode; |
4e9823111 [PATCH] IPC names... |
989 |
struct ipc_namespace *ns; |
bc56bba8f [PATCH] shm: make... |
990 991 |
struct shm_file_data *sfd; struct path path; |
aeb5d7270 [PATCH] introduce... |
992 |
fmode_t f_mode; |
41badc15c mm: make do_mmap_... |
993 |
unsigned long populate = 0; |
1da177e4c Linux-2.6.12-rc2 |
994 |
|
bc56bba8f [PATCH] shm: make... |
995 996 |
err = -EINVAL; if (shmid < 0) |
1da177e4c Linux-2.6.12-rc2 |
997 |
goto out; |
bc56bba8f [PATCH] shm: make... |
998 |
else if ((addr = (ulong)shmaddr)) { |
079a96ae3 ipc: add COMPAT_S... |
999 |
if (addr & (shmlba - 1)) { |
1da177e4c Linux-2.6.12-rc2 |
1000 |
if (shmflg & SHM_RND) |
079a96ae3 ipc: add COMPAT_S... |
1001 |
addr &= ~(shmlba - 1); /* round down */ |
1da177e4c Linux-2.6.12-rc2 |
1002 1003 1004 1005 |
else #ifndef __ARCH_FORCE_SHMLBA if (addr & ~PAGE_MASK) #endif |
bc56bba8f [PATCH] shm: make... |
1006 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1007 1008 1009 1010 |
} flags = MAP_SHARED | MAP_FIXED; } else { if ((shmflg & SHM_REMAP)) |
bc56bba8f [PATCH] shm: make... |
1011 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1012 1013 1014 1015 1016 1017 |
flags = MAP_SHARED; } if (shmflg & SHM_RDONLY) { prot = PROT_READ; |
1da177e4c Linux-2.6.12-rc2 |
1018 |
acc_mode = S_IRUGO; |
bc56bba8f [PATCH] shm: make... |
1019 |
f_mode = FMODE_READ; |
1da177e4c Linux-2.6.12-rc2 |
1020 1021 |
} else { prot = PROT_READ | PROT_WRITE; |
1da177e4c Linux-2.6.12-rc2 |
1022 |
acc_mode = S_IRUGO | S_IWUGO; |
bc56bba8f [PATCH] shm: make... |
1023 |
f_mode = FMODE_READ | FMODE_WRITE; |
1da177e4c Linux-2.6.12-rc2 |
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 |
} if (shmflg & SHM_EXEC) { prot |= PROT_EXEC; acc_mode |= S_IXUGO; } /* * We cannot rely on the fs check since SYSV IPC does have an * additional creator id... */ |
4e9823111 [PATCH] IPC names... |
1034 |
ns = current->nsproxy->ipc_ns; |
bd58e2dc2 ipc,shm: shorten ... |
1035 1036 |
rcu_read_lock(); shp = shm_obtain_object_check(ns, shmid); |
023a53557 ipc: integrate ip... |
1037 1038 |
if (IS_ERR(shp)) { err = PTR_ERR(shp); |
bd58e2dc2 ipc,shm: shorten ... |
1039 |
goto out_unlock; |
023a53557 ipc: integrate ip... |
1040 |
} |
bc56bba8f [PATCH] shm: make... |
1041 1042 |
err = -EACCES; |
b0e77598f userns: user name... |
1043 |
if (ipcperms(ns, &shp->shm_perm, acc_mode)) |
bc56bba8f [PATCH] shm: make... |
1044 |
goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
1045 1046 |
err = security_shm_shmat(shp, shmaddr, shmflg); |
bc56bba8f [PATCH] shm: make... |
1047 1048 |
if (err) goto out_unlock; |
bd58e2dc2 ipc,shm: shorten ... |
1049 |
ipc_lock_object(&shp->shm_perm); |
2c48b9c45 switch alloc_file... |
1050 1051 |
path = shp->shm_file->f_path; path_get(&path); |
1da177e4c Linux-2.6.12-rc2 |
1052 |
shp->shm_nattch++; |
bc56bba8f [PATCH] shm: make... |
1053 |
size = i_size_read(path.dentry->d_inode); |
bd58e2dc2 ipc,shm: shorten ... |
1054 1055 |
ipc_unlock_object(&shp->shm_perm); rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
1056 |
|
bc56bba8f [PATCH] shm: make... |
1057 1058 |
err = -ENOMEM; sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); |
247ec302b ipc,shm: cleanup ... |
1059 1060 1061 1062 |
if (!sfd) { path_put(&path); goto out_nattch; } |
bc56bba8f [PATCH] shm: make... |
1063 |
|
2c48b9c45 switch alloc_file... |
1064 1065 |
file = alloc_file(&path, f_mode, is_file_hugepages(shp->shm_file) ? |
c4caa7781 file ->get_unmapp... |
1066 1067 |
&shm_file_operations_huge : &shm_file_operations); |
39b652527 fs: Preserve erro... |
1068 |
err = PTR_ERR(file); |
247ec302b ipc,shm: cleanup ... |
1069 1070 1071 1072 1073 |
if (IS_ERR(file)) { kfree(sfd); path_put(&path); goto out_nattch; } |
bc56bba8f [PATCH] shm: make... |
1074 |
|
bc56bba8f [PATCH] shm: make... |
1075 |
file->private_data = sfd; |
bc56bba8f [PATCH] shm: make... |
1076 |
file->f_mapping = shp->shm_file->f_mapping; |
7ca7e564e ipc: store ipcs i... |
1077 |
sfd->id = shp->shm_perm.id; |
bc56bba8f [PATCH] shm: make... |
1078 1079 1080 |
sfd->ns = get_ipc_ns(ns); sfd->file = shp->shm_file; sfd->vm_ops = NULL; |
8b3ec6814 take security_mma... |
1081 1082 1083 |
err = security_mmap_file(file, prot, flags); if (err) goto out_fput; |
1da177e4c Linux-2.6.12-rc2 |
1084 1085 |
down_write(¤t->mm->mmap_sem); if (addr && !(shmflg & SHM_REMAP)) { |
bc56bba8f [PATCH] shm: make... |
1086 |
err = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 |
if (find_vma_intersection(current->mm, addr, addr + size)) goto invalid; /* * If shm segment goes below stack, make sure there is some * space left for the stack to grow (at least 4 pages). */ if (addr < current->mm->start_stack && addr > current->mm->start_stack - size - PAGE_SIZE * 5) goto invalid; } |
247ec302b ipc,shm: cleanup ... |
1097 |
|
bebeb3d68 mm: introduce mm_... |
1098 1099 |
addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate); *raddr = addr; |
bc56bba8f [PATCH] shm: make... |
1100 |
err = 0; |
bebeb3d68 mm: introduce mm_... |
1101 1102 |
if (IS_ERR_VALUE(addr)) err = (long)addr; |
1da177e4c Linux-2.6.12-rc2 |
1103 1104 |
invalid: up_write(¤t->mm->mmap_sem); |
bebeb3d68 mm: introduce mm_... |
1105 |
if (populate) |
41badc15c mm: make do_mmap_... |
1106 |
mm_populate(addr, populate); |
1da177e4c Linux-2.6.12-rc2 |
1107 |
|
8b3ec6814 take security_mma... |
1108 |
out_fput: |
bc56bba8f [PATCH] shm: make... |
1109 1110 1111 |
fput(file); out_nattch: |
33b746698 ipc: rename ids->... |
1112 |
down_write(&shm_ids(ns).rwsem); |
00c2bf85d ipc: get rid of i... |
1113 |
shp = shm_lock(ns, shmid); |
023a53557 ipc: integrate ip... |
1114 |
BUG_ON(IS_ERR(shp)); |
1da177e4c Linux-2.6.12-rc2 |
1115 |
shp->shm_nattch--; |
b34a6b1da ipc: introduce sh... |
1116 |
if (shm_may_destroy(ns, shp)) |
4e9823111 [PATCH] IPC names... |
1117 |
shm_destroy(ns, shp); |
1da177e4c Linux-2.6.12-rc2 |
1118 1119 |
else shm_unlock(shp); |
33b746698 ipc: rename ids->... |
1120 |
up_write(&shm_ids(ns).rwsem); |
1da177e4c Linux-2.6.12-rc2 |
1121 |
return err; |
bc56bba8f [PATCH] shm: make... |
1122 1123 |
out_unlock: |
bd58e2dc2 ipc,shm: shorten ... |
1124 |
rcu_read_unlock(); |
247ec302b ipc,shm: cleanup ... |
1125 1126 |
out: return err; |
1da177e4c Linux-2.6.12-rc2 |
1127 |
} |
d5460c997 [CVE-2009-0029] S... |
1128 |
SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) |
7d87e14c2 [PATCH] consolida... |
1129 1130 1131 |
{ unsigned long ret; long err; |
079a96ae3 ipc: add COMPAT_S... |
1132 |
err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA); |
7d87e14c2 [PATCH] consolida... |
1133 1134 1135 1136 1137 |
if (err) return err; force_successful_syscall_return(); return (long)ret; } |
1da177e4c Linux-2.6.12-rc2 |
1138 1139 1140 1141 |
/* * detach and kill segment if marked destroyed. * The work is done in shm_close. */ |
d5460c997 [CVE-2009-0029] S... |
1142 |
SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) |
1da177e4c Linux-2.6.12-rc2 |
1143 1144 |
{ struct mm_struct *mm = current->mm; |
586c7e6a2 shm: fix unused w... |
1145 |
struct vm_area_struct *vma; |
1da177e4c Linux-2.6.12-rc2 |
1146 |
unsigned long addr = (unsigned long)shmaddr; |
1da177e4c Linux-2.6.12-rc2 |
1147 |
int retval = -EINVAL; |
586c7e6a2 shm: fix unused w... |
1148 1149 1150 1151 |
#ifdef CONFIG_MMU loff_t size = 0; struct vm_area_struct *next; #endif |
1da177e4c Linux-2.6.12-rc2 |
1152 |
|
df1e2fb54 [PATCH] shmdt: ch... |
1153 1154 |
if (addr & ~PAGE_MASK) return retval; |
1da177e4c Linux-2.6.12-rc2 |
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 |
down_write(&mm->mmap_sem); /* * This function tries to be smart and unmap shm segments that * were modified by partial mlock or munmap calls: * - It first determines the size of the shm segment that should be * unmapped: It searches for a vma that is backed by shm and that * started at address shmaddr. It records it's size and then unmaps * it. * - Then it unmaps all shm vmas that started at shmaddr and that * are within the initially determined size. * Errors from do_munmap are ignored: the function only fails if * it's called with invalid parameters or if it's called to unmap * a part of a vma. Both calls in this function are for full vmas, * the parameters are directly copied from the vma itself and always * valid - therefore do_munmap cannot fail. (famous last words?) */ /* * If it had been mremap()'d, the starting address would not * match the usual checks anyway. So assume all vma's are * above the starting address given. */ vma = find_vma(mm, addr); |
8feae1311 NOMMU: Make VMAs ... |
1178 |
#ifdef CONFIG_MMU |
1da177e4c Linux-2.6.12-rc2 |
1179 1180 1181 1182 1183 1184 1185 1186 |
while (vma) { next = vma->vm_next; /* * Check if the starting address would match, i.e. it's * a fragment created by mprotect() and/or munmap(), or it * otherwise it starts at this address with no hassles. */ |
bc56bba8f [PATCH] shm: make... |
1187 |
if ((vma->vm_ops == &shm_vm_ops) && |
1da177e4c Linux-2.6.12-rc2 |
1188 |
(vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) { |
496ad9aa8 new helper: file_... |
1189 |
size = file_inode(vma->vm_file)->i_size; |
1da177e4c Linux-2.6.12-rc2 |
1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 |
do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); /* * We discovered the size of the shm segment, so * break out of here and fall through to the next * loop that uses the size information to stop * searching for matching vma's. */ retval = 0; vma = next; break; } vma = next; } /* * We need look no further than the maximum address a fragment * could possibly have landed at. Also cast things to loff_t to |
25985edce Fix common misspe... |
1207 |
* prevent overflows and make comparisons vs. equal-width types. |
1da177e4c Linux-2.6.12-rc2 |
1208 |
*/ |
8e36709d8 [PATCH] shmdt can... |
1209 |
size = PAGE_ALIGN(size); |
1da177e4c Linux-2.6.12-rc2 |
1210 1211 1212 1213 |
while (vma && (loff_t)(vma->vm_end - addr) <= size) { next = vma->vm_next; /* finding a matching vma now does not alter retval */ |
bc56bba8f [PATCH] shm: make... |
1214 |
if ((vma->vm_ops == &shm_vm_ops) && |
1da177e4c Linux-2.6.12-rc2 |
1215 1216 1217 1218 1219 |
(vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); vma = next; } |
8feae1311 NOMMU: Make VMAs ... |
1220 1221 1222 |
#else /* CONFIG_MMU */ /* under NOMMU conditions, the exact address to be destroyed must be * given */ |
48ec782ce ipc, shm: guard a... |
1223 |
if (vma && vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) { |
8feae1311 NOMMU: Make VMAs ... |
1224 1225 1226 1227 1228 |
do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); retval = 0; } #endif |
1da177e4c Linux-2.6.12-rc2 |
1229 1230 1231 1232 1233 |
up_write(&mm->mmap_sem); return retval; } #ifdef CONFIG_PROC_FS |
19b4946ca [PATCH] ipc: conv... |
1234 |
static int sysvipc_shm_proc_show(struct seq_file *s, void *it) |
1da177e4c Linux-2.6.12-rc2 |
1235 |
{ |
1efdb69b0 userns: Convert i... |
1236 |
struct user_namespace *user_ns = seq_user_ns(s); |
19b4946ca [PATCH] ipc: conv... |
1237 |
struct shmid_kernel *shp = it; |
b79521807 ipc/shm.c: add RS... |
1238 1239 1240 |
unsigned long rss = 0, swp = 0; shm_add_rss_swap(shp, &rss, &swp); |
1da177e4c Linux-2.6.12-rc2 |
1241 |
|
6c826818f /proc/sysvipc/shm... |
1242 1243 1244 1245 1246 |
#if BITS_PER_LONG <= 32 #define SIZE_SPEC "%10lu" #else #define SIZE_SPEC "%21lu" #endif |
1da177e4c Linux-2.6.12-rc2 |
1247 |
|
6c826818f /proc/sysvipc/shm... |
1248 1249 |
return seq_printf(s, "%10d %10d %4o " SIZE_SPEC " %5u %5u " |
b79521807 ipc/shm.c: add RS... |
1250 1251 1252 |
"%5lu %5u %5u %5u %5u %10lu %10lu %10lu " SIZE_SPEC " " SIZE_SPEC " ", |
19b4946ca [PATCH] ipc: conv... |
1253 |
shp->shm_perm.key, |
7ca7e564e ipc: store ipcs i... |
1254 |
shp->shm_perm.id, |
b33291c0b [PATCH] ipc: expa... |
1255 |
shp->shm_perm.mode, |
19b4946ca [PATCH] ipc: conv... |
1256 1257 1258 |
shp->shm_segsz, shp->shm_cprid, shp->shm_lprid, |
bc56bba8f [PATCH] shm: make... |
1259 |
shp->shm_nattch, |
1efdb69b0 userns: Convert i... |
1260 1261 1262 1263 |
from_kuid_munged(user_ns, shp->shm_perm.uid), from_kgid_munged(user_ns, shp->shm_perm.gid), from_kuid_munged(user_ns, shp->shm_perm.cuid), from_kgid_munged(user_ns, shp->shm_perm.cgid), |
19b4946ca [PATCH] ipc: conv... |
1264 1265 |
shp->shm_atim, shp->shm_dtim, |
b79521807 ipc/shm.c: add RS... |
1266 1267 1268 |
shp->shm_ctim, rss * PAGE_SIZE, swp * PAGE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
1269 1270 |
} #endif |