Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/ipc/shm.c (Version 2.6.25.8) and /linux/ipc/shm.c (Version 2.6.11.8)


  1 /*                                                  1 /*
  2  * linux/ipc/shm.c                                  2  * linux/ipc/shm.c
  3  * Copyright (C) 1992, 1993 Krishna Balasubram      3  * Copyright (C) 1992, 1993 Krishna Balasubramanian
  4  *       Many improvements/fixes by Bruno Haib      4  *       Many improvements/fixes by Bruno Haible.
  5  * Replaced `struct shm_desc' by `struct vm_ar      5  * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994.
  6  * Fixed the shm swap deallocation (shm_unuse(      6  * Fixed the shm swap deallocation (shm_unuse()), August 1998 Andrea Arcangeli.
  7  *                                                  7  *
  8  * /proc/sysvipc/shm support (c) 1999 Dragos A      8  * /proc/sysvipc/shm support (c) 1999 Dragos Acostachioaie <dragos@iname.com>
  9  * BIGMEM support, Andrea Arcangeli <andrea@su      9  * BIGMEM support, Andrea Arcangeli <andrea@suse.de>
 10  * SMP thread shm, Jean-Luc Boyard <jean-luc.b     10  * SMP thread shm, Jean-Luc Boyard <jean-luc.boyard@siemens.fr>
 11  * HIGHMEM support, Ingo Molnar <mingo@redhat.     11  * HIGHMEM support, Ingo Molnar <mingo@redhat.com>
 12  * Make shmmax, shmall, shmmni sysctl'able, Ch     12  * Make shmmax, shmall, shmmni sysctl'able, Christoph Rohland <cr@sap.com>
 13  * Shared /dev/zero support, Kanoj Sarcar <kan     13  * Shared /dev/zero support, Kanoj Sarcar <kanoj@sgi.com>
 14  * Move the mm functionality over to mm/shmem.     14  * Move the mm functionality over to mm/shmem.c, Christoph Rohland <cr@sap.com>
 15  *                                                 15  *
 16  * support for audit of ipc object properties  << 
 17  * Dustin Kirkland <dustin.kirkland@us.ibm.com << 
 18  *                                             << 
 19  * namespaces support                          << 
 20  * OpenVZ, SWsoft Inc.                         << 
 21  * Pavel Emelianov <xemul@openvz.org>          << 
 22  */                                                16  */
 23                                                    17 
                                                   >>  18 #include <linux/config.h>
 24 #include <linux/slab.h>                            19 #include <linux/slab.h>
 25 #include <linux/mm.h>                              20 #include <linux/mm.h>
 26 #include <linux/hugetlb.h>                         21 #include <linux/hugetlb.h>
 27 #include <linux/shm.h>                             22 #include <linux/shm.h>
 28 #include <linux/init.h>                            23 #include <linux/init.h>
 29 #include <linux/file.h>                            24 #include <linux/file.h>
 30 #include <linux/mman.h>                            25 #include <linux/mman.h>
                                                   >>  26 #include <linux/proc_fs.h>
 31 #include <linux/shmem_fs.h>                        27 #include <linux/shmem_fs.h>
 32 #include <linux/security.h>                        28 #include <linux/security.h>
 33 #include <linux/syscalls.h>                        29 #include <linux/syscalls.h>
 34 #include <linux/audit.h>                       << 
 35 #include <linux/capability.h>                  << 
 36 #include <linux/ptrace.h>                      << 
 37 #include <linux/seq_file.h>                    << 
 38 #include <linux/rwsem.h>                       << 
 39 #include <linux/nsproxy.h>                     << 
 40 #include <linux/mount.h>                       << 
 41 #include <linux/ipc_namespace.h>               << 
 42                                                << 
 43 #include <asm/uaccess.h>                           30 #include <asm/uaccess.h>
 44                                                    31 
 45 #include "util.h"                                  32 #include "util.h"
 46                                                    33 
 47 struct shm_file_data {                         !!  34 #define shm_flags       shm_perm.mode
 48         int id;                                << 
 49         struct ipc_namespace *ns;              << 
 50         struct file *file;                     << 
 51         const struct vm_operations_struct *vm_ << 
 52 };                                             << 
 53                                                << 
 54 #define shm_file_data(file) (*((struct shm_fil << 
 55                                                    35 
 56 static const struct file_operations shm_file_o !!  36 static struct file_operations shm_file_operations;
 57 static struct vm_operations_struct shm_vm_ops;     37 static struct vm_operations_struct shm_vm_ops;
 58                                                    38 
 59 #define shm_ids(ns)     ((ns)->ids[IPC_SHM_IDS !!  39 static struct ipc_ids shm_ids;
 60                                                    40 
 61 #define shm_unlock(shp)                 \      !!  41 #define shm_lock(id)    ((struct shmid_kernel*)ipc_lock(&shm_ids,id))
 62         ipc_unlock(&(shp)->shm_perm)           !!  42 #define shm_unlock(shp) ipc_unlock(&(shp)->shm_perm)
 63 #define shm_buildid(id, seq)    ipc_buildid(id !!  43 #define shm_get(id)     ((struct shmid_kernel*)ipc_get(&shm_ids,id))
 64                                                !!  44 #define shm_buildid(id, seq) \
 65 static int newseg(struct ipc_namespace *, stru !!  45         ipc_buildid(&shm_ids, id, seq)
 66 static void shm_open(struct vm_area_struct *vm !!  46 
 67 static void shm_close(struct vm_area_struct *v !!  47 static int newseg (key_t key, int shmflg, size_t size);
 68 static void shm_destroy (struct ipc_namespace  !!  48 static void shm_open (struct vm_area_struct *shmd);
                                                   >>  49 static void shm_close (struct vm_area_struct *shmd);
 69 #ifdef CONFIG_PROC_FS                              50 #ifdef CONFIG_PROC_FS
 70 static int sysvipc_shm_proc_show(struct seq_fi !!  51 static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
 71 #endif                                             52 #endif
 72                                                    53 
 73 void shm_init_ns(struct ipc_namespace *ns)     !!  54 size_t  shm_ctlmax = SHMMAX;
 74 {                                              !!  55 size_t  shm_ctlall = SHMALL;
 75         ns->shm_ctlmax = SHMMAX;               !!  56 int     shm_ctlmni = SHMMNI;
 76         ns->shm_ctlall = SHMALL;               << 
 77         ns->shm_ctlmni = SHMMNI;               << 
 78         ns->shm_tot = 0;                       << 
 79         ipc_init_ids(&ns->ids[IPC_SHM_IDS]);   << 
 80 }                                              << 
 81                                                << 
 82 /*                                             << 
 83  * Called with shm_ids.rw_mutex (writer) and t << 
 84  * Only shm_ids.rw_mutex remains locked on exi << 
 85  */                                            << 
 86 static void do_shm_rmid(struct ipc_namespace * << 
 87 {                                              << 
 88         struct shmid_kernel *shp;              << 
 89         shp = container_of(ipcp, struct shmid_ << 
 90                                                << 
 91         if (shp->shm_nattch){                  << 
 92                 shp->shm_perm.mode |= SHM_DEST << 
 93                 /* Do not find it any more */  << 
 94                 shp->shm_perm.key = IPC_PRIVAT << 
 95                 shm_unlock(shp);               << 
 96         } else                                 << 
 97                 shm_destroy(ns, shp);          << 
 98 }                                              << 
 99                                                    57 
100 #ifdef CONFIG_IPC_NS                           !!  58 static int shm_tot; /* total number of shared memory pages */
101 void shm_exit_ns(struct ipc_namespace *ns)     << 
102 {                                              << 
103         free_ipcs(ns, &shm_ids(ns), do_shm_rmi << 
104 }                                              << 
105 #endif                                         << 
106                                                    59 
107 void __init shm_init (void)                        60 void __init shm_init (void)
108 {                                                  61 {
109         shm_init_ns(&init_ipc_ns);             !!  62         ipc_init_ids(&shm_ids, 1);
110         ipc_init_proc_interface("sysvipc/shm", !!  63 #ifdef CONFIG_PROC_FS
111                                 "       key    !!  64         create_proc_read_entry("sysvipc/shm", 0, NULL, sysvipc_shm_read_proc, NULL);
112                                 IPC_SHM_IDS, s !!  65 #endif
113 }                                              << 
114                                                << 
115 /*                                             << 
116  * shm_lock_(check_)down routines are called i << 
117  * is held to protect access to the idr tree.  << 
118  */                                            << 
119 static inline struct shmid_kernel *shm_lock_do << 
120                                                << 
121 {                                              << 
122         struct kern_ipc_perm *ipcp = ipc_lock_ << 
123                                                << 
124         if (IS_ERR(ipcp))                      << 
125                 return (struct shmid_kernel *) << 
126                                                << 
127         return container_of(ipcp, struct shmid << 
128 }                                              << 
129                                                << 
130 static inline struct shmid_kernel *shm_lock_ch << 
131                                                << 
132                                                << 
133 {                                              << 
134         struct kern_ipc_perm *ipcp = ipc_lock_ << 
135                                                << 
136         if (IS_ERR(ipcp))                      << 
137                 return (struct shmid_kernel *) << 
138                                                << 
139         return container_of(ipcp, struct shmid << 
140 }                                              << 
141                                                << 
142 /*                                             << 
143  * shm_lock_(check_) routines are called in th << 
144  * is not held.                                << 
145  */                                            << 
146 static inline struct shmid_kernel *shm_lock(st << 
147 {                                              << 
148         struct kern_ipc_perm *ipcp = ipc_lock( << 
149                                                << 
150         if (IS_ERR(ipcp))                      << 
151                 return (struct shmid_kernel *) << 
152                                                << 
153         return container_of(ipcp, struct shmid << 
154 }                                                  66 }
155                                                    67 
156 static inline struct shmid_kernel *shm_lock_ch !!  68 static inline int shm_checkid(struct shmid_kernel *s, int id)
157                                                << 
158 {                                                  69 {
159         struct kern_ipc_perm *ipcp = ipc_lock_ !!  70         if (ipc_checkid(&shm_ids,&s->shm_perm,id))
160                                                !!  71                 return -EIDRM;
161         if (IS_ERR(ipcp))                      !!  72         return 0;
162                 return (struct shmid_kernel *) << 
163                                                << 
164         return container_of(ipcp, struct shmid << 
165 }                                                  73 }
166                                                    74 
167 static inline void shm_rmid(struct ipc_namespa !!  75 static inline struct shmid_kernel *shm_rmid(int id)
168 {                                                  76 {
169         ipc_rmid(&shm_ids(ns), &s->shm_perm);  !!  77         return (struct shmid_kernel *)ipc_rmid(&shm_ids,id);
170 }                                                  78 }
171                                                    79 
172 static inline int shm_addid(struct ipc_namespa !!  80 static inline int shm_addid(struct shmid_kernel *shp)
173 {                                                  81 {
174         return ipc_addid(&shm_ids(ns), &shp->s !!  82         return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni);
175 }                                                  83 }
176                                                    84 
177                                                    85 
178                                                    86 
179 /* This is called by fork, once for every shm  !!  87 static inline void shm_inc (int id) {
180 static void shm_open(struct vm_area_struct *vm << 
181 {                                              << 
182         struct file *file = vma->vm_file;      << 
183         struct shm_file_data *sfd = shm_file_d << 
184         struct shmid_kernel *shp;                  88         struct shmid_kernel *shp;
185                                                    89 
186         shp = shm_lock(sfd->ns, sfd->id);      !!  90         if(!(shp = shm_lock(id)))
187         BUG_ON(IS_ERR(shp));                   !!  91                 BUG();
188         shp->shm_atim = get_seconds();             92         shp->shm_atim = get_seconds();
189         shp->shm_lprid = task_tgid_vnr(current !!  93         shp->shm_lprid = current->tgid;
190         shp->shm_nattch++;                         94         shp->shm_nattch++;
191         shm_unlock(shp);                           95         shm_unlock(shp);
192 }                                                  96 }
193                                                    97 
                                                   >>  98 /* This is called by fork, once for every shm attach. */
                                                   >>  99 static void shm_open (struct vm_area_struct *shmd)
                                                   >> 100 {
                                                   >> 101         shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
                                                   >> 102 }
                                                   >> 103 
194 /*                                                104 /*
195  * shm_destroy - free the struct shmid_kernel     105  * shm_destroy - free the struct shmid_kernel
196  *                                                106  *
197  * @ns: namespace                              << 
198  * @shp: struct to free                           107  * @shp: struct to free
199  *                                                108  *
200  * It has to be called with shp and shm_ids.rw !! 109  * It has to be called with shp and shm_ids.sem locked,
201  * but returns with shp unlocked and freed.       110  * but returns with shp unlocked and freed.
202  */                                               111  */
203 static void shm_destroy(struct ipc_namespace * !! 112 static void shm_destroy (struct shmid_kernel *shp)
204 {                                                 113 {
205         ns->shm_tot -= (shp->shm_segsz + PAGE_ !! 114         shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
206         shm_rmid(ns, shp);                     !! 115         shm_rmid (shp->id);
207         shm_unlock(shp);                          116         shm_unlock(shp);
208         if (!is_file_hugepages(shp->shm_file))    117         if (!is_file_hugepages(shp->shm_file))
209                 shmem_lock(shp->shm_file, 0, s    118                 shmem_lock(shp->shm_file, 0, shp->mlock_user);
210         else                                      119         else
211                 user_shm_unlock(shp->shm_file- !! 120                 user_shm_unlock(shp->shm_file->f_dentry->d_inode->i_size,
212                                                   121                                                 shp->mlock_user);
213         fput (shp->shm_file);                     122         fput (shp->shm_file);
214         security_shm_free(shp);                   123         security_shm_free(shp);
215         ipc_rcu_putref(shp);                      124         ipc_rcu_putref(shp);
216 }                                                 125 }
217                                                   126 
218 /*                                                127 /*
219  * remove the attach descriptor vma.           !! 128  * remove the attach descriptor shmd.
220  * free memory for segment if it is marked des    129  * free memory for segment if it is marked destroyed.
221  * The descriptor has already been removed fro    130  * The descriptor has already been removed from the current->mm->mmap list
222  * and will later be kfree()d.                    131  * and will later be kfree()d.
223  */                                               132  */
224 static void shm_close(struct vm_area_struct *v !! 133 static void shm_close (struct vm_area_struct *shmd)
225 {                                                 134 {
226         struct file * file = vma->vm_file;     !! 135         struct file * file = shmd->vm_file;
227         struct shm_file_data *sfd = shm_file_d !! 136         int id = file->f_dentry->d_inode->i_ino;
228         struct shmid_kernel *shp;                 137         struct shmid_kernel *shp;
229         struct ipc_namespace *ns = sfd->ns;    << 
230                                                   138 
231         down_write(&shm_ids(ns).rw_mutex);     !! 139         down (&shm_ids.sem);
232         /* remove from the list of attaches of    140         /* remove from the list of attaches of the shm segment */
233         shp = shm_lock_down(ns, sfd->id);      !! 141         if(!(shp = shm_lock(id)))
234         BUG_ON(IS_ERR(shp));                   !! 142                 BUG();
235         shp->shm_lprid = task_tgid_vnr(current !! 143         shp->shm_lprid = current->tgid;
236         shp->shm_dtim = get_seconds();            144         shp->shm_dtim = get_seconds();
237         shp->shm_nattch--;                        145         shp->shm_nattch--;
238         if(shp->shm_nattch == 0 &&                146         if(shp->shm_nattch == 0 &&
239            shp->shm_perm.mode & SHM_DEST)      !! 147            shp->shm_flags & SHM_DEST)
240                 shm_destroy(ns, shp);          !! 148                 shm_destroy (shp);
241         else                                      149         else
242                 shm_unlock(shp);                  150                 shm_unlock(shp);
243         up_write(&shm_ids(ns).rw_mutex);       !! 151         up (&shm_ids.sem);
244 }                                              << 
245                                                << 
246 static int shm_fault(struct vm_area_struct *vm << 
247 {                                              << 
248         struct file *file = vma->vm_file;      << 
249         struct shm_file_data *sfd = shm_file_d << 
250                                                << 
251         return sfd->vm_ops->fault(vma, vmf);   << 
252 }                                              << 
253                                                << 
254 #ifdef CONFIG_NUMA                             << 
255 static int shm_set_policy(struct vm_area_struc << 
256 {                                              << 
257         struct file *file = vma->vm_file;      << 
258         struct shm_file_data *sfd = shm_file_d << 
259         int err = 0;                           << 
260         if (sfd->vm_ops->set_policy)           << 
261                 err = sfd->vm_ops->set_policy( << 
262         return err;                            << 
263 }                                              << 
264                                                << 
265 static struct mempolicy *shm_get_policy(struct << 
266                                         unsign << 
267 {                                              << 
268         struct file *file = vma->vm_file;      << 
269         struct shm_file_data *sfd = shm_file_d << 
270         struct mempolicy *pol = NULL;          << 
271                                                << 
272         if (sfd->vm_ops->get_policy)           << 
273                 pol = sfd->vm_ops->get_policy( << 
274         else if (vma->vm_policy) {             << 
275                 pol = vma->vm_policy;          << 
276                 mpol_get(pol);  /* get_vma_pol << 
277         } else                                 << 
278                 pol = current->mempolicy;      << 
279         return pol;                            << 
280 }                                                 152 }
281 #endif                                         << 
282                                                   153 
283 static int shm_mmap(struct file * file, struct    154 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
284 {                                                 155 {
285         struct shm_file_data *sfd = shm_file_d !! 156         file_accessed(file);
286         int ret;                               << 
287                                                << 
288         ret = sfd->file->f_op->mmap(sfd->file, << 
289         if (ret != 0)                          << 
290                 return ret;                    << 
291         sfd->vm_ops = vma->vm_ops;             << 
292 #ifdef CONFIG_MMU                              << 
293         BUG_ON(!sfd->vm_ops->fault);           << 
294 #endif                                         << 
295         vma->vm_ops = &shm_vm_ops;                157         vma->vm_ops = &shm_vm_ops;
296         shm_open(vma);                         !! 158         shm_inc(file->f_dentry->d_inode->i_ino);
297                                                << 
298         return ret;                            << 
299 }                                              << 
300                                                << 
301 static int shm_release(struct inode *ino, stru << 
302 {                                              << 
303         struct shm_file_data *sfd = shm_file_d << 
304                                                << 
305         put_ipc_ns(sfd->ns);                   << 
306         shm_file_data(file) = NULL;            << 
307         kfree(sfd);                            << 
308         return 0;                                 159         return 0;
309 }                                                 160 }
310                                                   161 
311 static int shm_fsync(struct file *file, struct !! 162 static struct file_operations shm_file_operations = {
312 {                                              !! 163         .mmap   = shm_mmap
313         int (*fsync) (struct file *, struct de << 
314         struct shm_file_data *sfd = shm_file_d << 
315         int ret = -EINVAL;                     << 
316                                                << 
317         fsync = sfd->file->f_op->fsync;        << 
318         if (fsync)                             << 
319                 ret = fsync(sfd->file, sfd->fi << 
320         return ret;                            << 
321 }                                              << 
322                                                << 
323 static unsigned long shm_get_unmapped_area(str << 
324         unsigned long addr, unsigned long len, << 
325         unsigned long flags)                   << 
326 {                                              << 
327         struct shm_file_data *sfd = shm_file_d << 
328         return get_unmapped_area(sfd->file, ad << 
329 }                                              << 
330                                                << 
331 int is_file_shm_hugepages(struct file *file)   << 
332 {                                              << 
333         int ret = 0;                           << 
334                                                << 
335         if (file->f_op == &shm_file_operations << 
336                 struct shm_file_data *sfd;     << 
337                 sfd = shm_file_data(file);     << 
338                 ret = is_file_hugepages(sfd->f << 
339         }                                      << 
340         return ret;                            << 
341 }                                              << 
342                                                << 
343 static const struct file_operations shm_file_o << 
344         .mmap           = shm_mmap,            << 
345         .fsync          = shm_fsync,           << 
346         .release        = shm_release,         << 
347         .get_unmapped_area      = shm_get_unma << 
348 };                                                164 };
349                                                   165 
350 static struct vm_operations_struct shm_vm_ops     166 static struct vm_operations_struct shm_vm_ops = {
351         .open   = shm_open,     /* callback fo    167         .open   = shm_open,     /* callback for a new vm-area open */
352         .close  = shm_close,    /* callback fo    168         .close  = shm_close,    /* callback for when the vm-area is released */
353         .fault  = shm_fault,                   !! 169         .nopage = shmem_nopage,
354 #if defined(CONFIG_NUMA)                       !! 170 #ifdef CONFIG_NUMA
355         .set_policy = shm_set_policy,          !! 171         .set_policy = shmem_set_policy,
356         .get_policy = shm_get_policy,          !! 172         .get_policy = shmem_get_policy,
357 #endif                                            173 #endif
358 };                                                174 };
359                                                   175 
360 /**                                            !! 176 static int newseg (key_t key, int shmflg, size_t size)
361  * newseg - Create a new shared memory segment << 
362  * @ns: namespace                              << 
363  * @params: ptr to the structure that contains << 
364  *                                             << 
365  * Called with shm_ids.rw_mutex held as a writ << 
366  */                                            << 
367                                                << 
368 static int newseg(struct ipc_namespace *ns, st << 
369 {                                                 177 {
370         key_t key = params->key;               << 
371         int shmflg = params->flg;              << 
372         size_t size = params->u.size;          << 
373         int error;                                178         int error;
374         struct shmid_kernel *shp;                 179         struct shmid_kernel *shp;
375         int numpages = (size + PAGE_SIZE -1) >    180         int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
376         struct file * file;                       181         struct file * file;
377         char name[13];                            182         char name[13];
378         int id;                                   183         int id;
379                                                   184 
380         if (size < SHMMIN || size > ns->shm_ct !! 185         if (size < SHMMIN || size > shm_ctlmax)
381                 return -EINVAL;                   186                 return -EINVAL;
382                                                   187 
383         if (ns->shm_tot + numpages > ns->shm_c !! 188         if (shm_tot + numpages >= shm_ctlall)
384                 return -ENOSPC;                   189                 return -ENOSPC;
385                                                   190 
386         shp = ipc_rcu_alloc(sizeof(*shp));        191         shp = ipc_rcu_alloc(sizeof(*shp));
387         if (!shp)                                 192         if (!shp)
388                 return -ENOMEM;                   193                 return -ENOMEM;
389                                                   194 
390         shp->shm_perm.key = key;                  195         shp->shm_perm.key = key;
391         shp->shm_perm.mode = (shmflg & S_IRWXU !! 196         shp->shm_flags = (shmflg & S_IRWXUGO);
392         shp->mlock_user = NULL;                   197         shp->mlock_user = NULL;
393                                                   198 
394         shp->shm_perm.security = NULL;            199         shp->shm_perm.security = NULL;
395         error = security_shm_alloc(shp);          200         error = security_shm_alloc(shp);
396         if (error) {                              201         if (error) {
397                 ipc_rcu_putref(shp);              202                 ipc_rcu_putref(shp);
398                 return error;                     203                 return error;
399         }                                         204         }
400                                                   205 
401         sprintf (name, "SYSV%08x", key);       << 
402         if (shmflg & SHM_HUGETLB) {               206         if (shmflg & SHM_HUGETLB) {
403                 /* hugetlb_file_setup takes ca !! 207                 /* hugetlb_zero_setup takes care of mlock user accounting */
404                 file = hugetlb_file_setup(name !! 208                 file = hugetlb_zero_setup(size);
405                 shp->mlock_user = current->use    209                 shp->mlock_user = current->user;
406         } else {                                  210         } else {
407                 int acctflag = VM_ACCOUNT;     !! 211                 sprintf (name, "SYSV%08x", key);
408                 /*                             !! 212                 file = shmem_file_setup(name, size, VM_ACCOUNT);
409                  * Do not allow no accounting  << 
410                  * if it's asked for.          << 
411                  */                            << 
412                 if  ((shmflg & SHM_NORESERVE)  << 
413                                 sysctl_overcom << 
414                         acctflag = 0;          << 
415                 file = shmem_file_setup(name,  << 
416         }                                         213         }
417         error = PTR_ERR(file);                    214         error = PTR_ERR(file);
418         if (IS_ERR(file))                         215         if (IS_ERR(file))
419                 goto no_file;                     216                 goto no_file;
420                                                   217 
421         id = shm_addid(ns, shp);               !! 218         error = -ENOSPC;
422         if (id < 0) {                          !! 219         id = shm_addid(shp);
423                 error = id;                    !! 220         if(id == -1) 
424                 goto no_id;                       221                 goto no_id;
425         }                                      << 
426                                                   222 
427         shp->shm_cprid = task_tgid_vnr(current !! 223         shp->shm_cprid = current->tgid;
428         shp->shm_lprid = 0;                       224         shp->shm_lprid = 0;
429         shp->shm_atim = shp->shm_dtim = 0;        225         shp->shm_atim = shp->shm_dtim = 0;
430         shp->shm_ctim = get_seconds();            226         shp->shm_ctim = get_seconds();
431         shp->shm_segsz = size;                    227         shp->shm_segsz = size;
432         shp->shm_nattch = 0;                      228         shp->shm_nattch = 0;
433         shp->shm_perm.id = shm_buildid(id, shp !! 229         shp->id = shm_buildid(id,shp->shm_perm.seq);
434         shp->shm_file = file;                     230         shp->shm_file = file;
435         /*                                     !! 231         file->f_dentry->d_inode->i_ino = shp->id;
436          * shmid gets reported as "inode#" in  !! 232         if (shmflg & SHM_HUGETLB)
437          * proc-ps tools use this. Changing th !! 233                 set_file_hugepages(file);
438          */                                    !! 234         else
439         file->f_dentry->d_inode->i_ino = shp-> !! 235                 file->f_op = &shm_file_operations;
440                                                !! 236         shm_tot += numpages;
441         ns->shm_tot += numpages;               << 
442         error = shp->shm_perm.id;              << 
443         shm_unlock(shp);                          237         shm_unlock(shp);
444         return error;                          !! 238         return shp->id;
445                                                   239 
446 no_id:                                            240 no_id:
447         fput(file);                               241         fput(file);
448 no_file:                                          242 no_file:
449         security_shm_free(shp);                   243         security_shm_free(shp);
450         ipc_rcu_putref(shp);                      244         ipc_rcu_putref(shp);
451         return error;                             245         return error;
452 }                                                 246 }
453                                                   247 
454 /*                                             << 
455  * Called with shm_ids.rw_mutex and ipcp locke << 
456  */                                            << 
457 static inline int shm_security(struct kern_ipc << 
458 {                                              << 
459         struct shmid_kernel *shp;              << 
460                                                << 
461         shp = container_of(ipcp, struct shmid_ << 
462         return security_shm_associate(shp, shm << 
463 }                                              << 
464                                                << 
465 /*                                             << 
466  * Called with shm_ids.rw_mutex and ipcp locke << 
467  */                                            << 
468 static inline int shm_more_checks(struct kern_ << 
469                                 struct ipc_par << 
470 {                                              << 
471         struct shmid_kernel *shp;              << 
472                                                << 
473         shp = container_of(ipcp, struct shmid_ << 
474         if (shp->shm_segsz < params->u.size)   << 
475                 return -EINVAL;                << 
476                                                << 
477         return 0;                              << 
478 }                                              << 
479                                                << 
480 asmlinkage long sys_shmget (key_t key, size_t     248 asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
481 {                                                 249 {
482         struct ipc_namespace *ns;              !! 250         struct shmid_kernel *shp;
483         struct ipc_ops shm_ops;                !! 251         int err, id = 0;
484         struct ipc_params shm_params;          << 
485                                                << 
486         ns = current->nsproxy->ipc_ns;         << 
487                                                << 
488         shm_ops.getnew = newseg;               << 
489         shm_ops.associate = shm_security;      << 
490         shm_ops.more_checks = shm_more_checks; << 
491                                                   252 
492         shm_params.key = key;                  !! 253         down(&shm_ids.sem);
493         shm_params.flg = shmflg;               !! 254         if (key == IPC_PRIVATE) {
494         shm_params.u.size = size;              !! 255                 err = newseg(key, shmflg, size);
                                                   >> 256         } else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
                                                   >> 257                 if (!(shmflg & IPC_CREAT))
                                                   >> 258                         err = -ENOENT;
                                                   >> 259                 else
                                                   >> 260                         err = newseg(key, shmflg, size);
                                                   >> 261         } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
                                                   >> 262                 err = -EEXIST;
                                                   >> 263         } else {
                                                   >> 264                 shp = shm_lock(id);
                                                   >> 265                 if(shp==NULL)
                                                   >> 266                         BUG();
                                                   >> 267                 if (shp->shm_segsz < size)
                                                   >> 268                         err = -EINVAL;
                                                   >> 269                 else if (ipcperms(&shp->shm_perm, shmflg))
                                                   >> 270                         err = -EACCES;
                                                   >> 271                 else {
                                                   >> 272                         int shmid = shm_buildid(id, shp->shm_perm.seq);
                                                   >> 273                         err = security_shm_associate(shp, shmflg);
                                                   >> 274                         if (!err)
                                                   >> 275                                 err = shmid;
                                                   >> 276                 }
                                                   >> 277                 shm_unlock(shp);
                                                   >> 278         }
                                                   >> 279         up(&shm_ids.sem);
495                                                   280 
496         return ipcget(ns, &shm_ids(ns), &shm_o !! 281         return err;
497 }                                                 282 }
498                                                   283 
499 static inline unsigned long copy_shmid_to_user    284 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
500 {                                                 285 {
501         switch(version) {                         286         switch(version) {
502         case IPC_64:                              287         case IPC_64:
503                 return copy_to_user(buf, in, s    288                 return copy_to_user(buf, in, sizeof(*in));
504         case IPC_OLD:                             289         case IPC_OLD:
505             {                                     290             {
506                 struct shmid_ds out;              291                 struct shmid_ds out;
507                                                   292 
508                 ipc64_perm_to_ipc_perm(&in->sh    293                 ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm);
509                 out.shm_segsz   = in->shm_segs    294                 out.shm_segsz   = in->shm_segsz;
510                 out.shm_atime   = in->shm_atim    295                 out.shm_atime   = in->shm_atime;
511                 out.shm_dtime   = in->shm_dtim    296                 out.shm_dtime   = in->shm_dtime;
512                 out.shm_ctime   = in->shm_ctim    297                 out.shm_ctime   = in->shm_ctime;
513                 out.shm_cpid    = in->shm_cpid    298                 out.shm_cpid    = in->shm_cpid;
514                 out.shm_lpid    = in->shm_lpid    299                 out.shm_lpid    = in->shm_lpid;
515                 out.shm_nattch  = in->shm_natt    300                 out.shm_nattch  = in->shm_nattch;
516                                                   301 
517                 return copy_to_user(buf, &out,    302                 return copy_to_user(buf, &out, sizeof(out));
518             }                                     303             }
519         default:                                  304         default:
520                 return -EINVAL;                   305                 return -EINVAL;
521         }                                         306         }
522 }                                                 307 }
523                                                   308 
524 struct shm_setbuf {                               309 struct shm_setbuf {
525         uid_t   uid;                              310         uid_t   uid;
526         gid_t   gid;                              311         gid_t   gid;
527         mode_t  mode;                             312         mode_t  mode;
528 };                                                313 };      
529                                                   314 
530 static inline unsigned long copy_shmid_from_us    315 static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __user *buf, int version)
531 {                                                 316 {
532         switch(version) {                         317         switch(version) {
533         case IPC_64:                              318         case IPC_64:
534             {                                     319             {
535                 struct shmid64_ds tbuf;           320                 struct shmid64_ds tbuf;
536                                                   321 
537                 if (copy_from_user(&tbuf, buf,    322                 if (copy_from_user(&tbuf, buf, sizeof(tbuf)))
538                         return -EFAULT;           323                         return -EFAULT;
539                                                   324 
540                 out->uid        = tbuf.shm_per    325                 out->uid        = tbuf.shm_perm.uid;
541                 out->gid        = tbuf.shm_per    326                 out->gid        = tbuf.shm_perm.gid;
542                 out->mode       = tbuf.shm_per !! 327                 out->mode       = tbuf.shm_flags;
543                                                   328 
544                 return 0;                         329                 return 0;
545             }                                     330             }
546         case IPC_OLD:                             331         case IPC_OLD:
547             {                                     332             {
548                 struct shmid_ds tbuf_old;         333                 struct shmid_ds tbuf_old;
549                                                   334 
550                 if (copy_from_user(&tbuf_old,     335                 if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
551                         return -EFAULT;           336                         return -EFAULT;
552                                                   337 
553                 out->uid        = tbuf_old.shm    338                 out->uid        = tbuf_old.shm_perm.uid;
554                 out->gid        = tbuf_old.shm    339                 out->gid        = tbuf_old.shm_perm.gid;
555                 out->mode       = tbuf_old.shm !! 340                 out->mode       = tbuf_old.shm_flags;
556                                                   341 
557                 return 0;                         342                 return 0;
558             }                                     343             }
559         default:                                  344         default:
560                 return -EINVAL;                   345                 return -EINVAL;
561         }                                         346         }
562 }                                                 347 }
563                                                   348 
564 static inline unsigned long copy_shminfo_to_us    349 static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminfo64 *in, int version)
565 {                                                 350 {
566         switch(version) {                         351         switch(version) {
567         case IPC_64:                              352         case IPC_64:
568                 return copy_to_user(buf, in, s    353                 return copy_to_user(buf, in, sizeof(*in));
569         case IPC_OLD:                             354         case IPC_OLD:
570             {                                     355             {
571                 struct shminfo out;               356                 struct shminfo out;
572                                                   357 
573                 if(in->shmmax > INT_MAX)          358                 if(in->shmmax > INT_MAX)
574                         out.shmmax = INT_MAX;     359                         out.shmmax = INT_MAX;
575                 else                              360                 else
576                         out.shmmax = (int)in->    361                         out.shmmax = (int)in->shmmax;
577                                                   362 
578                 out.shmmin      = in->shmmin;     363                 out.shmmin      = in->shmmin;
579                 out.shmmni      = in->shmmni;     364                 out.shmmni      = in->shmmni;
580                 out.shmseg      = in->shmseg;     365                 out.shmseg      = in->shmseg;
581                 out.shmall      = in->shmall;     366                 out.shmall      = in->shmall; 
582                                                   367 
583                 return copy_to_user(buf, &out,    368                 return copy_to_user(buf, &out, sizeof(out));
584             }                                     369             }
585         default:                                  370         default:
586                 return -EINVAL;                   371                 return -EINVAL;
587         }                                         372         }
588 }                                                 373 }
589                                                   374 
590 /*                                             !! 375 static void shm_get_stat(unsigned long *rss, unsigned long *swp) 
591  * Called with shm_ids.rw_mutex held as a read << 
592  */                                            << 
593 static void shm_get_stat(struct ipc_namespace  << 
594                 unsigned long *swp)            << 
595 {                                                 376 {
596         int next_id;                           !! 377         int i;
597         int total, in_use;                     << 
598                                                   378 
599         *rss = 0;                                 379         *rss = 0;
600         *swp = 0;                                 380         *swp = 0;
601                                                   381 
602         in_use = shm_ids(ns).in_use;           !! 382         for (i = 0; i <= shm_ids.max_id; i++) {
603                                                << 
604         for (total = 0, next_id = 0; total < i << 
605                 struct shmid_kernel *shp;         383                 struct shmid_kernel *shp;
606                 struct inode *inode;              384                 struct inode *inode;
607                                                   385 
608                 shp = idr_find(&shm_ids(ns).ip !! 386                 shp = shm_get(i);
609                 if (shp == NULL)               !! 387                 if(!shp)
610                         continue;                 388                         continue;
611                                                   389 
612                 inode = shp->shm_file->f_path. !! 390                 inode = shp->shm_file->f_dentry->d_inode;
613                                                   391 
614                 if (is_file_hugepages(shp->shm    392                 if (is_file_hugepages(shp->shm_file)) {
615                         struct address_space *    393                         struct address_space *mapping = inode->i_mapping;
616                         *rss += (HPAGE_SIZE/PA !! 394                         *rss += (HPAGE_SIZE/PAGE_SIZE)*mapping->nrpages;
617                 } else {                          395                 } else {
618                         struct shmem_inode_inf    396                         struct shmem_inode_info *info = SHMEM_I(inode);
619                         spin_lock(&info->lock)    397                         spin_lock(&info->lock);
620                         *rss += mapping_nrpage !! 398                         *rss += inode->i_mapping->nrpages;
621                         *swp += info->swapped;    399                         *swp += info->swapped;
622                         spin_unlock(&info->loc    400                         spin_unlock(&info->lock);
623                 }                                 401                 }
624                                                << 
625                 total++;                       << 
626         }                                         402         }
627 }                                                 403 }
628                                                   404 
629 asmlinkage long sys_shmctl (int shmid, int cmd    405 asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
630 {                                                 406 {
631         struct shm_setbuf setbuf;                 407         struct shm_setbuf setbuf;
632         struct shmid_kernel *shp;                 408         struct shmid_kernel *shp;
633         int err, version;                         409         int err, version;
634         struct ipc_namespace *ns;              << 
635                                                   410 
636         if (cmd < 0 || shmid < 0) {               411         if (cmd < 0 || shmid < 0) {
637                 err = -EINVAL;                    412                 err = -EINVAL;
638                 goto out;                         413                 goto out;
639         }                                         414         }
640                                                   415 
641         version = ipc_parse_version(&cmd);        416         version = ipc_parse_version(&cmd);
642         ns = current->nsproxy->ipc_ns;         << 
643                                                   417 
644         switch (cmd) { /* replace with proc in    418         switch (cmd) { /* replace with proc interface ? */
645         case IPC_INFO:                            419         case IPC_INFO:
646         {                                         420         {
647                 struct shminfo64 shminfo;         421                 struct shminfo64 shminfo;
648                                                   422 
649                 err = security_shm_shmctl(NULL    423                 err = security_shm_shmctl(NULL, cmd);
650                 if (err)                          424                 if (err)
651                         return err;               425                         return err;
652                                                   426 
653                 memset(&shminfo,0,sizeof(shmin    427                 memset(&shminfo,0,sizeof(shminfo));
654                 shminfo.shmmni = shminfo.shmse !! 428                 shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
655                 shminfo.shmmax = ns->shm_ctlma !! 429                 shminfo.shmmax = shm_ctlmax;
656                 shminfo.shmall = ns->shm_ctlal !! 430                 shminfo.shmall = shm_ctlall;
657                                                   431 
658                 shminfo.shmmin = SHMMIN;          432                 shminfo.shmmin = SHMMIN;
659                 if(copy_shminfo_to_user (buf,     433                 if(copy_shminfo_to_user (buf, &shminfo, version))
660                         return -EFAULT;           434                         return -EFAULT;
661                                                !! 435                 /* reading a integer is always atomic */
662                 down_read(&shm_ids(ns).rw_mute !! 436                 err= shm_ids.max_id;
663                 err = ipc_get_maxid(&shm_ids(n << 
664                 up_read(&shm_ids(ns).rw_mutex) << 
665                                                << 
666                 if(err<0)                         437                 if(err<0)
667                         err = 0;                  438                         err = 0;
668                 goto out;                         439                 goto out;
669         }                                         440         }
670         case SHM_INFO:                            441         case SHM_INFO:
671         {                                         442         {
672                 struct shm_info shm_info;         443                 struct shm_info shm_info;
673                                                   444 
674                 err = security_shm_shmctl(NULL    445                 err = security_shm_shmctl(NULL, cmd);
675                 if (err)                          446                 if (err)
676                         return err;               447                         return err;
677                                                   448 
678                 memset(&shm_info,0,sizeof(shm_    449                 memset(&shm_info,0,sizeof(shm_info));
679                 down_read(&shm_ids(ns).rw_mute !! 450                 down(&shm_ids.sem);
680                 shm_info.used_ids = shm_ids(ns !! 451                 shm_info.used_ids = shm_ids.in_use;
681                 shm_get_stat (ns, &shm_info.sh !! 452                 shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
682                 shm_info.shm_tot = ns->shm_tot !! 453                 shm_info.shm_tot = shm_tot;
683                 shm_info.swap_attempts = 0;       454                 shm_info.swap_attempts = 0;
684                 shm_info.swap_successes = 0;      455                 shm_info.swap_successes = 0;
685                 err = ipc_get_maxid(&shm_ids(n !! 456                 err = shm_ids.max_id;
686                 up_read(&shm_ids(ns).rw_mutex) !! 457                 up(&shm_ids.sem);
687                 if(copy_to_user (buf, &shm_inf    458                 if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
688                         err = -EFAULT;            459                         err = -EFAULT;
689                         goto out;                 460                         goto out;
690                 }                                 461                 }
691                                                   462 
692                 err = err < 0 ? 0 : err;          463                 err = err < 0 ? 0 : err;
693                 goto out;                         464                 goto out;
694         }                                         465         }
695         case SHM_STAT:                            466         case SHM_STAT:
696         case IPC_STAT:                            467         case IPC_STAT:
697         {                                         468         {
698                 struct shmid64_ds tbuf;           469                 struct shmid64_ds tbuf;
699                 int result;                       470                 int result;
700                                                !! 471                 memset(&tbuf, 0, sizeof(tbuf));
701                 if (!buf) {                    !! 472                 shp = shm_lock(shmid);
702                         err = -EFAULT;         !! 473                 if(shp==NULL) {
                                                   >> 474                         err = -EINVAL;
703                         goto out;                 475                         goto out;
704                 }                              !! 476                 } else if(cmd==SHM_STAT) {
705                                                !! 477                         err = -EINVAL;
706                 if (cmd == SHM_STAT) {         !! 478                         if (shmid > shm_ids.max_id)
707                         shp = shm_lock(ns, shm !! 479                                 goto out_unlock;
708                         if (IS_ERR(shp)) {     !! 480                         result = shm_buildid(shmid, shp->shm_perm.seq);
709                                 err = PTR_ERR( << 
710                                 goto out;      << 
711                         }                      << 
712                         result = shp->shm_perm << 
713                 } else {                          481                 } else {
714                         shp = shm_lock_check(n !! 482                         err = shm_checkid(shp,shmid);
715                         if (IS_ERR(shp)) {     !! 483                         if(err)
716                                 err = PTR_ERR( !! 484                                 goto out_unlock;
717                                 goto out;      << 
718                         }                      << 
719                         result = 0;               485                         result = 0;
720                 }                                 486                 }
721                 err=-EACCES;                      487                 err=-EACCES;
722                 if (ipcperms (&shp->shm_perm,     488                 if (ipcperms (&shp->shm_perm, S_IRUGO))
723                         goto out_unlock;          489                         goto out_unlock;
724                 err = security_shm_shmctl(shp,    490                 err = security_shm_shmctl(shp, cmd);
725                 if (err)                          491                 if (err)
726                         goto out_unlock;          492                         goto out_unlock;
727                 memset(&tbuf, 0, sizeof(tbuf)) << 
728                 kernel_to_ipc64_perm(&shp->shm    493                 kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
729                 tbuf.shm_segsz  = shp->shm_seg    494                 tbuf.shm_segsz  = shp->shm_segsz;
730                 tbuf.shm_atime  = shp->shm_ati    495                 tbuf.shm_atime  = shp->shm_atim;
731                 tbuf.shm_dtime  = shp->shm_dti    496                 tbuf.shm_dtime  = shp->shm_dtim;
732                 tbuf.shm_ctime  = shp->shm_cti    497                 tbuf.shm_ctime  = shp->shm_ctim;
733                 tbuf.shm_cpid   = shp->shm_cpr    498                 tbuf.shm_cpid   = shp->shm_cprid;
734                 tbuf.shm_lpid   = shp->shm_lpr    499                 tbuf.shm_lpid   = shp->shm_lprid;
735                 tbuf.shm_nattch = shp->shm_nat !! 500                 if (!is_file_hugepages(shp->shm_file))
                                                   >> 501                         tbuf.shm_nattch = shp->shm_nattch;
                                                   >> 502                 else
                                                   >> 503                         tbuf.shm_nattch = file_count(shp->shm_file) - 1;
736                 shm_unlock(shp);                  504                 shm_unlock(shp);
737                 if(copy_shmid_to_user (buf, &t    505                 if(copy_shmid_to_user (buf, &tbuf, version))
738                         err = -EFAULT;            506                         err = -EFAULT;
739                 else                              507                 else
740                         err = result;             508                         err = result;
741                 goto out;                         509                 goto out;
742         }                                         510         }
743         case SHM_LOCK:                            511         case SHM_LOCK:
744         case SHM_UNLOCK:                          512         case SHM_UNLOCK:
745         {                                         513         {
746                 shp = shm_lock_check(ns, shmid !! 514                 shp = shm_lock(shmid);
747                 if (IS_ERR(shp)) {             !! 515                 if(shp==NULL) {
748                         err = PTR_ERR(shp);    !! 516                         err = -EINVAL;
749                         goto out;                 517                         goto out;
750                 }                                 518                 }
751                                                !! 519                 err = shm_checkid(shp,shmid);
752                 err = audit_ipc_obj(&(shp->shm !! 520                 if(err)
753                 if (err)                       << 
754                         goto out_unlock;          521                         goto out_unlock;
755                                                   522 
756                 if (!capable(CAP_IPC_LOCK)) {     523                 if (!capable(CAP_IPC_LOCK)) {
757                         err = -EPERM;             524                         err = -EPERM;
758                         if (current->euid != s    525                         if (current->euid != shp->shm_perm.uid &&
759                             current->euid != s    526                             current->euid != shp->shm_perm.cuid)
760                                 goto out_unloc    527                                 goto out_unlock;
761                         if (cmd == SHM_LOCK &&    528                         if (cmd == SHM_LOCK &&
762                             !current->signal->    529                             !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
763                                 goto out_unloc    530                                 goto out_unlock;
764                 }                                 531                 }
765                                                   532 
766                 err = security_shm_shmctl(shp,    533                 err = security_shm_shmctl(shp, cmd);
767                 if (err)                          534                 if (err)
768                         goto out_unlock;          535                         goto out_unlock;
769                                                   536                 
770                 if(cmd==SHM_LOCK) {               537                 if(cmd==SHM_LOCK) {
771                         struct user_struct * u    538                         struct user_struct * user = current->user;
772                         if (!is_file_hugepages    539                         if (!is_file_hugepages(shp->shm_file)) {
773                                 err = shmem_lo    540                                 err = shmem_lock(shp->shm_file, 1, user);
774                                 if (!err && !( !! 541                                 if (!err) {
775                                         shp->s !! 542                                         shp->shm_flags |= SHM_LOCKED;
776                                         shp->m    543                                         shp->mlock_user = user;
777                                 }                 544                                 }
778                         }                         545                         }
779                 } else if (!is_file_hugepages(    546                 } else if (!is_file_hugepages(shp->shm_file)) {
780                         shmem_lock(shp->shm_fi    547                         shmem_lock(shp->shm_file, 0, shp->mlock_user);
781                         shp->shm_perm.mode &=  !! 548                         shp->shm_flags &= ~SHM_LOCKED;
782                         shp->mlock_user = NULL    549                         shp->mlock_user = NULL;
783                 }                                 550                 }
784                 shm_unlock(shp);                  551                 shm_unlock(shp);
785                 goto out;                         552                 goto out;
786         }                                         553         }
787         case IPC_RMID:                            554         case IPC_RMID:
788         {                                         555         {
789                 /*                                556                 /*
790                  *      We cannot simply remov    557                  *      We cannot simply remove the file. The SVID states
791                  *      that the block remains    558                  *      that the block remains until the last person
792                  *      detaches from it, then    559                  *      detaches from it, then is deleted. A shmat() on
793                  *      an RMID segment is leg    560                  *      an RMID segment is legal in older Linux and if 
794                  *      we change it apps brea    561                  *      we change it apps break...
795                  *                                562                  *
796                  *      Instead we set a destr    563                  *      Instead we set a destroyed flag, and then blow
797                  *      the name away when the    564                  *      the name away when the usage hits zero.
798                  */                               565                  */
799                 down_write(&shm_ids(ns).rw_mut !! 566                 down(&shm_ids.sem);
800                 shp = shm_lock_check_down(ns,  !! 567                 shp = shm_lock(shmid);
801                 if (IS_ERR(shp)) {             !! 568                 err = -EINVAL;
802                         err = PTR_ERR(shp);    !! 569                 if (shp == NULL) 
803                         goto out_up;              570                         goto out_up;
804                 }                              !! 571                 err = shm_checkid(shp, shmid);
805                                                !! 572                 if(err)
806                 err = audit_ipc_obj(&(shp->shm << 
807                 if (err)                       << 
808                         goto out_unlock_up;       573                         goto out_unlock_up;
809                                                   574 
810                 if (current->euid != shp->shm_    575                 if (current->euid != shp->shm_perm.uid &&
811                     current->euid != shp->shm_    576                     current->euid != shp->shm_perm.cuid && 
812                     !capable(CAP_SYS_ADMIN)) {    577                     !capable(CAP_SYS_ADMIN)) {
813                         err=-EPERM;               578                         err=-EPERM;
814                         goto out_unlock_up;       579                         goto out_unlock_up;
815                 }                                 580                 }
816                                                   581 
817                 err = security_shm_shmctl(shp,    582                 err = security_shm_shmctl(shp, cmd);
818                 if (err)                          583                 if (err)
819                         goto out_unlock_up;       584                         goto out_unlock_up;
820                                                   585 
821                 do_shm_rmid(ns, &shp->shm_perm !! 586                 if (shp->shm_nattch){
822                 up_write(&shm_ids(ns).rw_mutex !! 587                         shp->shm_flags |= SHM_DEST;
                                                   >> 588                         /* Do not find it any more */
                                                   >> 589                         shp->shm_perm.key = IPC_PRIVATE;
                                                   >> 590                         shm_unlock(shp);
                                                   >> 591                 } else
                                                   >> 592                         shm_destroy (shp);
                                                   >> 593                 up(&shm_ids.sem);
823                 goto out;                         594                 goto out;
824         }                                         595         }
825                                                   596 
826         case IPC_SET:                             597         case IPC_SET:
827         {                                         598         {
828                 if (!buf) {                    << 
829                         err = -EFAULT;         << 
830                         goto out;              << 
831                 }                              << 
832                                                << 
833                 if (copy_shmid_from_user (&set    599                 if (copy_shmid_from_user (&setbuf, buf, version)) {
834                         err = -EFAULT;            600                         err = -EFAULT;
835                         goto out;                 601                         goto out;
836                 }                                 602                 }
837                 down_write(&shm_ids(ns).rw_mut !! 603                 down(&shm_ids.sem);
838                 shp = shm_lock_check_down(ns,  !! 604                 shp = shm_lock(shmid);
839                 if (IS_ERR(shp)) {             !! 605                 err=-EINVAL;
840                         err = PTR_ERR(shp);    !! 606                 if(shp==NULL)
841                         goto out_up;              607                         goto out_up;
842                 }                              !! 608                 err = shm_checkid(shp,shmid);
843                 err = audit_ipc_obj(&(shp->shm !! 609                 if(err)
844                 if (err)                       << 
845                         goto out_unlock_up;    << 
846                 err = audit_ipc_set_perm(0, se << 
847                 if (err)                       << 
848                         goto out_unlock_up;       610                         goto out_unlock_up;
849                 err=-EPERM;                       611                 err=-EPERM;
850                 if (current->euid != shp->shm_    612                 if (current->euid != shp->shm_perm.uid &&
851                     current->euid != shp->shm_    613                     current->euid != shp->shm_perm.cuid && 
852                     !capable(CAP_SYS_ADMIN)) {    614                     !capable(CAP_SYS_ADMIN)) {
853                         goto out_unlock_up;       615                         goto out_unlock_up;
854                 }                                 616                 }
855                                                   617 
856                 err = security_shm_shmctl(shp,    618                 err = security_shm_shmctl(shp, cmd);
857                 if (err)                          619                 if (err)
858                         goto out_unlock_up;       620                         goto out_unlock_up;
859                                                   621                 
860                 shp->shm_perm.uid = setbuf.uid    622                 shp->shm_perm.uid = setbuf.uid;
861                 shp->shm_perm.gid = setbuf.gid    623                 shp->shm_perm.gid = setbuf.gid;
862                 shp->shm_perm.mode = (shp->shm !! 624                 shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO)
863                         | (setbuf.mode & S_IRW    625                         | (setbuf.mode & S_IRWXUGO);
864                 shp->shm_ctim = get_seconds();    626                 shp->shm_ctim = get_seconds();
865                 break;                            627                 break;
866         }                                         628         }
867                                                   629 
868         default:                                  630         default:
869                 err = -EINVAL;                    631                 err = -EINVAL;
870                 goto out;                         632                 goto out;
871         }                                         633         }
872                                                   634 
873         err = 0;                                  635         err = 0;
874 out_unlock_up:                                    636 out_unlock_up:
875         shm_unlock(shp);                          637         shm_unlock(shp);
876 out_up:                                           638 out_up:
877         up_write(&shm_ids(ns).rw_mutex);       !! 639         up(&shm_ids.sem);
878         goto out;                                 640         goto out;
879 out_unlock:                                       641 out_unlock:
880         shm_unlock(shp);                          642         shm_unlock(shp);
881 out:                                              643 out:
882         return err;                               644         return err;
883 }                                                 645 }
884                                                   646 
885 /*                                                647 /*
886  * Fix shmaddr, allocate descriptor, map shm,     648  * Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists.
887  *                                                649  *
888  * NOTE! Despite the name, this is NOT a direc    650  * NOTE! Despite the name, this is NOT a direct system call entrypoint. The
889  * "raddr" thing points to kernel space, and t    651  * "raddr" thing points to kernel space, and there has to be a wrapper around
890  * this.                                          652  * this.
891  */                                               653  */
892 long do_shmat(int shmid, char __user *shmaddr,    654 long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
893 {                                                 655 {
894         struct shmid_kernel *shp;                 656         struct shmid_kernel *shp;
895         unsigned long addr;                       657         unsigned long addr;
896         unsigned long size;                       658         unsigned long size;
897         struct file * file;                       659         struct file * file;
898         int    err;                               660         int    err;
899         unsigned long flags;                      661         unsigned long flags;
900         unsigned long prot;                       662         unsigned long prot;
                                                   >> 663         unsigned long o_flags;
901         int acc_mode;                             664         int acc_mode;
902         unsigned long user_addr;               !! 665         void *user_addr;
903         struct ipc_namespace *ns;              << 
904         struct shm_file_data *sfd;             << 
905         struct path path;                      << 
906         mode_t f_mode;                         << 
907                                                   666 
908         err = -EINVAL;                         !! 667         if (shmid < 0) {
909         if (shmid < 0)                         !! 668                 err = -EINVAL;
910                 goto out;                         669                 goto out;
911         else if ((addr = (ulong)shmaddr)) {    !! 670         } else if ((addr = (ulong)shmaddr)) {
912                 if (addr & (SHMLBA-1)) {          671                 if (addr & (SHMLBA-1)) {
913                         if (shmflg & SHM_RND)     672                         if (shmflg & SHM_RND)
914                                 addr &= ~(SHML    673                                 addr &= ~(SHMLBA-1);       /* round down */
915                         else                      674                         else
916 #ifndef __ARCH_FORCE_SHMLBA                       675 #ifndef __ARCH_FORCE_SHMLBA
917                                 if (addr & ~PA    676                                 if (addr & ~PAGE_MASK)
918 #endif                                            677 #endif
919                                         goto o !! 678                                         return -EINVAL;
920                 }                                 679                 }
921                 flags = MAP_SHARED | MAP_FIXED    680                 flags = MAP_SHARED | MAP_FIXED;
922         } else {                                  681         } else {
923                 if ((shmflg & SHM_REMAP))         682                 if ((shmflg & SHM_REMAP))
924                         goto out;              !! 683                         return -EINVAL;
925                                                   684 
926                 flags = MAP_SHARED;               685                 flags = MAP_SHARED;
927         }                                         686         }
928                                                   687 
929         if (shmflg & SHM_RDONLY) {                688         if (shmflg & SHM_RDONLY) {
930                 prot = PROT_READ;                 689                 prot = PROT_READ;
                                                   >> 690                 o_flags = O_RDONLY;
931                 acc_mode = S_IRUGO;               691                 acc_mode = S_IRUGO;
932                 f_mode = FMODE_READ;           << 
933         } else {                                  692         } else {
934                 prot = PROT_READ | PROT_WRITE;    693                 prot = PROT_READ | PROT_WRITE;
                                                   >> 694                 o_flags = O_RDWR;
935                 acc_mode = S_IRUGO | S_IWUGO;     695                 acc_mode = S_IRUGO | S_IWUGO;
936                 f_mode = FMODE_READ | FMODE_WR << 
937         }                                         696         }
938         if (shmflg & SHM_EXEC) {                  697         if (shmflg & SHM_EXEC) {
939                 prot |= PROT_EXEC;                698                 prot |= PROT_EXEC;
940                 acc_mode |= S_IXUGO;              699                 acc_mode |= S_IXUGO;
941         }                                         700         }
942                                                   701 
943         /*                                        702         /*
944          * We cannot rely on the fs check sinc    703          * We cannot rely on the fs check since SYSV IPC does have an
945          * additional creator id...               704          * additional creator id...
946          */                                       705          */
947         ns = current->nsproxy->ipc_ns;         !! 706         shp = shm_lock(shmid);
948         shp = shm_lock_check(ns, shmid);       !! 707         if(shp == NULL) {
949         if (IS_ERR(shp)) {                     !! 708                 err = -EINVAL;
950                 err = PTR_ERR(shp);            !! 709                 goto out;
                                                   >> 710         }
                                                   >> 711         err = shm_checkid(shp,shmid);
                                                   >> 712         if (err) {
                                                   >> 713                 shm_unlock(shp);
                                                   >> 714                 goto out;
                                                   >> 715         }
                                                   >> 716         if (ipcperms(&shp->shm_perm, acc_mode)) {
                                                   >> 717                 shm_unlock(shp);
                                                   >> 718                 err = -EACCES;
951                 goto out;                         719                 goto out;
952         }                                         720         }
953                                                << 
954         err = -EACCES;                         << 
955         if (ipcperms(&shp->shm_perm, acc_mode) << 
956                 goto out_unlock;               << 
957                                                   721 
958         err = security_shm_shmat(shp, shmaddr,    722         err = security_shm_shmat(shp, shmaddr, shmflg);
959         if (err)                               !! 723         if (err) {
960                 goto out_unlock;               !! 724                 shm_unlock(shp);
961                                                !! 725                 return err;
962         path.dentry = dget(shp->shm_file->f_pa !! 726         }
963         path.mnt    = shp->shm_file->f_path.mn !! 727                 
                                                   >> 728         file = shp->shm_file;
                                                   >> 729         size = i_size_read(file->f_dentry->d_inode);
964         shp->shm_nattch++;                        730         shp->shm_nattch++;
965         size = i_size_read(path.dentry->d_inod << 
966         shm_unlock(shp);                          731         shm_unlock(shp);
967                                                   732 
968         err = -ENOMEM;                         << 
969         sfd = kzalloc(sizeof(*sfd), GFP_KERNEL << 
970         if (!sfd)                              << 
971                 goto out_put_dentry;           << 
972                                                << 
973         err = -ENOMEM;                         << 
974                                                << 
975         file = alloc_file(path.mnt, path.dentr << 
976         if (!file)                             << 
977                 goto out_free;                 << 
978                                                << 
979         file->private_data = sfd;              << 
980         file->f_mapping = shp->shm_file->f_map << 
981         sfd->id = shp->shm_perm.id;            << 
982         sfd->ns = get_ipc_ns(ns);              << 
983         sfd->file = shp->shm_file;             << 
984         sfd->vm_ops = NULL;                    << 
985                                                << 
986         down_write(&current->mm->mmap_sem);       733         down_write(&current->mm->mmap_sem);
987         if (addr && !(shmflg & SHM_REMAP)) {      734         if (addr && !(shmflg & SHM_REMAP)) {
988                 err = -EINVAL;                 !! 735                 user_addr = ERR_PTR(-EINVAL);
989                 if (find_vma_intersection(curr    736                 if (find_vma_intersection(current->mm, addr, addr + size))
990                         goto invalid;             737                         goto invalid;
991                 /*                                738                 /*
992                  * If shm segment goes below s    739                  * If shm segment goes below stack, make sure there is some
993                  * space left for the stack to    740                  * space left for the stack to grow (at least 4 pages).
994                  */                               741                  */
995                 if (addr < current->mm->start_    742                 if (addr < current->mm->start_stack &&
996                     addr > current->mm->start_    743                     addr > current->mm->start_stack - size - PAGE_SIZE * 5)
997                         goto invalid;             744                         goto invalid;
998         }                                         745         }
999                                                   746                 
1000         user_addr = do_mmap (file, addr, size !! 747         user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
1001         *raddr = user_addr;                   !! 748 
1002         err = 0;                              << 
1003         if (IS_ERR_VALUE(user_addr))          << 
1004                 err = (long)user_addr;        << 
1005 invalid:                                         749 invalid:
1006         up_write(&current->mm->mmap_sem);        750         up_write(&current->mm->mmap_sem);
1007                                                  751 
1008         fput(file);                           !! 752         down (&shm_ids.sem);
1009                                               !! 753         if(!(shp = shm_lock(shmid)))
1010 out_nattch:                                   !! 754                 BUG();
1011         down_write(&shm_ids(ns).rw_mutex);    << 
1012         shp = shm_lock_down(ns, shmid);       << 
1013         BUG_ON(IS_ERR(shp));                  << 
1014         shp->shm_nattch--;                       755         shp->shm_nattch--;
1015         if(shp->shm_nattch == 0 &&               756         if(shp->shm_nattch == 0 &&
1016            shp->shm_perm.mode & SHM_DEST)     !! 757            shp->shm_flags & SHM_DEST)
1017                 shm_destroy(ns, shp);         !! 758                 shm_destroy (shp);
1018         else                                     759         else
1019                 shm_unlock(shp);                 760                 shm_unlock(shp);
1020         up_write(&shm_ids(ns).rw_mutex);      !! 761         up (&shm_ids.sem);
1021                                                  762 
                                                   >> 763         *raddr = (unsigned long) user_addr;
                                                   >> 764         err = 0;
                                                   >> 765         if (IS_ERR(user_addr))
                                                   >> 766                 err = PTR_ERR(user_addr);
1022 out:                                             767 out:
1023         return err;                              768         return err;
1024                                               << 
1025 out_unlock:                                   << 
1026         shm_unlock(shp);                      << 
1027         goto out;                             << 
1028                                               << 
1029 out_free:                                     << 
1030         kfree(sfd);                           << 
1031 out_put_dentry:                               << 
1032         dput(path.dentry);                    << 
1033         goto out_nattch;                      << 
1034 }                                             << 
1035                                               << 
1036 asmlinkage long sys_shmat(int shmid, char __u << 
1037 {                                             << 
1038         unsigned long ret;                    << 
1039         long err;                             << 
1040                                               << 
1041         err = do_shmat(shmid, shmaddr, shmflg << 
1042         if (err)                              << 
1043                 return err;                   << 
1044         force_successful_syscall_return();    << 
1045         return (long)ret;                     << 
1046 }                                                769 }
1047                                                  770 
1048 /*                                               771 /*
1049  * detach and kill segment if marked destroye    772  * detach and kill segment if marked destroyed.
1050  * The work is done in shm_close.                773  * The work is done in shm_close.
1051  */                                              774  */
1052 asmlinkage long sys_shmdt(char __user *shmadd    775 asmlinkage long sys_shmdt(char __user *shmaddr)
1053 {                                                776 {
1054         struct mm_struct *mm = current->mm;      777         struct mm_struct *mm = current->mm;
1055         struct vm_area_struct *vma, *next;       778         struct vm_area_struct *vma, *next;
1056         unsigned long addr = (unsigned long)s    779         unsigned long addr = (unsigned long)shmaddr;
1057         loff_t size = 0;                         780         loff_t size = 0;
1058         int retval = -EINVAL;                    781         int retval = -EINVAL;
1059                                                  782 
1060         if (addr & ~PAGE_MASK)                << 
1061                 return retval;                << 
1062                                               << 
1063         down_write(&mm->mmap_sem);               783         down_write(&mm->mmap_sem);
1064                                                  784 
1065         /*                                       785         /*
1066          * This function tries to be smart an    786          * This function tries to be smart and unmap shm segments that
1067          * were modified by partial mlock or     787          * were modified by partial mlock or munmap calls:
1068          * - It first determines the size of     788          * - It first determines the size of the shm segment that should be
1069          *   unmapped: It searches for a vma     789          *   unmapped: It searches for a vma that is backed by shm and that
1070          *   started at address shmaddr. It r    790          *   started at address shmaddr. It records it's size and then unmaps
1071          *   it.                                 791          *   it.
1072          * - Then it unmaps all shm vmas that    792          * - Then it unmaps all shm vmas that started at shmaddr and that
1073          *   are within the initially determi    793          *   are within the initially determined size.
1074          * Errors from do_munmap are ignored:    794          * Errors from do_munmap are ignored: the function only fails if
1075          * it's called with invalid parameter    795          * it's called with invalid parameters or if it's called to unmap
1076          * a part of a vma. Both calls in thi    796          * a part of a vma. Both calls in this function are for full vmas,
1077          * the parameters are directly copied    797          * the parameters are directly copied from the vma itself and always
1078          * valid - therefore do_munmap cannot    798          * valid - therefore do_munmap cannot fail. (famous last words?)
1079          */                                      799          */
1080         /*                                       800         /*
1081          * If it had been mremap()'d, the sta    801          * If it had been mremap()'d, the starting address would not
1082          * match the usual checks anyway. So     802          * match the usual checks anyway. So assume all vma's are
1083          * above the starting address given.     803          * above the starting address given.
1084          */                                      804          */
1085         vma = find_vma(mm, addr);                805         vma = find_vma(mm, addr);
1086                                                  806 
1087         while (vma) {                            807         while (vma) {
1088                 next = vma->vm_next;             808                 next = vma->vm_next;
1089                                                  809 
1090                 /*                               810                 /*
1091                  * Check if the starting addr    811                  * Check if the starting address would match, i.e. it's
1092                  * a fragment created by mpro    812                  * a fragment created by mprotect() and/or munmap(), or it
1093                  * otherwise it starts at thi    813                  * otherwise it starts at this address with no hassles.
1094                  */                              814                  */
1095                 if ((vma->vm_ops == &shm_vm_o !! 815                 if ((vma->vm_ops == &shm_vm_ops || is_vm_hugetlb_page(vma)) &&
1096                         (vma->vm_start - addr    816                         (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) {
1097                                                  817 
1098                                                  818 
1099                         size = vma->vm_file-> !! 819                         size = vma->vm_file->f_dentry->d_inode->i_size;
1100                         do_munmap(mm, vma->vm    820                         do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
1101                         /*                       821                         /*
1102                          * We discovered the     822                          * We discovered the size of the shm segment, so
1103                          * break out of here     823                          * break out of here and fall through to the next
1104                          * loop that uses the    824                          * loop that uses the size information to stop
1105                          * searching for matc    825                          * searching for matching vma's.
1106                          */                      826                          */
1107                         retval = 0;              827                         retval = 0;
1108                         vma = next;              828                         vma = next;
1109                         break;                   829                         break;
1110                 }                                830                 }
1111                 vma = next;                      831                 vma = next;
1112         }                                        832         }
1113                                                  833 
1114         /*                                       834         /*
1115          * We need look no further than the m    835          * We need look no further than the maximum address a fragment
1116          * could possibly have landed at. Als    836          * could possibly have landed at. Also cast things to loff_t to
1117          * prevent overflows and make compari    837          * prevent overflows and make comparisions vs. equal-width types.
1118          */                                      838          */
1119         size = PAGE_ALIGN(size);              << 
1120         while (vma && (loff_t)(vma->vm_end -     839         while (vma && (loff_t)(vma->vm_end - addr) <= size) {
1121                 next = vma->vm_next;             840                 next = vma->vm_next;
1122                                                  841 
1123                 /* finding a matching vma now    842                 /* finding a matching vma now does not alter retval */
1124                 if ((vma->vm_ops == &shm_vm_o !! 843                 if ((vma->vm_ops == &shm_vm_ops || is_vm_hugetlb_page(vma)) &&
1125                         (vma->vm_start - addr    844                         (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff)
1126                                                  845 
1127                         do_munmap(mm, vma->vm    846                         do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
1128                 vma = next;                      847                 vma = next;
1129         }                                        848         }
1130                                                  849 
1131         up_write(&mm->mmap_sem);                 850         up_write(&mm->mmap_sem);
1132         return retval;                           851         return retval;
1133 }                                                852 }
1134                                                  853 
1135 #ifdef CONFIG_PROC_FS                            854 #ifdef CONFIG_PROC_FS
1136 static int sysvipc_shm_proc_show(struct seq_f !! 855 static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
1137 {                                                856 {
1138         struct shmid_kernel *shp = it;        !! 857         off_t pos = 0;
1139         char *format;                         !! 858         off_t begin = 0;
                                                   >> 859         int i, len = 0;
                                                   >> 860 
                                                   >> 861         down(&shm_ids.sem);
                                                   >> 862         len += sprintf(buffer, "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n");
                                                   >> 863 
                                                   >> 864         for(i = 0; i <= shm_ids.max_id; i++) {
                                                   >> 865                 struct shmid_kernel* shp;
1140                                                  866 
                                                   >> 867                 shp = shm_lock(i);
                                                   >> 868                 if(shp!=NULL) {
1141 #define SMALL_STRING "%10d %10d  %4o %10u %5u    869 #define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
1142 #define BIG_STRING   "%10d %10d  %4o %21u %5u    870 #define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
                                                   >> 871                         char *format;
1143                                                  872 
1144         if (sizeof(size_t) <= sizeof(int))    !! 873                         if (sizeof(size_t) <= sizeof(int))
1145                 format = SMALL_STRING;        !! 874                                 format = SMALL_STRING;
1146         else                                  !! 875                         else
1147                 format = BIG_STRING;          !! 876                                 format = BIG_STRING;
1148         return seq_printf(s, format,          !! 877                         len += sprintf(buffer + len, format,
1149                           shp->shm_perm.key,  !! 878                                 shp->shm_perm.key,
1150                           shp->shm_perm.id,   !! 879                                 shm_buildid(i, shp->shm_perm.seq),
1151                           shp->shm_perm.mode, !! 880                                 shp->shm_flags,
1152                           shp->shm_segsz,     !! 881                                 shp->shm_segsz,
1153                           shp->shm_cprid,     !! 882                                 shp->shm_cprid,
1154                           shp->shm_lprid,     !! 883                                 shp->shm_lprid,
1155                           shp->shm_nattch,    !! 884                                 is_file_hugepages(shp->shm_file) ? (file_count(shp->shm_file) - 1) : shp->shm_nattch,
1156                           shp->shm_perm.uid,  !! 885                                 shp->shm_perm.uid,
1157                           shp->shm_perm.gid,  !! 886                                 shp->shm_perm.gid,
1158                           shp->shm_perm.cuid, !! 887                                 shp->shm_perm.cuid,
1159                           shp->shm_perm.cgid, !! 888                                 shp->shm_perm.cgid,
1160                           shp->shm_atim,      !! 889                                 shp->shm_atim,
1161                           shp->shm_dtim,      !! 890                                 shp->shm_dtim,
1162                           shp->shm_ctim);     !! 891                                 shp->shm_ctim);
                                                   >> 892                         shm_unlock(shp);
                                                   >> 893 
                                                   >> 894                         pos += len;
                                                   >> 895                         if(pos < offset) {
                                                   >> 896                                 len = 0;
                                                   >> 897                                 begin = pos;
                                                   >> 898                         }
                                                   >> 899                         if(pos > offset + length)
                                                   >> 900                                 goto done;
                                                   >> 901                 }
                                                   >> 902         }
                                                   >> 903         *eof = 1;
                                                   >> 904 done:
                                                   >> 905         up(&shm_ids.sem);
                                                   >> 906         *start = buffer + (offset - begin);
                                                   >> 907         len -= (offset - begin);
                                                   >> 908         if(len > length)
                                                   >> 909                 len = length;
                                                   >> 910         if(len < 0)
                                                   >> 911                 len = 0;
                                                   >> 912         return len;
1163 }                                                913 }
1164 #endif                                           914 #endif
1165                                                  915 
  This page was automatically generated by the LXR engine.