[DRBD-cvs] svn commit by phil - r2392 - in trunk: . drbd drbd/linux user - Cleanup of the kernel side of drbd_nl.c

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Thu Aug 31 21:06:58 CEST 2006


Author: phil
Date: 2006-08-31 21:06:56 +0200 (Thu, 31 Aug 2006)
New Revision: 2392

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_nl.c
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_tag_magic.h
   trunk/user/drbdsetup.c
Log:
Cleanup of the kernel side of drbd_nl.c 


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-08-29 13:50:39 UTC (rev 2391)
+++ trunk/ROADMAP	2006-08-31 19:06:56 UTC (rev 2392)
@@ -441,13 +441,6 @@
 
   Things to do:
   
-  * Fix drbdadm (nees to use --create-device and --set-defaults; adjust
-      needs to be changes since the kernel can not return the device
-      names of backing and meta device.)
-  * Remove the memset( .., 0, ...) from drbd_nl.c. Use the defaults instead.
-  * Use only one connector callback.
-  * use try_module_get() and put_module() when control enters a/the connector
-    callback.
   * Locking in userspace, to prevent multiple instances of drbdsetup
 
   50% DONE

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-08-29 13:50:39 UTC (rev 2391)
+++ trunk/drbd/drbd_nl.c	2006-08-31 19:06:56 UTC (rev 2392)
@@ -120,35 +120,6 @@
 void drbd_nl_send_reply(struct cn_msg *, int);
 
 
-STATIC void drbd_nl_create (void *data)
-{ 
-	static int next_minor=0;
-	int minor,ok;
-	drbd_dev *mdev = NULL;
-
-	minor = next_minor;
-
-	mdev = drbd_new_device(minor);
-	if(!mdev) goto out;
-
-	spin_lock_irq(&drbd_pp_lock); // just to protect this from itself
-	if ( (ok = next_minor < minor_count && minor == next_minor) ) {
-		minor_table[minor] = mdev;
-		wmb();
-		next_minor++;
-	}
-	spin_unlock_irq(&drbd_pp_lock);
-
-	if(!ok) {
-	out:
-		if(mdev) {
-			if(mdev->app_reads_hash) kfree(mdev->app_reads_hash);
-			if(mdev->md_io_page) __free_page(mdev->md_io_page);
-			kfree(mdev);
-		}
-	}
-}
-
 int drbd_khelper(drbd_dev *mdev, char* cmd)
 {
 	char mb[12];
@@ -332,77 +303,29 @@
 	return r;
 }
 
-STATIC drbd_dev *ensure_mdev(struct drbd_nl_cfg_req *nlp)
-{
-	drbd_dev *mdev;
 
-	mdev = minor_to_mdev(nlp->drbd_minor);
-
-	if(!mdev && (nlp->flags & DRBD_NL_CREATE_DEVICE)) {
-		mdev = drbd_new_device(nlp->drbd_minor);
-		
-		spin_lock_irq(&drbd_pp_lock);
-		if( minor_table[nlp->drbd_minor] == NULL) {
-			minor_table[nlp->drbd_minor] = mdev;
-			mdev = NULL;
-		}
-		spin_unlock_irq(&drbd_pp_lock);
-		
-		if(mdev) {
-			if(mdev->app_reads_hash) kfree(mdev->app_reads_hash);
-			if(mdev->md_io_page) __free_page(mdev->md_io_page);
-			kfree(mdev);
-			mdev = NULL;
-		}
-
-		mdev = minor_to_mdev(nlp->drbd_minor);
-	}
-
-	return mdev;
-}
-
-
-STATIC void drbd_nl_primary (void *data) 
+STATIC int drbd_nl_primary(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
 	struct primary primary_args;
-	int retcode;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-	
 	memset(&primary_args, 0, sizeof(struct primary));
 	if(!primary_from_tags(mdev,nlp->tag_list,&primary_args)) {
-		retcode=UnknownMandatoryTag;
-		goto fail;
+		reply->ret_code=UnknownMandatoryTag;
+		return 0;
 	}
 
-	retcode = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
+	reply->ret_code = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
 
- fail:
-	drbd_nl_send_reply(req, retcode );
+	return 0;
 }
 
