Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Sun, 16 Dec 2001 01:30:16 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Sun, 16 Dec 2001 01:30:07 -0500 Received: from megaela.fe.dis.titech.ac.jp ([131.112.171.110]:25351 "HELO megaela.srvf.org") by vger.kernel.org with SMTP id ; Sun, 16 Dec 2001 01:29:53 -0500 Date: Sun, 16 Dec 2001 15:29:40 +0900 Message-ID: From: GOTO Masanori To: Suresh Gopalakrishnan Cc: linux-kernel@vger.kernel.org, marcelo@conectiva.com.br, torvalds@transmeta.com, gotom@debian.org Subject: Re: O_DIRECT wierd behavior.. In-Reply-To: In-Reply-To: User-Agent: Wanderlust/2.7.6 (Too Funky) SEMI/1.14.3 (Ushinoya) FLIM/1.14.3 (=?ISO-8859-4?Q?Unebigory=F2mae?=) APEL/10.3 Emacs/20.7 (i386-debian-linux-gnu) MULE/4.1 (AOI) MIME-Version: 1.0 (generated by SEMI 1.14.3 - "Ushinoya") Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Hi, At Sat, 15 Dec 2001 19:47:46 -0500 (EST), Suresh Gopalakrishnan wrote: > I tried this small piece of code from an old post in the archive: > > #include > #include > #include > #include > #include > #include > > #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; > } > > Output is: > > write returns -1 > Filesize limit exceeded (core dumped) > > $ ls -l /tmp/blah > ---------- 1 gsuresh users 4294967274 Dec 15 19:15 /tmp/blah > > The kernel is 2.4.16 and /tmp is ext2. (It runs fine on 2.4.2). > > Any idea why this happens and how to fix this? Hmm, kernel 2.4.17-rc1 also has this problem. The reason of this problem is that written is defined as unsigned long currently, so if generic_file_direct_IO returns -EINVAL, then written is translated as (unsigned long)(-EINVAL) = (0x100000000-EINVAL). Thus the file size changed such a big value! This patch fixes it. --- linux-2.4.17-rc1.vanilla/mm/filemap.c Sun Dec 16 14:57:42 2001 +++ linux-2.4.17-rc1/mm/filemap.c Sun Dec 16 15:02:10 2001 @@ -2854,7 +2854,7 @@ unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; loff_t pos; struct page *page, *cached_page; - unsigned long written; + ssize_t written; long status = 0; int err; unsigned bytes; This problem breaks file inode size with direct IO... we lost the correct file inode size forever. It's serious. Linus and Marcelo, please consider to apply this patch? However, your program does not work yet. Try my test program. It works well because valloc()/memalign() allocates aligned page boundary. But, my interest is that why we cannot access with stack memory or malloc()-ed memory. I heard Suresh's program works fine on 2.4.2, but it does not work on 2.4.17-rc1. Should we modify the kernel to work well with user stack/heap memory when we use direct IO for the file ? Or, this behavior is absolutely correct ? #include #include #include #include #include #include #define O_DIRECT 040000 /* direct disk access hint */ int main() { char *buf; int fd; buf = valloc(16384); fd = open("/tmp/blah", O_CREAT | O_RDWR | O_DIRECT, 0755 ); printf("write returns %i\n", write(fd, buf, 4096)); return 0; } -- gotom - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/