All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@zip.com.au>
To: Suresh Gopalakrishnan <gsuresh@cs.rutgers.edu>
Cc: linux-kernel@vger.kernel.org, Andrea Arcangeli <andrea@suse.de>
Subject: Re: O_DIRECT wierd behavior..
Date: Sat, 15 Dec 2001 21:59:06 -0800	[thread overview]
Message-ID: <3C1C382A.946EA61B@zip.com.au> (raw)
In-Reply-To: <Pine.GSO.4.02A.10112151947010.14453-100000@aramis.rutgers.edu>

Suresh Gopalakrishnan wrote:
> 
> I tried this small piece of code from an old post in the archive:
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <sys/types.h>
> #include <unistd.h>
> 
> #define O_DIRECT         040000 /* direct disk access hint */
> 
> int main()
> {
>         char buf[16384];
>         int fd;
>         char *p;
> 
>         p = (char *)((((unsigned long)buf) + 8191) & ~8191L);
>         fd = open("/tmp/blah", O_CREAT | O_RDWR | O_DIRECT);
> 
>         printf("write returns %i\n", write(fd, buf, 8192));
>         printf("write returns %i\n", write(fd, p, 1));
> 
>         return 0;
> }
> 

The app has a bug in it (I think); but the kernel has four.
Your first write fails because `buf' is not page-aligned.

Then the kernel screws up the error handling, and ends up
setting the file size to -EINVAL (ie: rather large).



1: We're testing `written >= 0', but it is unsigned (!).  In two
   places.

   This one, IMO is a gcc shortcoming.  The compiler is capable of warning
   about expressions which always evaluate to true or false in `if' statements,
   but turning this on also enables lots of things you don't want it to warn about.
   gcc needs to provide finer control of its warning capabilities.  I patched
   gcc-2.7.2.3 to do this ages back and it was very useful.

2: If generic_osync_inode() returns an error, we fail to report it.  In
   two places.

Here's a quick fix.  It needs a review.



--- linux-2.4.17-rc1/mm/filemap.c	Thu Dec 13 14:07:55 2001
+++ linux-akpm/mm/filemap.c	Sat Dec 15 21:52:06 2001
@@ -3038,8 +3038,11 @@ unlock:
 	/* For now, when the user asks for O_SYNC, we'll actually
 	 * provide O_DSYNC. */
 	if (status >= 0) {
-		if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+		if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
 			status = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
+			if (status < 0)
+				written = 0;	/* Return the right thing */
+		}
 	}
 	
 out_status:	
@@ -3054,7 +3057,8 @@ fail_write:
 
 o_direct:
 	written = generic_file_direct_IO(WRITE, file, (char *) buf, count, pos);
-	if (written > 0) {
+	status = written;
+	if (status > 0) {
 		loff_t end = pos + written;
 		if (end > inode->i_size && !S_ISBLK(inode->i_mode)) {
 			inode->i_size = end;
@@ -3067,8 +3071,11 @@ o_direct:
 	 * Sync the fs metadata but not the minor inode changes and
 	 * of course not the data as we did direct DMA for the IO.
 	 */
-	if (written >= 0 && file->f_flags & O_SYNC)
+	if (status >= 0 && file->f_flags & O_SYNC) {
 		status = generic_osync_inode(inode, OSYNC_METADATA);
+		if (status < 0)
+			written = 0;	/* Return the right thing */
+	}
 	goto out_status;
 }

  reply	other threads:[~2001-12-16  6:00 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-12-16  0:47 O_DIRECT wierd behavior Suresh Gopalakrishnan
2001-12-16  5:59 ` Andrew Morton [this message]
2001-12-16  8:17   ` GOTO Masanori
2001-12-16  8:46     ` Andrew Morton
2001-12-16  9:20       ` Suresh Gopalakrishnan
2001-12-16 13:57         ` Terje Eggestad
2001-12-16 17:43           ` Suresh Gopalakrishnan
2001-12-17  9:04             ` Terje Eggestad
2001-12-17 17:18     ` Andrea Arcangeli
2001-12-17 18:07       ` Hugh Dickins
2001-12-17 18:13         ` Andrea Arcangeli
2001-12-17 18:57         ` Andrew Morton
2001-12-17 19:26           ` Linus Torvalds
2001-12-17 19:53             ` Joel Becker
2001-12-17 19:59               ` Linus Torvalds
2001-12-17 20:20                 ` Joel Becker
2001-12-17 20:38                   ` Andre Hedrick
2001-12-26 14:54             ` Riley Williams
2001-12-16  6:29 ` GOTO Masanori
2002-01-20  4:16 ` multithreaded RPC handling Suresh Gopalakrishnan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C1C382A.946EA61B@zip.com.au \
    --to=akpm@zip.com.au \
    --cc=andrea@suse.de \
    --cc=gsuresh@cs.rutgers.edu \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.