[PATCH 53/58] staging/lustre/obd: move status files from procfs to debugfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Dmitry Eremin <dmiter4ever@xxxxxxxxx>

change type of
* obd->obd_proc_entry
* obd->obd_svc_procroot
* lov->lov_pool_proc_entry
* obd_type->typ_procroot
* pool_desc->pool_proc_entry

Signed-off-by: Dmitry Eremin <dmiter4ever@xxxxxxxxx>
Signed-off-by: Oleg Drokin <green@xxxxxxxxxxxxxx>
---
 .../staging/lustre/lustre/include/lprocfs_status.h |  4 ++
 drivers/staging/lustre/lustre/include/obd.h        | 10 ++--
 drivers/staging/lustre/lustre/lmv/lmv_obd.c        | 14 ++---
 drivers/staging/lustre/lustre/lmv/lproc_lmv.c      |  2 +-
 drivers/staging/lustre/lustre/lov/lov_obd.c        | 19 +++----
 drivers/staging/lustre/lustre/lov/lov_pool.c       | 31 +++++------
 drivers/staging/lustre/lustre/lov/lproc_lov.c      |  2 +-
 drivers/staging/lustre/lustre/mdc/lproc_mdc.c      |  2 +-
 drivers/staging/lustre/lustre/obdclass/genops.c    | 17 +++---
 .../lustre/lustre/obdclass/lprocfs_status.c        | 63 ++++++++++++++--------
 drivers/staging/lustre/lustre/osc/lproc_osc.c      |  4 +-
 .../staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c    | 12 ++---
 12 files changed, 98 insertions(+), 82 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index bbacda6..721efd6 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -565,6 +565,10 @@ extern int lprocfs_add_clear_entry(struct obd_device *obd,
 extern int lprocfs_exp_setup(struct obd_export *exp,
 			     lnet_nid_t *peer_nid, int *newnid);
 extern int lprocfs_exp_cleanup(struct obd_export *exp);
+extern struct dentry *ldebugfs_add_simple(struct dentry *root,
+					  char *name,
+					  void *data,
+					  struct file_operations *fops);
 extern struct proc_dir_entry *lprocfs_add_simple(struct proc_dir_entry *root,
 						char *name,
 						void *data,
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index 35f5fe7..d3df9eb 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -244,7 +244,7 @@ struct obd_type {
 	struct list_head typ_chain;
 	struct obd_ops *typ_dt_ops;
 	struct md_ops *typ_md_ops;
-	struct proc_dir_entry *typ_procroot;
+	struct dentry *typ_debugfs_entry;
 	char *typ_name;
 	int  typ_refcnt;
 	struct lu_device_type *typ_lu;
@@ -545,7 +545,7 @@ struct pool_desc {
 	struct lov_qos_rr     pool_rr;		/* round robin qos */
 	struct hlist_node      pool_hash;	      /* access by poolname */
 	struct list_head	    pool_list;	      /* serial access */
-	struct proc_dir_entry *pool_proc_entry;	/* file in /proc */
+	struct dentry		*pool_debugfs_entry;	/* file in /proc */
 	struct obd_device    *pool_lobd;	/* obd of the lov/lod to which
 						*  this pool belongs */
 };
@@ -566,7 +566,7 @@ struct lov_obd {
 	int		     lov_pool_count;
 	struct cfs_hash	     *lov_pools_hash_body; /* used for key access */
 	struct list_head	lov_pool_list; /* used for sequential access */
-	struct proc_dir_entry   *lov_pool_proc_entry;
+	struct dentry		*lov_pool_debugfs_entry;
 	enum lustre_sec_part    lov_sp_me;
 
 	/* Cached LRU pages from upper layer */
@@ -917,9 +917,9 @@ struct obd_device {
 	unsigned int	   md_cntr_base;
 	struct lprocfs_stats  *md_stats;
 
-	struct proc_dir_entry  *obd_proc_entry;
+	struct dentry		*obd_debugfs_entry;
 	struct proc_dir_entry  *obd_proc_exports_entry;
-	struct proc_dir_entry  *obd_svc_procroot;
+	struct dentry		*obd_svc_debugfs_entry;
 	struct lprocfs_stats  *obd_svc_stats;
 	atomic_t	   obd_evict_inprogress;
 	wait_queue_head_t	    obd_evict_inprogress_waitq;
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index 65c0138..aca686a 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -1310,15 +1310,11 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 	lprocfs_lmv_init_vars(&lvars);
 
 	lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars);
-#if defined (CONFIG_PROC_FS)
-	{
-		rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
-					0444, &lmv_proc_target_fops, obd);
-		if (rc)
-			CWARN("%s: error adding LMV target_obd file: rc = %d\n",
-			       obd->obd_name, rc);
-       }
-#endif
+	rc = ldebugfs_seq_create(obd->obd_debugfs_entry, "target_obd",
+				 0444, &lmv_proc_target_fops, obd);
+	if (rc)
+		CWARN("%s: error adding LMV target_obd file: rc = %d\n",
+		      obd->obd_name, rc);
 	rc = fld_client_init(&lmv->lmv_fld, obd->obd_name,
 			     LUSTRE_CLI_FLD_HASH_DHT);
 	if (rc) {
diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
index b113e5a..8583fe2 100644
--- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
+++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
@@ -194,7 +194,7 @@ static int lmv_target_seq_open(struct inode *inode, struct file *file)
 		return rc;
 
 	seq = file->private_data;
-	seq->private = PDE_DATA(inode);
+	seq->private = inode->i_private;
 
 	return 0;
 }
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
index caf1aff..b5dc9e1 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -810,20 +810,15 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 
 	lprocfs_lov_init_vars(&lvars);
 	lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars);
-#if defined (CONFIG_PROC_FS)
-	{
-		int rc1;
 
-		rc1 = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
-					0444, &lov_proc_target_fops, obd);
-		if (rc1)
-			CWARN("Error adding the target_obd file\n");
-	}
-#endif
-	lov->lov_pool_proc_entry = lprocfs_register("pools",
-						    obd->obd_proc_entry,
-						    NULL, NULL);
+	rc = ldebugfs_seq_create(obd->obd_debugfs_entry, "target_obd",
+				 0444, &lov_proc_target_fops, obd);
+	if (rc)
+		CWARN("Error adding the target_obd file\n");
 
+	lov->lov_pool_debugfs_entry = ldebugfs_register("pools",
+						     obd->obd_debugfs_entry,
+						     NULL, NULL);
 	return 0;
 
 out:
diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c
index 75301fa..30a29fd 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pool.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pool.c
@@ -64,7 +64,7 @@ void lov_pool_putref(struct pool_desc *pool)
 	if (atomic_dec_and_test(&pool->pool_refcount)) {
 		LASSERT(hlist_unhashed(&pool->pool_hash));
 		LASSERT(list_empty(&pool->pool_list));
-		LASSERT(pool->pool_proc_entry == NULL);
+		LASSERT(pool->pool_debugfs_entry == NULL);
 		lov_ost_pool_free(&(pool->pool_rr.lqr_pool));
 		lov_ost_pool_free(&(pool->pool_obds));
 		kfree(pool);
@@ -283,7 +283,7 @@ static int pool_proc_open(struct inode *inode, struct file *file)
 	rc = seq_open(file, &pool_proc_ops);
 	if (!rc) {
 		struct seq_file *s = file->private_data;
-		s->private = PDE_DATA(inode);
+		s->private = inode->i_private;
 	}
 	return rc;
 }
@@ -454,20 +454,21 @@ int lov_pool_new(struct obd_device *obd, char *poolname)
 
 	INIT_HLIST_NODE(&new_pool->pool_hash);
 
-#if defined (CONFIG_PROC_FS)
 	/* we need this assert seq_file is not implemented for liblustre */
 	/* get ref for /proc file */
 	lov_pool_getref(new_pool);
-	new_pool->pool_proc_entry = lprocfs_add_simple(lov->lov_pool_proc_entry,
-						       poolname, new_pool,
-						       &pool_proc_operations);
-	if (IS_ERR(new_pool->pool_proc_entry)) {
-		CWARN("Cannot add proc pool entry "LOV_POOLNAMEF"\n", poolname);
-		new_pool->pool_proc_entry = NULL;
+	new_pool->pool_debugfs_entry = ldebugfs_add_simple(
+						lov->lov_pool_debugfs_entry,
+						poolname, new_pool,
+						&pool_proc_operations);
+	if (IS_ERR_OR_NULL(new_pool->pool_debugfs_entry)) {
+		CWARN("Cannot add debugfs pool entry "LOV_POOLNAMEF"\n",
+		      poolname);
+		new_pool->pool_debugfs_entry = NULL;
 		lov_pool_putref(new_pool);
 	}
-	CDEBUG(D_INFO, "pool %p - proc %p\n", new_pool, new_pool->pool_proc_entry);
-#endif
+	CDEBUG(D_INFO, "pool %p - proc %p\n",
+		new_pool, new_pool->pool_debugfs_entry);
 
 	spin_lock(&obd->obd_dev_lock);
 	list_add_tail(&new_pool->pool_list, &lov->lov_pool_list);
@@ -493,7 +494,7 @@ out_err:
 	lov->lov_pool_count--;
 	spin_unlock(&obd->obd_dev_lock);
 
-	lprocfs_remove(&new_pool->pool_proc_entry);
+	ldebugfs_remove(&new_pool->pool_debugfs_entry);
 
 	lov_ost_pool_free(&new_pool->pool_rr.lqr_pool);
 out_free_pool_obds:
@@ -514,9 +515,9 @@ int lov_pool_del(struct obd_device *obd, char *poolname)
 	if (pool == NULL)
 		return -ENOENT;
 
-	if (pool->pool_proc_entry != NULL) {
-		CDEBUG(D_INFO, "proc entry %p\n", pool->pool_proc_entry);
-		lprocfs_remove(&pool->pool_proc_entry);
+	if (!IS_ERR_OR_NULL(pool->pool_debugfs_entry)) {
+		CDEBUG(D_INFO, "proc entry %p\n", pool->pool_debugfs_entry);
+		ldebugfs_remove(&pool->pool_debugfs_entry);
 		lov_pool_putref(pool);
 	}
 
diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c
index 41bb5b5..380b827 100644
--- a/drivers/staging/lustre/lustre/lov/lproc_lov.c
+++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c
@@ -258,7 +258,7 @@ static int lov_target_seq_open(struct inode *inode, struct file *file)
 		return rc;
 
 	seq = file->private_data;
-	seq->private = PDE_DATA(inode);
+	seq->private = inode->i_private;
 	return 0;
 }
 
diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
index 2121ca7..858d568 100644
--- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
+++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
@@ -84,7 +84,7 @@ LUSTRE_RW_ATTR(max_rpcs_in_flight);
 
 static int mdc_kuc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, NULL, PDE_DATA(inode));
+	return single_open(file, NULL, inode->i_private ?: PDE_DATA(inode));
 }
 
 /* temporary for testing */
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 8e3dfaf..978c3c5 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -191,11 +191,13 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
 	strcpy(type->typ_name, name);
 	spin_lock_init(&type->obd_type_lock);
 