-STATIC void drbd_nl_secondary (void *data) 
+STATIC int drbd_nl_secondary(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode;
+	reply->ret_code = drbd_set_role(mdev, Secondary, 0);
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-	
-	retcode = drbd_set_role(mdev, Secondary, 0);
-
- fail:
-	drbd_nl_send_reply(req, retcode );
+	return 0;
 }
 
 /* initializes the md.*_offset members, so we are able to find
@@ -661,23 +584,16 @@
 	}
 }
 
-STATIC void drbd_nl_disk_conf (void *data) 
+STATIC int drbd_nl_disk_conf(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
 	enum ret_codes retcode;
 	struct drbd_backing_dev* nbc=NULL; // new_backing_conf
 	struct inode *inode, *inode2;
 	struct lru_cache* resync_lru = NULL;
 	drbd_state_t ns,os;
-	drbd_dev *mdev;
 	int rv;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-	
 	/* if you want to reconfigure, please tear down first */
 	if (mdev->state.disk > Diskless) {
 		retcode=HaveDiskConfig;
@@ -955,8 +871,8 @@
 	drbd_bm_unlock(mdev);
 	drbd_md_sync(mdev);
 
-	drbd_nl_send_reply(req, NoError);
-	return;
+	reply->ret_code = retcode;
+	return 0;
 
  release_bdev3_fail:
 	drbd_force_state(mdev,NS(disk,Diskless));
@@ -973,31 +889,21 @@
 	}
 	if (resync_lru) lc_free(resync_lru);
 
-	drbd_nl_send_reply(req, retcode );
+	reply->ret_code = retcode;
+	return 0;
 }
 
-STATIC void drbd_nl_detach (void *data) 
+STATIC int drbd_nl_detach(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			  struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode;
+	reply->ret_code = drbd_request_state(mdev,NS(disk,Diskless));
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
-	retcode = drbd_request_state(mdev,NS(disk,Diskless));
-
- fail:
-	drbd_nl_send_reply(req, retcode);
+	return 0;
 }
 
