[LinuxPPS] [PATCH 02c/12] PPS: Clean up parameter get/set.

George Spelvin linux at horizon.com
Tue Feb 10 04:58:14 CET 2009


The setting took the spinlock, but the getting didn't, leading to
possible races.  And the parameter cleanup was a bit messy; straighten
it out.

Thinking, that spinlock should now be a mutex or something.
This patch probably needs redoing.
---
 drivers/pps/pps.c |   27 +++++++++++++--------------
 1 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index 92fc76a..d08fe3d 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -79,8 +79,9 @@ static long pps_cdev_ioctl(struct file *file,
 		pr_debug("PPS_GETPARAMS: source %d\n", pps->id);
 
 		/* Return current parameters */
-		err = copy_to_user(uarg, &pps->params,
-						sizeof(struct pps_kparams));
+		spin_lock(&pps->lock);
+		err = copy_to_user(uarg, &pps->params, sizeof pps->params);
+		spin_unlock(&pps->lock);
 		if (err)
 			return -EFAULT;
 
@@ -93,7 +94,7 @@ static long pps_cdev_ioctl(struct file *file,
 		if (!capable(CAP_SYS_TIME))
 			return -EPERM;
 
-		err = copy_from_user(&params, uarg, sizeof(struct pps_kparams));
+		err = copy_from_user(&params, uarg, sizeof params);
 		if (err)
 			return -EFAULT;
 		if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) {
@@ -109,23 +110,21 @@ static long pps_cdev_ioctl(struct file *file,
 			return -EINVAL;
 		}
 
-		spin_lock_irq(&pps->lock);
-
-		/* Save the new parameters */
-		pps->params = params;
-
 		/* Restore the read only parameters */
 		if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
 			/* section 3.3 of RFC 2783 interpreted */
 			pr_debug("time format unspecified (%x)\n",
 								params.mode);
-			pps->params.mode |= PPS_TSFMT_TSPEC;
+			params.mode |= PPS_TSFMT_TSPEC;
 		}
 		if (pps->info.mode & PPS_CANWAIT)
-			pps->params.mode |= PPS_CANWAIT;
-		pps->params.api_version = PPS_API_VERS;
+			params.mode |= PPS_CANWAIT;
+		params.api_version = PPS_API_VERS;
 
-		spin_unlock_irq(&pps->lock);
+		/* Save the new parameters */
+		spin_lock(&pps->lock);
+		pps->params = params;
+		spin_unlock(&pps->lock);
 
 		break;
 
@@ -141,7 +140,7 @@ static long pps_cdev_ioctl(struct file *file,
 	case PPS_FETCH:
 		pr_debug("PPS_FETCH: source %d\n", pps->id);
 
-		err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata));
+		err = copy_from_user(&fdata, uarg, sizeof fdata);
 		if (err)
 			return -EFAULT;
 
@@ -199,7 +198,7 @@ static int pps_cdev_open(struct inode *inode, struct file *file)
 						struct pps_device, cdev);
 	int found;
 
-	found = pps_get_source(pps->id) != 0;
+	found = pps_get_source(pps->id) != 0;	/* Bump refcount */
 	if (!found)
 		return -ENODEV;
 
-- 
1.6.0.6




More information about the LinuxPPS mailing list