-	type->typ_procroot = lprocfs_register(type->typ_name, proc_lustre_root,
-					      NULL, type);
-	if (IS_ERR(type->typ_procroot)) {
-		rc = PTR_ERR(type->typ_procroot);
-		type->typ_procroot = NULL;
+	type->typ_debugfs_entry = ldebugfs_register(type->typ_name,
+						    debugfs_lustre_root,
+						    NULL, type);
+	if (IS_ERR_OR_NULL(type->typ_debugfs_entry)) {
+		rc = type->typ_debugfs_entry ? PTR_ERR(type->typ_debugfs_entry)
+					     : -ENOMEM;
+		type->typ_debugfs_entry = NULL;
 		goto failed;
 	}
 
@@ -250,9 +252,8 @@ int class_unregister_type(const char *name)
 	if (type->typ_kobj)
 		kobject_put(type->typ_kobj);
 
-	if (type->typ_procroot) {
-		lprocfs_remove(&type->typ_procroot);
-	}
+	if (!IS_ERR_OR_NULL(type->typ_debugfs_entry))
+		ldebugfs_remove(&type->typ_debugfs_entry);
 
 	if (type->typ_lu)
 		lu_device_type_fini(type->typ_lu);
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
index b683d50..e7eae43 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
@@ -243,6 +243,29 @@ EXPORT_SYMBOL(lprocfs_seq_release);
 
 /* lprocfs API calls */
 
+struct dentry *ldebugfs_add_simple(struct dentry *root,
+				   char *name, void *data,
+				   struct file_operations *fops)
+{
+	struct dentry *entry;
+	umode_t mode = 0;
+
+	if (root == NULL || name == NULL || fops == NULL)
+		return ERR_PTR(-EINVAL);
+
+	if (fops->read)
+		mode = 0444;
+	if (fops->write)
+		mode |= 0200;
+	entry = debugfs_create_file(name, mode, root, data, fops);
+	if (IS_ERR_OR_NULL(entry)) {
+		CERROR("LprocFS: No memory to create <debugfs> entry %s", name);
+		return entry ?: ERR_PTR(-ENOMEM);
+	}
+	return entry;
+}
+EXPORT_SYMBOL(ldebugfs_add_simple);
+
 struct proc_dir_entry *lprocfs_add_simple(struct proc_dir_entry *root,
 				     char *name, void *data,
 				     struct file_operations *fops)
@@ -1036,10 +1059,6 @@ int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list,
 {
 	int rc = 0;
 
-	LASSERT(obd != NULL);
-	LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
-	LASSERT(obd->obd_type->typ_procroot != NULL);
-
 	init_completion(&obd->obd_kobj_unregister);
 	rc = kobject_init_and_add(&obd->obd_kobj, &obd_ktype,
 				  obd->obd_type->typ_kobj,
@@ -1055,15 +1074,15 @@ int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list,
 		}
 	}
 
-	obd->obd_proc_entry = lprocfs_register(obd->obd_name,
-					       obd->obd_type->typ_procroot,
-					       list, obd);
-	if (IS_ERR(obd->obd_proc_entry)) {
-		kobject_put(&obd->obd_kobj);
-		rc = PTR_ERR(obd->obd_proc_entry);
+	obd->obd_debugfs_entry = ldebugfs_register(obd->obd_name,
+						   obd->obd_type->typ_debugfs_entry,
+						   list, obd);
+	if (IS_ERR_OR_NULL(obd->obd_debugfs_entry)) {
+		rc = obd->obd_debugfs_entry ? PTR_ERR(obd->obd_debugfs_entry)
+					    : -ENOMEM;
 		CERROR("error %d setting up lprocfs for %s\n",
 		       rc, obd->obd_name);
-		obd->obd_proc_entry = NULL;
+		obd->obd_debugfs_entry = NULL;
 	}
 
 	return rc;
@@ -1074,17 +1093,19 @@ int lprocfs_obd_cleanup(struct obd_device *obd)
 {
 	if (!obd)
 		return -EINVAL;
+
 	if (obd->obd_proc_exports_entry) {
 		/* Should be no exports left */
 		lprocfs_remove(&obd->obd_proc_exports_entry);
 		obd->obd_proc_exports_entry = NULL;
 	}
-	if (obd->obd_proc_entry) {
-		lprocfs_remove(&obd->obd_proc_entry);
-		obd->obd_proc_entry = NULL;
-	}
+
+	if (!IS_ERR_OR_NULL(obd->obd_debugfs_entry))
+		ldebugfs_remove(&obd->obd_debugfs_entry);
+
 	kobject_put(&obd->obd_kobj);
 	wait_for_completion(&obd->obd_kobj_unregister);
+
 	return 0;
 }
 EXPORT_SYMBOL(lprocfs_obd_cleanup);
@@ -1507,7 +1528,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
 	int rc, i;
 
 	LASSERT(obd->obd_stats == NULL);
-	LASSERT(obd->obd_proc_entry != NULL);
+	LASSERT(obd->obd_debugfs_entry != NULL);
 	LASSERT(obd->obd_cntr_base == 0);
 
 	num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
@@ -1528,7 +1549,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
 			 "Missing obd_stat initializer obd_op operation at offset %d.\n",
 			 i - num_private_stats);
 	}
