]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Write with buffer>2GB returns broken errno (2)
authorRusty Russell <rusty@rustcorp.com.au>
Sun, 9 Feb 2003 11:01:17 +0000 (03:01 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 9 Feb 2003 11:01:17 +0000 (03:01 -0800)
[ Acked by AKPM --RR ]
From:  Kazuto MIYOSHI <miyoshi@hpc.bs1.fc.nec.co.jp>

  On 64-bit platforms, issuing write(2) with buffer larger than
  2GB will return -1 and broken errno (such as 2147483640)
  Requested data itself is written correctly.

  That is because generic_file_write() and other relating functions
  store 'ssize_t written' into 'int err'. Written byte is trimmed to
  int and then sign-extended to a negative ssize_t value, which
  wrongly indicates an error.

  (On 64bit platform, current glibc defines SSIZE_MAX as 'LONG_MAX')

mm/filemap.c

index a9659f20f74ad0d2d5db21e21e98798b6a8920a7..53d14110396592882f42ea522776a120ab8ffed6 100644 (file)
@@ -1557,7 +1557,7 @@ generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
        struct page     *page;
        struct page     *cached_page = NULL;
        ssize_t         written;
-       int             err;
+       ssize_t         err;
        size_t          bytes;
        struct pagevec  lru_pvec;
        const struct iovec *cur_iov = iov; /* current iovec */
@@ -1817,7 +1817,7 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const char *buf,
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
-       int err;
+       ssize_t err;
        struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
 
        BUG_ON(iocb->ki_pos != pos);
@@ -1836,7 +1836,7 @@ ssize_t generic_file_write(struct file *file, const char *buf,
                           size_t count, loff_t *ppos)
 {
        struct inode    *inode = file->f_dentry->d_inode->i_mapping->host;
-       int             err;
+       ssize_t         err;
        struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
 
        down(&inode->i_sem);