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 ]
  1 /*
  2  * linux/ipc/ipcns_notifier.c
  3  * Copyright (C) 2007 BULL SA. Nadia Derbey
  4  *
  5  * Notification mechanism for ipc namespaces:
  6  * The callback routine registered in the memory chain invokes the ipcns
  7  * notifier chain with the IPCNS_MEMCHANGED event.
  8  * Each callback routine registered in the ipcns namespace recomputes msgmni
  9  * for the owning namespace.
 10  */
 11 
 12 #include <linux/msg.h>
 13 #include <linux/rcupdate.h>
 14 #include <linux/notifier.h>
 15 #include <linux/nsproxy.h>
 16 #include <linux/ipc_namespace.h>
 17 
 18 #include "util.h"
 19 
 20 
 21 
 22 static BLOCKING_NOTIFIER_HEAD(ipcns_chain);
 23 
 24 
 25 static int ipcns_callback(struct notifier_block *self,
 26                                 unsigned long action, void *arg)
 27 {
 28         struct ipc_namespace *ns;
 29 
 30         switch (action) {
 31         case IPCNS_MEMCHANGED:   /* amount of lowmem has changed */
 32         case IPCNS_CREATED:
 33         case IPCNS_REMOVED:
 34                 /*
 35                  * It's time to recompute msgmni
 36                  */
 37                 ns = container_of(self, struct ipc_namespace, ipcns_nb);
 38                 /*
 39                  * No need to get a reference on the ns: the 1st job of
 40                  * free_ipc_ns() is to unregister the callback routine.
 41                  * blocking_notifier_chain_unregister takes the wr lock to do
 42                  * it.
 43                  * When this callback routine is called the rd lock is held by
 44                  * blocking_notifier_call_chain.
 45                  * So the ipc ns cannot be freed while we are here.
 46                  */
 47                 recompute_msgmni(ns);
 48                 break;
 49         default:
 50                 break;
 51         }
 52 
 53         return NOTIFY_OK;
 54 }
 55 
 56 int register_ipcns_notifier(struct ipc_namespace *ns)
 57 {
 58         int rc;
 59 
 60         memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb));
 61         ns->ipcns_nb.notifier_call = ipcns_callback;
 62         ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI;
 63         rc = blocking_notifier_chain_register(&ipcns_chain, &ns->ipcns_nb);
 64         if (!rc)
 65                 ns->auto_msgmni = 1;
 66         return rc;
 67 }
 68 
 69 int cond_register_ipcns_notifier(struct ipc_namespace *ns)
 70 {
 71         int rc;
 72 
 73         memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb));
 74         ns->ipcns_nb.notifier_call = ipcns_callback;
 75         ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI;
 76         rc = blocking_notifier_chain_cond_register(&ipcns_chain,
 77                                                         &ns->ipcns_nb);
 78         if (!rc)
 79                 ns->auto_msgmni = 1;
 80         return rc;
 81 }
 82 
 83 void unregister_ipcns_notifier(struct ipc_namespace *ns)
 84 {
 85         blocking_notifier_chain_unregister(&ipcns_chain, &ns->ipcns_nb);
 86         ns->auto_msgmni = 0;
 87 }
 88 
 89 int ipcns_notify(unsigned long val)
 90 {
 91         return blocking_notifier_call_chain(&ipcns_chain, val, NULL);
 92 }
 93 
  This page was automatically generated by the LXR engine.