patch-2.4.10 linux/fs/fcntl.c

Next file: linux/fs/file_table.c
Previous file: linux/fs/fat/inode.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.9/linux/fs/fcntl.c linux/fs/fcntl.c
@@ -10,6 +10,7 @@
 #include <linux/dnotify.h>
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
+#include <linux/iobuf.h>
 
 #include <asm/poll.h>
 #include <asm/siginfo.h>
@@ -194,7 +195,7 @@
 	return ret;
 }
 
-#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
+#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT)
 
 static int setfl(int fd, struct file * filp, unsigned long arg)
 {
@@ -215,6 +216,25 @@
 			if (error < 0)
 				return error;
 		}
+	}
+
+	if (arg & O_DIRECT) {
+		/*
+		 * alloc_kiovec() can sleep and we are only serialized by
+		 * the big kernel lock here, so abuse the i_sem to serialize
+		 * this case too. We of course wouldn't need to go deep down
+		 * to the inode layer, we could stay at the file layer, but
+		 * we don't want to pay for the memory of a semaphore in each
+		 * file structure too and we use the inode semaphore that we just
+		 * pay for anyways.
+		 */
+		error = 0;
+		down(&inode->i_sem);
+		if (!filp->f_iobuf)
+			error = alloc_kiovec(1, &filp->f_iobuf);
+		up(&inode->i_sem);
+		if (error < 0)
+			return error;
 	}
 
 	/* required for strict SunOS emulation */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)