All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.10-rc3] sys_ioctl: Add an unlocked_ioctl file operation
@ 2004-12-08 16:49 Mike Werner
  0 siblings, 0 replies; only message in thread
From: Mike Werner @ 2004-12-08 16:49 UTC (permalink / raw)
  To: linux-kernel

# This is a BitKeeper generated diff -Nru style patch.
#
# Add an unlocked_ioctl file operation
# It assumes if unlocked_ioctl is defined in fops
# then the driver can handle concurrency and
# lock_kernel isn't called.
#
# Signed-off-by: Mike Werner  <werner@sgi.com>
# 
diff -Nru a/fs/ioctl.c b/fs/ioctl.c
--- a/fs/ioctl.c	2004-12-07 16:14:55 -08:00
+++ b/fs/ioctl.c	2004-12-07 16:14:55 -08:00
@@ -16,6 +16,8 @@
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
+/* Any additions in file_ioctl need to be added to the lock_kernel filter in sys_ioctl */
+ 
 static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
 {
 	int error;
@@ -46,7 +48,9 @@
 		case FIONREAD:
 			return put_user(i_size_read(inode) - filp->f_pos, p);
 	}
-	if (filp->f_op && filp->f_op->ioctl)
+	if (filp->f_op && filp->f_op->unlocked_ioctl)
+		return filp->f_op->unlocked_ioctl(inode, filp, cmd, arg);
+	else if (filp->f_op && filp->f_op->ioctl)
 		return filp->f_op->ioctl(inode, filp, cmd, arg);
 	return -ENOTTY;
 }
@@ -56,7 +60,7 @@
 {	
 	struct file * filp;
 	unsigned int flag;
-	int on, error = -EBADF;
+	int on, locked, error = -EBADF;
 
 	filp = fget(fd);
 	if (!filp)
@@ -68,7 +72,26 @@
                 goto out;
         }
 
-	lock_kernel();
+	switch (cmd) {
+		case FIOCLEX:
+		case FIONCLEX:
+		case FIONBIO:
+		case FIOASYNC:
+		case FIOQSIZE:
+		case FIBMAP:
+		case FIGETBSZ:
+		case FIONREAD:
+			lock_kernel();
+			locked=1;
+			break;
+		default:
+			locked=0;
+			if (filp->f_op && !filp->f_op->unlocked_ioctl) {
+				lock_kernel();
+				locked=1;
+			}
+	}
+
 	switch (cmd) {
 		case FIOCLEX:
 			set_close_on_exec(fd, 1);
@@ -127,10 +150,13 @@
 			error = -ENOTTY;
 			if (S_ISREG(filp->f_dentry->d_inode->i_mode))
 				error = file_ioctl(filp, cmd, arg);
+			else if (filp->f_op && filp->f_op->unlocked_ioctl)
+				error = filp->f_op->unlocked_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
 			else if (filp->f_op && filp->f_op->ioctl)
 				error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
 	}
-	unlock_kernel();
+	if (locked)
+		unlock_kernel();
 	fput(filp);
 
 out:
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	2004-12-07 16:14:55 -08:00
+++ b/include/linux/fs.h	2004-12-07 16:14:55 -08:00
@@ -915,6 +915,7 @@
 	int (*readdir) (struct file *, void *, filldir_t);
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
+	int (*unlocked_ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
 	int (*mmap) (struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
 	int (*flush) (struct file *);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2004-12-08 16:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-08 16:49 [PATCH 2.6.10-rc3] sys_ioctl: Add an unlocked_ioctl file operation Mike Werner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.