-STATIC void drbd_nl_net_conf (void *data) 
+STATIC int drbd_nl_net_conf(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			    struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
 	int i,ns;
 	enum ret_codes retcode;
 	struct net_conf *new_conf = NULL;
@@ -1005,13 +911,7 @@
 	struct hlist_head *new_tl_hash = NULL;
 	struct hlist_head *new_ee_hash = NULL;
 	struct Drbd_Conf *odev;
-	drbd_dev *mdev;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
 	new_conf = kmalloc(sizeof(struct net_conf),GFP_KERNEL);
 	if(!new_conf) {			
 		retcode=KMallocFailed;
@@ -1177,8 +1077,8 @@
 
 	retcode = drbd_request_state(mdev,NS(conn,Unconnected));
 
-	drbd_nl_send_reply(req, retcode);
-	return ;
+	reply->ret_code = retcode;
+	return 0;
 
   fail:
 	if (tfm) crypto_free_tfm(tfm);
@@ -1186,22 +1086,15 @@
 	if (new_ee_hash) kfree(new_ee_hash);
 	if (new_conf) kfree(new_conf);
 
-	drbd_nl_send_reply(req, retcode);
+	reply->ret_code = retcode;
+	return 0;
 }
 
-STATIC void drbd_nl_disconnect (void *data) 
+STATIC int drbd_nl_disconnect(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
 	int retcode;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
-
 	retcode = _drbd_request_state(mdev,NS(conn,StandAlone),0);	// silently.
 
 	if ( retcode == SS_NothingToDo ) goto done;
@@ -1226,23 +1119,16 @@
 	retcode = NoError;
  fail:
 	drbd_md_sync(mdev);
-	drbd_nl_send_reply(req, retcode);
-	return ;
+	reply->ret_code = retcode;
+	return 0;
 }
 
-STATIC void drbd_nl_resize (void *data) 
+STATIC int drbd_nl_resize(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			  struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
 	struct resize rs;
-	drbd_dev *mdev;
 	int retcode=NoError;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
 	memset(&rs, 0, sizeof(struct resize));
 	if (!resize_from_tags(mdev,nlp->tag_list,&rs)) {
 		retcode=UnknownMandatoryTag;
@@ -1270,24 +1156,18 @@
 	}
 
  fail:
-	drbd_nl_send_reply(req, retcode);
+	reply->ret_code = retcode;
+	return 0;
 }
 
-STATIC void drbd_nl_syncer_conf (void *data) 
+STATIC int drbd_nl_syncer_conf(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			       struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
 	int retcode=NoError;
 	struct syncer_conf sc;
 	drbd_dev *odev;
 	int err;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
 	memcpy(&sc,&mdev->sync_conf,sizeof(struct syncer_conf));
 
 	if(nlp->flags & DRBD_NL_SET_DEFAULTS) {
@@ -1342,131 +1222,69 @@
 	drbd_alter_sa(mdev, sc.after);
 
  fail:
-	drbd_nl_send_reply(req, retcode);
-	return;
+	reply->ret_code = retcode;
+	return 0;
 }
 
-STATIC void drbd_nl_invalidate (void *data) 
+STATIC int drbd_nl_invalidate(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode;
-
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
-	retcode = drbd_request_state(mdev,NS2(conn,StartingSyncT,
-					disk,Inconsistent));
- fail:
-	drbd_nl_send_reply(req, retcode);
-	return;
+	reply->ret_code = drbd_request_state(mdev,NS2(conn,StartingSyncT,
+						      disk,Inconsistent));
+	return 0;
 }
 
-STATIC void drbd_nl_invalidate_peer (void *data) 
+STATIC int drbd_nl_invalidate_peer(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+				   struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
+	reply->ret_code = drbd_request_state(mdev,NS2(conn,StartingSyncS,
+						      pdsk,Inconsistent));
 
-	retcode = drbd_request_state(mdev,NS2(conn,StartingSyncS,
-					      pdsk,Inconsistent));
- fail:
-	drbd_nl_send_reply(req, retcode);
-	return;
+	return 0;
 }
 
-STATIC void drbd_nl_pause_sync (void *data) 
+STATIC int drbd_nl_pause_sync(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
 	int retcode=NoError;
-
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
 	
 	if(!drbd_resync_pause(mdev, UserImposed)) retcode = PauseFlagAlreadySet;
- fail:
-	drbd_nl_send_reply(req, retcode);
+	reply->ret_code = retcode;
+	return 0;
 }
 
-STATIC void drbd_nl_resume_sync (void *data) 
+STATIC int drbd_nl_resume_sync(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			       struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
 	int retcode=NoError;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-	
 	if(!drbd_resync_resume(mdev, UserImposed)) retcode = PauseFlagAlreadyClear;
- fail:
-	drbd_nl_send_reply(req, retcode);
+	reply->ret_code = retcode;
+	return 0;
 }
 
-STATIC void drbd_nl_suspend_io (void *data) 
+STATIC int drbd_nl_suspend_io(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode;
+	reply->ret_code = drbd_request_state(mdev,NS(susp,1));
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
-	retcode = drbd_request_state(mdev,NS(susp,1));
-
- fail:
-	drbd_nl_send_reply(req, retcode);
+	return 0;
 }
 
-STATIC void drbd_nl_resume_io (void *data) 
+STATIC int drbd_nl_resume_io(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode=NoError;
-
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
-	retcode = drbd_request_state(mdev,NS(susp,0));
-
- fail:
-	drbd_nl_send_reply(req, retcode);
+	reply->ret_code = drbd_request_state(mdev,NS(susp,0));
+	return 0;
 }
 
-STATIC void drbd_nl_outdate (void *data) 
+STATIC int drbd_nl_outdate(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
 	int retcode;
 	drbd_state_t os,ns;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-
 	spin_lock_irq(&mdev->req_lock);
 	os = mdev->state;
 	if( mdev->state.disk < Outdated ) {
@@ -1486,32 +1304,15 @@
 	drbd_md_sync(mdev);
 
  fail:
-	drbd_nl_send_reply(req, retcode);
+	reply->ret_code = retcode;
+	return 0;
 }
 
-
-STATIC void drbd_nl_get_config (void *data)
+STATIC int drbd_nl_get_config(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode=NoError,rr;
-	struct drbd_nl_cfg_reply* reply;
-	struct cn_msg *cn_reply;
 	unsigned short *tl;
-	int size = sizeof(struct cn_msg) + sizeof(struct drbd_nl_cfg_reply) +
-		disk_conf_tag_size + net_conf_tag_size + syncer_conf_tag_size + 2;
-
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
 	
-	if( !(cn_reply = kmalloc(size,GFP_KERNEL)) ) {
-		retcode=KMallocFailed;
-		goto fail;
-	}
-	reply = (struct drbd_nl_cfg_reply*) cn_reply->data;
 	tl = reply->tag_list;
 
 	if(inc_local(mdev)) {
@@ -1527,89 +1328,27 @@
 
 	*tl++ = TT_END; /* Close the tag list */
 
-	cn_reply->id = req->id;
-	cn_reply->seq = req->seq;
-	cn_reply->ack = req->ack  + 1;
-	cn_reply->len = (char*)tl - (char *)reply;
-	cn_reply->flags = 0;
-
-	reply->minor = nlp->drbd_minor;
-	reply->ret_code = retcode;
-
-	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
-	if(rr) printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);
-	kfree(cn_reply);
-	return;
- fail:
-	drbd_nl_send_reply(req, retcode);
+	return (int)((char*)tl - (char*)reply->tag_list);
 }
 
-STATIC void drbd_nl_get_state (void *data)
+STATIC int drbd_nl_get_state(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode=NoError,rr;
-	struct drbd_nl_cfg_reply* reply;
-	struct cn_msg *cn_reply;
 	unsigned short *tl;
-	int size = sizeof(struct cn_msg) + sizeof(struct drbd_nl_cfg_reply) +
-		get_state_tag_size;
 
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
-	
-	if( !(cn_reply = kmalloc(size,GFP_KERNEL)) ) {
-		retcode=KMallocFailed;
-		goto fail;
-	}
-	reply = (struct drbd_nl_cfg_reply*) cn_reply->data;
 	tl = reply->tag_list;
 
 	tl = get_state_to_tags(mdev,(struct get_state*)&mdev->state,tl);
 	*tl++ = TT_END; /* Close the tag list */
 
-	cn_reply->id = req->id;
-	cn_reply->seq = req->seq;
-	cn_reply->ack = req->ack  + 1;
-	cn_reply->len = (char*)tl - (char *)reply;
-	cn_reply->flags = 0;
-
-	reply->minor = nlp->drbd_minor;
-	reply->ret_code = retcode;
-
-	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
-	if(rr) printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);
-	kfree(cn_reply);
-	return;
- fail:
-	drbd_nl_send_reply(req, retcode);
+	return (int)((char*)tl - (char*)reply->tag_list);
 }
 
-STATIC void drbd_nl_get_uuids (void *data)
+STATIC int drbd_nl_get_uuids(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
 {
-	struct cn_msg *req = data;
-	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
-	drbd_dev *mdev;
-	int retcode=NoError,rr;
-	struct drbd_nl_cfg_reply* reply;
-	struct cn_msg *cn_reply;
 	unsigned short *tl;
-	int size = sizeof(struct cn_msg) + sizeof(struct drbd_nl_cfg_reply) +
-		get_uuids_tag_size;
-
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
-	}
 	
-	if( !(cn_reply = kmalloc(size,GFP_KERNEL)) ) {
-		retcode=KMallocFailed;
-		goto fail;
-	}
-	reply = (struct drbd_nl_cfg_reply*) cn_reply->data;
 	tl = reply->tag_list;
 
 	if(inc_local(mdev)) {
@@ -1626,47 +1365,137 @@
 	}
 	*tl++ = TT_END; /* Close the tag list */
 
+	return (int)((char*)tl - (char*)reply->tag_list);
+}
+
+STATIC drbd_dev *ensure_mdev(struct drbd_nl_cfg_req *nlp)
+{
+	drbd_dev *mdev;
+
+	mdev = minor_to_mdev(nlp->drbd_minor);
+
+	if(!mdev && (nlp->flags & DRBD_NL_CREATE_DEVICE)) {
+		mdev = drbd_new_device(nlp->drbd_minor);
+		
+		spin_lock_irq(&drbd_pp_lock);
+		if( minor_table[nlp->drbd_minor] == NULL) {
+			minor_table[nlp->drbd_minor] = mdev;
+			mdev = NULL;
+		}
+		spin_unlock_irq(&drbd_pp_lock);
+		
+		if(mdev) {
+			if(mdev->app_reads_hash) kfree(mdev->app_reads_hash);
+			if(mdev->md_io_page) __free_page(mdev->md_io_page);
+			kfree(mdev);
+			mdev = NULL;
+		}
+
+		mdev = minor_to_mdev(nlp->drbd_minor);
+	}
+
+	return mdev;
+}
+
+struct cn_handler_struct {
+	int (*function)(drbd_dev *,
+			 struct drbd_nl_cfg_req *, 
+			 struct drbd_nl_cfg_reply* );
+	int reply_body_size;
+};
+
+static struct cn_handler_struct cnd_table[] = {
+	[ P_primary ]		= { &drbd_nl_primary,		0 },
+	[ P_secondary ]		= { &drbd_nl_secondary,		0 },
+	[ P_disk_conf ]		= { &drbd_nl_disk_conf,		0 },
+	[ P_detach ]		= { &drbd_nl_detach,		0 },
+	[ P_net_conf ]		= { &drbd_nl_net_conf,		0 },
+	[ P_disconnect ]	= { &drbd_nl_disconnect,	0 },
+	[ P_resize ]		= { &drbd_nl_resize,		0 },
+	[ P_syncer_conf ]	= { &drbd_nl_syncer_conf,	0 },
+	[ P_invalidate ]	= { &drbd_nl_invalidate,	0 },
+	[ P_invalidate_peer ]	= { &drbd_nl_invalidate_peer,	0 },
+	[ P_pause_sync ]	= { &drbd_nl_pause_sync,	0 },
+	[ P_resume_sync ]	= { &drbd_nl_resume_sync,	0 },
+	[ P_suspend_io ]	= { &drbd_nl_suspend_io,	0 },
+	[ P_resume_io ]		= { &drbd_nl_resume_io,		0 },
+	[ P_outdate ]		= { &drbd_nl_outdate,		0 },
+	[ P_get_config ]	= { &drbd_nl_get_config,
+				    sizeof(struct syncer_conf_tag_len_struct) +
+				    sizeof(struct disk_conf_tag_len_struct) +
+				    sizeof(struct net_conf_tag_len_struct) },
+	[ P_get_state ]		= { &drbd_nl_get_state,
+				    sizeof(struct get_state_tag_len_struct) },
+	[ P_get_uuids ]		= { &drbd_nl_get_uuids,
+				    sizeof(struct get_uuids_tag_len_struct) },
+};
+
+void drbd_connector_callback(void *data)
+{
+	struct cn_msg *req = data;
+	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
+	struct cn_handler_struct *cm;
+	struct cn_msg *cn_reply;
+	struct drbd_nl_cfg_reply* reply;
+	drbd_dev *mdev;
+	int retcode,rr;
+	int reply_size = sizeof(struct cn_msg) + sizeof(struct drbd_nl_cfg_reply);
+	
+	if(!try_module_get(THIS_MODULE)) {
+		printk(KERN_ERR DEVICE_NAME "try_module_get() failed!\n");
+		return;
+	}
+
+	if( !(mdev = ensure_mdev(nlp)) ) {
+		retcode=MinorNotKnown;
+		goto fail;
+	}
+
+	if( nlp->packet_type >= P_nl_after_last_packet ) {
+		retcode=UnknownNetLinkPacket;
+		goto fail;
+	}
+
+	cm = cnd_table + nlp->packet_type;
+	reply_size += cm->reply_body_size;
+
+	if( !(cn_reply = kmalloc(reply_size,GFP_KERNEL)) ) {
+		retcode=KMallocFailed;
+		goto fail;
+	}
+	reply = (struct drbd_nl_cfg_reply*) cn_reply->data;
+
+	reply->minor = nlp->drbd_minor;
+	reply->ret_code = NoError; // Might by modified by cm->function.
+	// reply->tag_list; might be modified by cm->fucntion.
+
+	rr = cm->function(mdev,nlp,reply);
+	
 	cn_reply->id = req->id;
 	cn_reply->seq = req->seq;
 	cn_reply->ack = req->ack  + 1;
-	cn_reply->len = (char*)tl - (char *)reply;
+	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + rr;
 	cn_reply->flags = 0;
 
-	reply->minor = nlp->drbd_minor;
-	reply->ret_code = retcode;
-
 	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
 	if(rr) printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);
 	kfree(cn_reply);
+	module_put(THIS_MODULE);
 	return;
  fail:
 	drbd_nl_send_reply(req, retcode);
+	module_put(THIS_MODULE);
 }
 
-// Generate the packet_number to callback table...
-typedef void (*cn_handler)(void*);
-
-static cn_handler cnd_table[] = {
-#define PACKET(name, fields) [ P_ ## name ] = & drbd_nl_ ## name,
-#define INTEGER(pn,pr,member)
-#define INT64(pn,pr,member)
-#define BIT(pn,pr,member)
-#define STRING(pn,pr,member,len)
-#include "linux/drbd_nl.h"
-};
-
 int __init drbd_nl_init()
 {
-	static struct cb_id cn_id_drbd = { CN_IDX_DRBD, 0 };
-	int i,err;
+	static struct cb_id cn_id_drbd = { CN_IDX_DRBD, CN_VAL_DRBD };
+	int err;
 
-	for(i=0;i<P_nl_after_last_packet;i++) {
-		cn_id_drbd.val = i;
-		err = cn_add_callback(&cn_id_drbd,"cn_drbd",cnd_table[i]);
-		if(err) {
-			printk(KERN_ERR DEVICE_NAME "cn_drbd failed to register\n");
-			return err;
-		}
+	err = cn_add_callback(&cn_id_drbd,"cn_drbd",&drbd_connector_callback);
+	if(err) {
+		printk(KERN_ERR DEVICE_NAME "cn_drbd failed to register\n");
+		return err;
 	}
 
 	return 0;

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-08-29 13:50:39 UTC (rev 2391)
+++ trunk/drbd/linux/drbd.h	2006-08-31 19:06:56 UTC (rev 2392)
@@ -103,6 +103,7 @@
 	PauseFlagAlreadyClear,
 	DiskLowerThanOutdated,
 	FailedToClaimMyself,
+	UnknownNetLinkPacket,
 	AfterLastRetCode,
 };
 
@@ -247,8 +248,10 @@
 // The following line should be moved over to linux/connector.h
 // when the time comes
 #define CN_IDX_DRBD			0x4
+#define CN_VAL_DRBD			0x1
 
 struct drbd_nl_cfg_req {
+	int packet_type;
 	int drbd_minor;
 	int flags;
 	unsigned short tag_list[];

Modified: trunk/drbd/linux/drbd_tag_magic.h
===================================================================
--- trunk/drbd/linux/drbd_tag_magic.h	2006-08-29 13:50:39 UTC (rev 2391)
+++ trunk/drbd/linux/drbd_tag_magic.h	2006-08-31 19:06:56 UTC (rev 2392)
@@ -15,13 +15,24 @@
 	P_nl_after_last_packet,
 };
 
+// These struct are used to deduce the size of the tag lists:
+#define PACKET(name, fields) struct name ## _tag_len_struct { fields };
+#define INTEGER(pn,pr,member) int member; int tag_and_len ## member;
+#define INT64(pn,pr,member) __u64 member; int tag_and_len ## member;
+#define BIT(pn,pr,member)   unsigned char member : 1; int tag_and_len ## member;
+#define STRING(pn,pr,member,len) unsigned char member[len]; int member ## _len; \
+				 int tag_and_len ## member;
+#include "linux/drbd_nl.h"
+
 // declate tag-list-sizes
-#define PACKET(name,fields) const int name ## _tag_size = 2 fields ;
+const int tag_list_sizes[] = {
+#define PACKET(name,fields) 2 fields ,
 #define INTEGER(pn,pr,member)     +4+4 
 #define INT64(pn,pr,member)       +4+8
 #define BIT(pn,pr,member)         +4+1
 #define STRING(pn,pr,member,len)  +4+len
 #include "drbd_nl.h"
+};
 
 /* The two highest bits are used for the tag type */
 #define TT_MASK      0xC000

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-08-29 13:50:39 UTC (rev 2391)
+++ trunk/user/drbdsetup.c	2006-08-31 19:06:56 UTC (rev 2392)
@@ -1053,6 +1053,10 @@
 	prevcol=col=0;
 
 	col += snprintf(line+col, maxcol-col, " %s", commands[i].cmd);
+
+	// Only those config commands have arguments and options...
+	if(commands[i].function != generic_config_cmd) goto out;
+
 	if ((args = commands[i].cp.args)) {
 		while (args->name) {
 			col += snprintf(line+col, maxcol-col, " %s", args->name);
@@ -1087,6 +1091,8 @@
 		}
 	}
 	line[col]=0;
+
+ out:
 	printf("%s\n",line);
 	if (addinfo) {
 		printf("%s\n",addinfo);
@@ -1210,7 +1216,8 @@
 
 int send_tag_list_cn(int sk_nl, struct drbd_tag_list *tl, const int packet_id, int minor, int flags)
 {
-	tl->cn_header->id.val = packet_id;
+	tl->cn_header->id.val = CN_VAL_DRBD;
+	tl->drbd_p_header->packet_type = packet_id;
 	tl->drbd_p_header->drbd_minor = minor;
 	tl->drbd_p_header->flags = flags;
 



More information about the drbd-cvs mailing list