-	rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
+	rc = ldebugfs_register_stats(obd->obd_debugfs_entry, "stats", stats);
 	if (rc < 0) {
 		lprocfs_free_stats(&stats);
 	} else {
@@ -1598,7 +1619,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd,
 	int rc, i;
 
 	LASSERT(obd->md_stats == NULL);
-	LASSERT(obd->obd_proc_entry != NULL);
+	LASSERT(obd->obd_debugfs_entry != NULL);
 	LASSERT(obd->md_cntr_base == 0);
 
 	num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
@@ -1616,7 +1637,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd,
 			LBUG();
 		}
 	}
-	rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
+	rc = ldebugfs_register_stats(obd->obd_debugfs_entry, "md_stats", stats);
 	if (rc < 0) {
 		lprocfs_free_stats(&stats);
 	} else {
@@ -2135,8 +2156,8 @@ int lprocfs_obd_seq_create(struct obd_device *dev,
 			   const struct file_operations *seq_fops,
 			   void *data)
 {
-	return lprocfs_seq_create(dev->obd_proc_entry, name,
-				  mode, seq_fops, data);
+	return ldebugfs_seq_create(dev->obd_debugfs_entry, name,
+				   mode, seq_fops, data);
 }
 EXPORT_SYMBOL(lprocfs_obd_seq_create);
 
diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c
index 2f07ea5..0ba2c36 100644
--- a/drivers/staging/lustre/lustre/osc/lproc_osc.c
+++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c
@@ -738,8 +738,8 @@ int lproc_osc_attach_seqstat(struct obd_device *dev)
 {
 	int rc;
 
-	rc = lprocfs_seq_create(dev->obd_proc_entry, "osc_stats", 0644,
-				&osc_stats_fops, dev);
+	rc = ldebugfs_seq_create(dev->obd_debugfs_entry, "osc_stats", 0644,
+				 &osc_stats_fops, dev);
 	if (rc == 0)
 		rc = lprocfs_obd_seq_create(dev, "rpc_stats", 0644,
 					    &osc_rpc_stats_fops, dev);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
index 8c0c995..cf5196a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -1142,11 +1142,9 @@ void ptlrpc_ldebugfs_register_service(struct dentry *entry,
 
 void ptlrpc_lprocfs_register_obd(struct obd_device *obddev)
 {
-/* TODO: enable after change type of obddev->obd_proc_entry
- *	ptlrpc_ldebugfs_register(obddev->obd_proc_entry, NULL, "stats",
- *				&obddev->obd_svc_procroot,
- *				&obddev->obd_svc_stats);
- */
+	ptlrpc_ldebugfs_register(obddev->obd_debugfs_entry, NULL, "stats",
+				 &obddev->obd_svc_debugfs_entry,
+				 &obddev->obd_svc_stats);
 }
 EXPORT_SYMBOL(ptlrpc_lprocfs_register_obd);
 
@@ -1203,8 +1201,8 @@ void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc)
 
 void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd)
 {
-	if (obd->obd_svc_procroot)
-		lprocfs_remove(&obd->obd_svc_procroot);
+	if (!IS_ERR_OR_NULL(obd->obd_svc_debugfs_entry))
+		ldebugfs_remove(&obd->obd_svc_debugfs_entry);
 
 	if (obd->obd_svc_stats)
 		lprocfs_free_stats(&obd->obd_svc_stats);
-- 
2.1.0

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux