]> git.hungrycats.org Git - linux/commitdiff
[PATCH] tmpfs 1/6 use generic_write_checks
authorAndrew Morton <akpm@digeo.com>
Thu, 3 Apr 2003 00:26:58 +0000 (16:26 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Thu, 3 Apr 2003 00:26:58 +0000 (16:26 -0800)
From: Hugh Dickins <hugh@veritas.com>

Remove the duplicated checks in shmem_file-write(), use
generic_write_checks() instead.

mm/shmem.c

index db89937437cf97be367de76f91513ac0b9eaed6a..692a732f334526c3adc62598d0ba3a3b3836c9b0 100644 (file)
@@ -1126,10 +1126,8 @@ static ssize_t
 shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
        struct inode    *inode = file->f_dentry->d_inode;
-       unsigned long   limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
        loff_t          pos;
        unsigned long   written;
-       long            status;
        int             err;
        loff_t          maxpos;
 
@@ -1142,88 +1140,25 @@ shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
        down(&inode->i_sem);
 
        pos = *ppos;
-       err = -EINVAL;
-       if (pos < 0)
-               goto out_nc;
-
-       err = file->f_error;
-       if (err) {
-               file->f_error = 0;
-               goto out_nc;
-       }
-
        written = 0;
 
-       if (file->f_flags & O_APPEND)
-               pos = inode->i_size;
+       err = generic_write_checks(inode, file, &pos, &count, 0);
+       if (err || !count)
+               goto out;
 
        maxpos = inode->i_size;
-       if (pos + count > inode->i_size) {
+       if (maxpos < pos + count) {
                maxpos = pos + count;
-               if (maxpos > SHMEM_MAX_BYTES)
-                       maxpos = SHMEM_MAX_BYTES;
                if (!vm_enough_memory(VM_ACCT(maxpos) - VM_ACCT(inode->i_size))) {
                        err = -ENOMEM;
-                       goto out_nc;
-               }
-       }
-
-       /*
-        * Check whether we've reached the file size limit.
-        */
-       err = -EFBIG;
-       if (limit != RLIM_INFINITY) {
-               if (pos >= limit) {
-                       send_sig(SIGXFSZ, current, 0);
                        goto out;
                }
-               if (pos > 0xFFFFFFFFULL || count > limit - (u32)pos) {
-                       /* send_sig(SIGXFSZ, current, 0); */
-                       count = limit - (u32)pos;
-               }
        }
 
-       /*
-        *      LFS rule
-        */
-       if (pos + count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) {
-               if (pos >= MAX_NON_LFS) {
-                       send_sig(SIGXFSZ, current, 0);
-                       goto out;
-               }
-               if (count > MAX_NON_LFS - (u32)pos) {
-                       /* send_sig(SIGXFSZ, current, 0); */
-                       count = MAX_NON_LFS - (u32)pos;
-               }
-       }
-
-       /*
-        *      Are we about to exceed the fs block limit ?
-        *
-        *      If we have written data it becomes a short write
-        *      If we have exceeded without writing data we send
-        *      a signal and give them an EFBIG.
-        *
-        *      Linus frestrict idea will clean these up nicely..
-        */
-       if (pos >= SHMEM_MAX_BYTES) {
-               if (count || pos > SHMEM_MAX_BYTES) {
-                       send_sig(SIGXFSZ, current, 0);
-                       err = -EFBIG;
-                       goto out;
-               }
-               /* zero-length writes at ->s_maxbytes are OK */
-       }
-       if (pos + count > SHMEM_MAX_BYTES)
-               count = SHMEM_MAX_BYTES - pos;
-
-       status  = 0;
-       if (count) {
-               remove_suid(file->f_dentry);
-               inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-       }
+       remove_suid(file->f_dentry);
+       inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 
-       while (count) {
+       do {
                struct page *page = NULL;
                unsigned long bytes, index, offset;
                char *kaddr;
@@ -1241,8 +1176,8 @@ shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                 * But it still may be a good idea to prefault below.
                 */
 
-               status = shmem_getpage(inode, index, &page, SGP_WRITE);
-               if (status)
+               err = shmem_getpage(inode, index, &page, SGP_WRITE);
+               if (err)
                        break;
 
                left = bytes;
@@ -1263,7 +1198,7 @@ shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                flush_dcache_page(page);
                if (left) {
                        page_cache_release(page);
-                       status = -EFAULT;
+                       err = -EFAULT;
                        break;
                }
 
@@ -1271,7 +1206,8 @@ shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                page_cache_release(page);
 
                /*
-                * Balance dirty pages??
+                * Our dirty pages are not counted in nr_dirty,
+                * and we do not attempt to balance dirty pages.
                 */
 
                written += bytes;
@@ -1280,15 +1216,16 @@ shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                buf += bytes;
                if (pos > inode->i_size)
                        inode->i_size = pos;
-       }
+       } while (count);
 
        *ppos = pos;
-       err = written ? written : status;
-out:
+       if (written)
+               err = written;
+
        /* Short writes give back address space */
        if (inode->i_size != maxpos)
                vm_unacct_memory(VM_ACCT(maxpos) - VM_ACCT(inode->i_size));
-out_nc:
+out:
        up(&inode->i_sem);
        return err;
 }