]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.128 2.1.128
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:13 +0000 (15:17 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:13 +0000 (15:17 -0500)
39 files changed:
arch/alpha/kernel/osf_sys.c
drivers/block/ll_rw_blk.c
fs/exec.c
fs/isofs/dir.c
fs/minix/fsync.c
fs/minix/inode.c
fs/minix/truncate.c
fs/msdos/namei.c
fs/nfs/read.c
fs/nfs/write.c
fs/qnx4/file.c
fs/qnx4/symlinks.c
fs/readdir.c
fs/smbfs/file.c
fs/ufs/dir.c
fs/vfat/namei.c
include/linux/nfs_fs.h
include/linux/sched.h
init/main.c
kernel/acct.c
kernel/capability.c
kernel/exec_domain.c
kernel/exit.c
kernel/fork.c
kernel/info.c
kernel/itimer.c
kernel/kmod.c
kernel/ksyms.c
kernel/module.c
kernel/panic.c
kernel/printk.c
kernel/resource.c
kernel/sched.c
kernel/signal.c
kernel/softirq.c
kernel/sys.c
kernel/sysctl.c
kernel/time.c
mm/filemap.c

index 00e02d8a1633b4ed13145c7e9824a6e5458c75c0..4c540f6968a8605c83bfa1f6e326dfb02ac18e26 100644 (file)
@@ -1136,7 +1136,7 @@ osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
        unsigned long timeout;
        int ret;
 
-       timeout = ~0UL;
+       timeout = MAX_SCHEDULE_TIMEOUT;
        if (tvp) {
                time_t sec, usec;
 
@@ -1147,8 +1147,6 @@ osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
 
                timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
                timeout += sec * HZ;
-               if (timeout)
-                       timeout += jiffies + 1;
        }
 
        ret = -ENOMEM;
@@ -1168,7 +1166,7 @@ osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
        zero_fd_set(n, fds->res_out);
        zero_fd_set(n, fds->res_ex);
 
-       ret = do_select(n, fds, timeout);
+       ret = do_select(n, fds, &timeout);
 
        /* OSF does not copy back the remaining time.  */
 
index b86019ecf8de9e2530d3a2da7a33f4cda39558d5..3d26017566d4e30dc5fbcfdfee275ce302010c2e 100644 (file)
@@ -331,10 +331,16 @@ void add_request(struct blk_dev_struct * dev, struct request * req)
                goto out;
        }
        for ( ; tmp->next ; tmp = tmp->next) {
-               if ((IN_ORDER(tmp,req) ||
-                   !IN_ORDER(tmp,tmp->next)) &&
-                   IN_ORDER(req,tmp->next))
-                       break;
+               const int after_current = IN_ORDER(tmp,req);
+               const int before_next = IN_ORDER(req,tmp->next);
+
+               if (!IN_ORDER(tmp,tmp->next)) {
+                       if (after_current || before_next)
+                               break;
+               } else {
+                       if (after_current && before_next)
+                               break;
+               }
        }
        req->next = tmp->next;
        tmp->next = req;
index d0d2da81c26dc94d86eccc5634f3c2a39d53da0a..2a35ed7dad25514694aea375bf51ecf588c353ac 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -445,9 +445,9 @@ fail_nomem:
 
 /*
  * This function makes sure the current process has its own signal table,
- * so that flush_old_signals can later reset the signals without disturbing
- * other processes.  (Other processes might share the signal table via
- * the CLONE_SIGHAND option to clone().)
+ * so that flush_signal_handlers can later reset the handlers without
+ * disturbing other processes.  (Other processes might share the signal
+ * table via the CLONE_SIGHAND option to clone().)
  */
  
 static inline int make_private_signals(void)
@@ -485,13 +485,6 @@ static inline void release_old_signals(struct signal_struct * oldsig)
  * These functions flushes out all traces of the currently running executable
  * so that a new one can be started
  */
-static inline void flush_old_signals(struct task_struct *t)
-{
-#if 0
-       flush_signals(t);
-#endif
-       flush_signal_handlers(t);
-}
 
 static inline void flush_old_files(struct files_struct * files)
 {
@@ -554,7 +547,7 @@ int flush_old_exec(struct linux_binprm * bprm)
            permission(bprm->dentry->d_inode,MAY_READ))
                current->dumpable = 0;
 
-       flush_old_signals(current);
+       flush_signal_handlers(current);
        flush_old_files(current->files);
 
        return 0;
index f73ec5271fd2c15c9ae9dd75987caf4891f345c8..a57f9680c63752daa7ccd7fac7c7b2a6d4b0d2b2 100644 (file)
@@ -59,7 +59,7 @@ struct inode_operations isofs_dir_inode_operations =
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
-       isofs_bmap,             /* bmap */
+       NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL                    /* permission */
 };
index 44606d2600ae9f01688c9ad2c830a8f4923b70f9..ef3d15db97326bf91f0ec6a48243c43ce8608127 100644 (file)
@@ -144,7 +144,7 @@ static int V1_sync_dindirect(struct inode *inode, unsigned short *diblock,
        return err;
 }
 
-int V1_minix_sync_file(struct inode * inode, struct file * file)
+static int V1_minix_sync_file(struct inode * inode, struct file * file)
 {
        int wait, err = 0;
        
@@ -305,7 +305,7 @@ static int V2_sync_tindirect(struct inode *inode, unsigned long *tiblock,
        return err;
 }
 
-int V2_minix_sync_file(struct inode * inode, struct file * file)
+static int V2_minix_sync_file(struct inode * inode, struct file * file)
 {
        int wait, err = 0;
        
index 46ae5c11c024843ed48742311fd6b0a0600df704..98336c98b09a99295b49fc415371a98993b8ba76 100644 (file)
@@ -40,7 +40,7 @@ static void minix_commit_super (struct super_block * sb,
        sb->s_dirt = 0;
 }
 
-void minix_write_super (struct super_block * sb)
+static void minix_write_super (struct super_block * sb)
 {
        struct minix_super_block * ms;
 
@@ -55,7 +55,7 @@ void minix_write_super (struct super_block * sb)
 }
 
 
-void minix_put_super(struct super_block *sb)
+static void minix_put_super(struct super_block *sb)
 {
        int i;
 
@@ -86,7 +86,7 @@ static struct super_operations minix_sops = {
        minix_remount
 };
 
-int minix_remount (struct super_block * sb, int * flags, char * data)
+static int minix_remount (struct super_block * sb, int * flags, char * data)
 {
        struct minix_super_block * ms;
 
@@ -162,7 +162,7 @@ static const char * minix_checkroot(struct super_block *s, struct inode *dir)
        return errmsg;
 }
 
-struct super_block *minix_read_super(struct super_block *s, void *data,
+static struct super_block *minix_read_super(struct super_block *s, void *data,
                                     int silent)
 {
        struct buffer_head *bh;
@@ -326,7 +326,7 @@ out_bad_sb:
        return NULL;
 }
 
-int minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
        struct statfs tmp;
 
@@ -830,7 +830,7 @@ static void V2_minix_read_inode(struct inode * inode)
 /*
  * The global function to read an inode.
  */
-void minix_read_inode(struct inode * inode)
+static void minix_read_inode(struct inode * inode)
 {
        if (INODE_VERSION(inode) == MINIX_V1)
                V1_minix_read_inode(inode);
@@ -916,7 +916,7 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
        return bh;
 }
 
-struct buffer_head *minix_update_inode(struct inode *inode)
+static struct buffer_head *minix_update_inode(struct inode *inode)
 {
        if (INODE_VERSION(inode) == MINIX_V1)
                return V1_minix_update_inode(inode);
@@ -924,7 +924,7 @@ struct buffer_head *minix_update_inode(struct inode *inode)
                return V2_minix_update_inode(inode);
 }
 
-void minix_write_inode(struct inode * inode)
+static void minix_write_inode(struct inode * inode)
 {
        struct buffer_head *bh;
 
index 0f0afa6044294e8978edea40ffc2ea6bc1f85648..a94806fdf2f597f3cd277757fdddf5bdf5145c6f 100644 (file)
@@ -176,7 +176,7 @@ repeat:
        return retry;
 }
 
-void V1_minix_truncate(struct inode * inode)
+static void V1_minix_truncate(struct inode * inode)
 {
        int retry;
 
index bd183c9e8501bdde2a210705559d607d9c1ec1d4..0e03e79ee382c311bf82f7c583909e07e2d3bc49 100644 (file)
@@ -993,7 +993,7 @@ struct inode_operations msdos_dir_inode_operations = {
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
-       fat_bmap,               /* bmap */
+       NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* permission */
        NULL,                   /* smap */
index 6f1fdd7ffae361166d2d96f7875198242d45b7f5..58b8942327fb7891ed0dfa77f66bc52490864c90 100644 (file)
@@ -230,6 +230,17 @@ nfs_readpage(struct file *file, struct page *page)
        dprintk("NFS: nfs_readpage (%p %ld@%ld)\n",
                page, PAGE_SIZE, page->offset);
        set_bit(PG_locked, &page->flags);
+
+       /*
+        * Try to flush any pending writes to the file..
+        *
+        * NOTE! Because we own the page lock, there cannot
+        * be any new pending writes generated at this point.
+        */
+       error = nfs_flush_pages(inode, 0, 0, 0);
+       if (error)
+               return error;
+
        atomic_inc(&page->count);
        if (!IS_SWAPFILE(inode) && !PageError(page) &&
            NFS_SERVER(inode)->rsize >= PAGE_SIZE)
index f1e803bd29e3874edbc309861507ce3c3ae0a896..d1ce5af5eadc562b53881d52d7e69163e8c6bab8 100644 (file)
@@ -59,7 +59,7 @@
 #define NFS_PARANOIA 1
 #define NFSDBG_FACILITY                NFSDBG_PAGECACHE
 
-static void                    nfs_wback_lock(struct rpc_task *task);
+static void                    nfs_wback_begin(struct rpc_task *task);
 static void                    nfs_wback_result(struct rpc_task *task);
 static void                    nfs_cancel_request(struct nfs_wreq *req);
 
@@ -73,55 +73,13 @@ static void                 nfs_cancel_request(struct nfs_wreq *req);
  * Limit number of delayed writes
  */
 static int                     nr_write_requests = 0;
-static int                     nr_failed_requests = 0;
 static struct rpc_wait_queue   write_queue = RPC_INIT_WAITQ("write_chain");
-struct nfs_wreq *              nfs_failed_requests = NULL;
 
 /* Hack for future NFS swap support */
 #ifndef IS_SWAPFILE
 # define IS_SWAPFILE(inode)    (0)
 #endif
 
-/*
- * Unlock a page after writing it
- */
-static inline void
-nfs_unlock_page(struct page *page)
-{
-       dprintk("NFS:      unlock %ld\n", page->offset);
-       clear_bit(PG_locked, &page->flags);
-       wake_up(&page->wait);
-
-#ifdef CONFIG_NFS_SWAP
-       /* async swap-out support */
-       if (test_and_clear_bit(PG_decr_after, &page->flags))
-               atomic_dec(&page->count);
-       if (test_and_clear_bit(PG_swap_unlock_after, &page->flags)) {
-               /*
-                * We're doing a swap, so check that this page is
-                * swap-cached and do the necessary cleanup. 
-                */
-               swap_after_unlock_page(page->offset);
-       }
-#endif
-}
-
-/*
- * Transfer a page lock to a write request waiting for it.
- */
-static inline void
-transfer_page_lock(struct nfs_wreq *req)
-{
-       dprintk("NFS:      transfer_page_lock\n");
-
-       req->wb_flags &= ~NFS_WRITE_WANTLOCK;
-       req->wb_flags |= NFS_WRITE_LOCKED;
-       rpc_wake_up_task(&req->wb_task);
-
-       dprintk("NFS:      wake up task %d (flags %x)\n",
-                       req->wb_task.tk_pid, req->wb_flags);
-}
-
 /*
  * Write a page synchronously.
  * Offset is the data offset within the page.
@@ -195,7 +153,6 @@ io_error:
                                inode->i_ino, fattr.fileid);
        }
 
-       nfs_unlock_page(page);
        return written? written : result;
 }
 
@@ -220,11 +177,13 @@ remove_write_request(struct nfs_wreq **q, struct nfs_wreq *wreq)
 }
 
 /*
- * Find a write request for a given page
+ * Find a non-busy write request for a given page to
+ * try to combine with.
  */
 static inline struct nfs_wreq *
 find_write_request(struct inode *inode, struct page *page)
 {
+       pid_t pid = current->pid;
        struct nfs_wreq *head, *req;
 
        dprintk("NFS:      find_write_request(%x/%ld, %p)\n",
@@ -232,8 +191,21 @@ find_write_request(struct inode *inode, struct page *page)
        if (!(req = head = NFS_WRITEBACK(inode)))
                return NULL;
        do {
-               if (req->wb_page == page)
+               /*
+                * We can't combine with canceled requests or
+                * requests that have already been started..
+                */
+               if (req->wb_flags & (NFS_WRITE_CANCELLED | NFS_WRITE_INPROGRESS))
+                       continue;
+
+               if (req->wb_page == page && req->wb_pid == pid)
                        return req;
+
+               /*
+                * Ehh, don't keep too many tasks queued..
+                */
+               rpc_wake_up_task(&req->wb_task);
+
        } while ((req = WB_NEXT(req)) != head);
        return NULL;
 }
@@ -259,65 +231,14 @@ nfs_find_dentry_request(struct inode *inode, struct dentry *dentry)
        return found;
 }
 
-/*
- * Find a failed write request by pid
- */
-static struct nfs_wreq *
-find_failed_request(struct inode *inode, pid_t pid)
-{
-       struct nfs_wreq *head, *req;
-
-       req = head = nfs_failed_requests;
-       while (req != NULL) {
-               if (req->wb_inode == inode && (pid == 0 || req->wb_pid == pid))
-                       return req;
-               if ((req = WB_NEXT(req)) == head)
-                       break;
-       }
-       return NULL;
-}
-
-/*
- * Add a request to the failed list.
- */
-static void
-append_failed_request(struct nfs_wreq * req)
-{
-       static int old_max = 16;
-
-       append_write_request(&nfs_failed_requests, req);
-       nr_failed_requests++;
-       if (nr_failed_requests >= old_max) {
-               printk("NFS: %d failed requests\n", nr_failed_requests);
-               old_max = old_max << 1;
-       }
-}
-
-/*
- * Remove a request from the failed list and free it.
- */
-static void
-remove_failed_request(struct nfs_wreq * req)
-{
-       remove_write_request(&nfs_failed_requests, req);
-       kfree(req);
-       nr_failed_requests--;
-}
-
 /*
  * Find and release all failed requests for this inode.
  */
 int
 nfs_check_failed_request(struct inode * inode)
 {
-       struct nfs_wreq * req;
-       int found = 0;
-
-       while ((req = find_failed_request(inode, 0)) != NULL) {
-               remove_failed_request(req);
-               found++;
-       }
-       return found;
+       /* FIXME! */
+       return 0;
 }
 
 /*
@@ -334,6 +255,10 @@ update_write_request(struct nfs_wreq *req, unsigned int first,
 
        dprintk("nfs:      trying to update write request %p\n", req);
 
+       /* not contiguous? */
+       if (rqlast < first || last < rqfirst)
+               return 0;
+
        /* Check the credentials associated with this write request.
         * If the buffer is owned by the same user, we can happily
         * add our data without risking server permission problems.
@@ -349,12 +274,25 @@ update_write_request(struct nfs_wreq *req, unsigned int first,
                rqfirst = first;
        if (rqlast < last)
                rqlast = last;
+
        req->wb_offset = rqfirst;
        req->wb_bytes  = rqlast - rqfirst;
+       req->wb_count++;
 
        return 1;
 }
 
+static inline void
+free_write_request(struct nfs_wreq * req)
+{
+       if (!--req->wb_count) {
+               struct inode *inode = req->wb_inode;
+               remove_write_request(&NFS_WRITEBACK(inode), req);
+               kfree(req);
+               nr_write_requests--;
+       }
+}
+
 /*
  * Create and initialize a writeback request
  */
@@ -371,8 +309,7 @@ create_write_request(struct dentry *dentry, struct inode *inode,
                page->offset + offset, bytes);
 
        /* FIXME: Enforce hard limit on number of concurrent writes? */
-
-       wreq = (struct nfs_wreq *) kmalloc(sizeof(*wreq), GFP_USER);
+       wreq = (struct nfs_wreq *) kmalloc(sizeof(*wreq), GFP_KERNEL);
        if (!wreq)
                goto out_fail;
        memset(wreq, 0, sizeof(*wreq));
@@ -380,7 +317,7 @@ create_write_request(struct dentry *dentry, struct inode *inode,
        task = &wreq->wb_task;
        rpc_init_task(task, clnt, nfs_wback_result, RPC_TASK_NFSWRITE);
        task->tk_calldata = wreq;
-       task->tk_action = nfs_wback_lock;
+       task->tk_action = nfs_wback_begin;
 
        rpcauth_lookupcred(task);       /* Obtain user creds */
        if (task->tk_status < 0)
@@ -393,6 +330,7 @@ create_write_request(struct dentry *dentry, struct inode *inode,
        wreq->wb_page   = page;
        wreq->wb_offset = offset;
        wreq->wb_bytes  = bytes;
+       wreq->wb_count  = 2;            /* One for the IO, one for us */
 
        atomic_inc(&page->count);
 
@@ -414,8 +352,7 @@ out_fail:
  * Schedule a writeback RPC call.
  * If the server is congested, don't add to our backlog of queued
  * requests but call it synchronously.
- * The function returns false if the page has been unlocked as the
- * consequence of a synchronous write call.
+ * The function returns whether we should wait for the thing or not.
  *
  * FIXME: Here we could walk the inode's lock list to see whether the
  * page we're currently writing to has been write-locked by the caller.
@@ -438,7 +375,6 @@ schedule_write_request(struct nfs_wreq *req, int sync)
                dprintk("NFS: %4d schedule_write_request (sync)\n",
                                        task->tk_pid);
                /* Page is already locked */
-               req->wb_flags |= NFS_WRITE_LOCKED;
                rpc_clnt_sigmask(clnt, &oldmask);
                rpc_execute(task);
                rpc_clnt_sigunmask(clnt, &oldmask);
@@ -450,39 +386,38 @@ schedule_write_request(struct nfs_wreq *req, int sync)
                rpc_sleep_on(&write_queue, task, NULL, NULL);
        }
 
-       return sync == 0;
+       return sync;
 }
 
 /*
- * Wait for request to complete
- * This is almost a copy of __wait_on_page
+ * Wait for request to complete.
  */
-static inline int
+static int
 wait_on_write_request(struct nfs_wreq *req)
 {
+       struct rpc_clnt         *clnt = NFS_CLIENT(req->wb_inode);
        struct wait_queue       wait = { current, NULL };
-       struct page             *page = req->wb_page;
-       int retval;
        sigset_t                oldmask;
-       struct rpc_clnt         *clnt = NFS_CLIENT(req->wb_inode);
+       int retval;
+
+       /* Make sure it's started.. */
+       if (!WB_INPROGRESS(req))
+               rpc_wake_up_task(&req->wb_task);
 
        rpc_clnt_sigmask(clnt, &oldmask);
-       add_wait_queue(&page->wait, &wait);
-       atomic_inc(&page->count);
+       add_wait_queue(&req->wb_wait, &wait);
        for (;;) {
                current->state = TASK_INTERRUPTIBLE;
                retval = 0;
-               if (!PageLocked(page))
+               if (req->wb_flags & NFS_WRITE_COMPLETE)
                        break;
                retval = -ERESTARTSYS;
                if (signalled())
                        break;
                schedule();
        }
-       remove_wait_queue(&page->wait, &wait);
+       remove_wait_queue(&req->wb_wait, &wait);
        current->state = TASK_RUNNING;
-       /* N.B. page may have been unused, so we must use free_page() */
-       free_page(page_address(page));
        rpc_clnt_sigunmask(clnt, &oldmask);
        return retval;
 }
@@ -510,7 +445,8 @@ nfs_updatepage(struct file *file, struct page *page, unsigned long offset, unsig
        struct dentry   *dentry = file->f_dentry;
        struct inode    *inode = dentry->d_inode;
        struct nfs_wreq *req;
-       int             status = 0, page_locked = 1;
+       int             synchronous = sync;
+       int             retval;
 
        dprintk("NFS:      nfs_updatepage(%s/%s %d@%ld, sync=%d)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -526,143 +462,54 @@ nfs_updatepage(struct file *file, struct page *page, unsigned long offset, unsig
         * After returning, generic_file_write will wait on the
         * page and retry the update.
         */
-       if ((req = find_write_request(inode, page)) != NULL) {
-               if (update_write_request(req, offset, count))
-                       goto updated;
+       req = find_write_request(inode, page);
+       if (req && update_write_request(req, offset, count))
+               goto updated;
 
-               dprintk("NFS:      wake up conflicting write request.\n");
-               transfer_page_lock(req);
-               return 0;
-       }
-
-       /* If wsize is smaller than page size, update and write
+       /*
+        * If wsize is smaller than page size, update and write
         * page synchronously.
         */
        if (NFS_SERVER(inode)->wsize < PAGE_SIZE)
                return nfs_writepage_sync(dentry, inode, page, offset, count);
 
        /* Create the write request. */
-       status = -ENOBUFS;
        req = create_write_request(dentry, inode, page, offset, count);
        if (!req)
-               goto done;
+               return -ENOBUFS;
+
+       /*
+        * Ok, there's another user of this page with the new request..
+        * Increment the usage count, and schedule the request (the
+        * end of the request will drop the usage count..)
+        */
+       atomic_inc(&page->count);
 
        /* Schedule request */
-       page_locked = schedule_write_request(req, sync);
+       synchronous = schedule_write_request(req, sync);
 
 updated:
        if (req->wb_bytes == PAGE_SIZE)
                set_bit(PG_uptodate, &page->flags);
 
-       /*
-        * If we wrote up to the end of the chunk, transmit request now.
-        * We should be a bit more intelligent about detecting whether a
-        * process accesses the file sequentially or not.
-        */
-       if (page_locked && (offset + count >= PAGE_SIZE || sync))
-               req->wb_flags |= NFS_WRITE_WANTLOCK;
-
-       /* If the page was written synchronously, return any error that
-        * may have happened; otherwise return the write count. */
-       if (page_locked || (status = nfs_write_error(inode)) >= 0)
-               status = count;
-
-done:
-       /* Unlock page and wake up anyone sleeping on it */
-       if (page_locked) {
-               if (req && WB_WANTLOCK(req)) {
-                       transfer_page_lock(req);
-                       /* rpc_execute(&req->wb_task); */
-                       if (sync) {
-                               /* if signalled, ensure request is cancelled */
-                               if ((count = wait_on_write_request(req)) != 0) {
-                                       nfs_cancel_request(req);
-                                       status = count;
-                               }
-                               if ((count = nfs_write_error(inode)) < 0)
-                                       status = count;
-                       }
+       retval = count;
+       if (synchronous) {
+               int status = wait_on_write_request(req);
+               if (status) {
+                       nfs_cancel_request(req);
+                       retval = status;
                } else {
-                       if (status < 0) {
-printk("NFS: %s/%s write failed, clearing bit\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-                               clear_bit(PG_uptodate, &page->flags);
-                       }
-                       nfs_unlock_page(page);
+                       status = req->wb_status;
+                       if (status < 0)
+                               retval = status;
                }
-       }
-
-       dprintk("NFS:      nfs_updatepage returns %d (isize %ld)\n",
-                                               status, inode->i_size);
-       return status;
-}
-
-/*
- * Flush out a dirty page.
- */ 
-static void
-nfs_flush_request(struct nfs_wreq *req)
-{
-       struct page     *page = req->wb_page;
-
-#ifdef NFS_DEBUG_VERBOSE
-if (req->wb_inode != page->inode)
-printk("NFS: inode %ld no longer has page %p\n", req->wb_inode->i_ino, page);
-#endif
-       dprintk("NFS:      nfs_flush_request(%s/%s, @%ld)\n",
-               req->wb_dentry->d_parent->d_name.name,
-               req->wb_dentry->d_name.name, page->offset);
-
-       req->wb_flags |= NFS_WRITE_WANTLOCK;
-       if (!test_and_set_bit(PG_locked, &page->flags)) {
-               transfer_page_lock(req);
-       } else {
-               printk(KERN_WARNING "NFS oops in %s: can't lock page!\n",
-                                       __FUNCTION__);
-               rpc_wake_up_task(&req->wb_task);
-       }
-}
-
-/*
- * Flush writeback requests. See nfs_flush_dirty_pages for details.
- */
-static struct nfs_wreq *
-nfs_flush_pages(struct inode *inode, pid_t pid, off_t offset, off_t len,
-                                               int invalidate)
-{
-       struct nfs_wreq *head, *req, *last = NULL;
-       off_t           rqoffset, rqend, end;
-
-       end = len? offset + len : 0x7fffffffUL;
-
-       req = head = NFS_WRITEBACK(inode);
-       while (req != NULL) {
-               dprintk("NFS: %4d nfs_flush inspect %s/%s @%ld fl %x\n",
-                       req->wb_task.tk_pid,
-                       req->wb_dentry->d_parent->d_name.name,
-                       req->wb_dentry->d_name.name,
-                       req->wb_page->offset, req->wb_flags);
 
-               rqoffset = req->wb_page->offset + req->wb_offset;
-               rqend    = rqoffset + req->wb_bytes;
-               if (rqoffset < end && offset < rqend &&
-                   (pid == 0 || req->wb_pid == pid)) {
-                       if (!WB_INPROGRESS(req) && !WB_HAVELOCK(req)) {
-#ifdef NFS_DEBUG_VERBOSE
-printk("nfs_flush: flushing inode=%ld, %d @ %lu\n",
-req->wb_inode->i_ino, req->wb_bytes, rqoffset);
-#endif
-                               nfs_flush_request(req);
-                       }
-                       last = req;
-               }
-               if (invalidate)
-                       req->wb_flags |= NFS_WRITE_INVALIDATE;
-               if ((req = WB_NEXT(req)) == head)
-                       break;
+               if (retval < 0)
+                       clear_bit(PG_uptodate, &page->flags);
        }
 
-       return last;
+       free_write_request(req);
+       return retval;
 }
 
 /*
@@ -699,53 +546,67 @@ nfs_cancel_dirty(struct inode *inode, pid_t pid)
 }
 
 /*
- * Flush out all dirty pages belonging to a certain user process and
- * maybe wait for the RPC calls to complete.
+ * Try to flush any dirty pages, returning a success marker..
  *
- * Another purpose of this function is sync()ing a file range before a
- * write lock is released. This is what offset and length are for, even if
- * this isn't used by the nlm module yet.
+ * Unlike "nfs_flush_dirty_pages()" this does not invalidate
+ * the writes if it is interrupted. The caller will instead
+ * look at the error code and gracefully fail to do what it
+ * wanted to do. 
  */
 int
-nfs_flush_dirty_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
+nfs_flush_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
 {
-       struct nfs_wreq *last = NULL;
-       int result = 0;
+       int retval;
 
-       dprintk("NFS:      flush_dirty_pages(%x/%ld for pid %d %ld/%ld)\n",
-               inode->i_dev, inode->i_ino, current->pid, offset, len);
+       do {
+               struct nfs_wreq *req = NFS_WRITEBACK(inode);
+               struct nfs_wreq *head = req;
 
-       for (;;) {
-               /* Flush all pending writes for the pid and file region */
-               last = nfs_flush_pages(inode, pid, offset, len, 0);
-               if (last == NULL)
-                       break;
-               result = wait_on_write_request(last);
-               if (result) {
-                       nfs_cancel_dirty(inode,pid);
-                       break;
+               if (!req)
+                       return 0;
+
+               /*
+                * Iterate over all outstanding write requests,
+                * looking for any that are ours..
+                */
+               for (;;) {
+                       if (!(req->wb_flags & NFS_WRITE_COMPLETE)) {
+                               if (!pid || req->wb_pid == pid)
+                                       break;
+                       }
+                       req = WB_NEXT(req);
+                       if (req == head)
+                               return 0;
                }
-       }
 
-       return result;
-}
+               req->wb_count++;
+               retval = wait_on_write_request(req);
+               free_write_request(req);
+       } while (!retval);
+       return retval;
+}      
 
 /*
- * Flush out any pending write requests and flag that they be discarded
- * after the write is complete.
+ * Flush out all dirty pages belonging to a certain user process and
+ * maybe wait for the RPC calls to complete.
  *
- * This function is called from nfs_refresh_inode just before it calls
- * invalidate_inode_pages. After nfs_flush_pages returns, we can be sure
- * that all dirty pages are locked, so that invalidate_inode_pages does
- * not throw away any dirty pages.
+ * Another purpose of this function is sync()ing a file range before a
+ * write lock is released. This is what offset and length are for, even if
+ * this isn't used by the nlm module yet.
  */
+int
+nfs_flush_dirty_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
+{
+       int retval = nfs_flush_pages(inode, pid, offset, len);
+       if (retval)
+               nfs_cancel_dirty(inode,pid);
+       return retval;
+}
+
 void
 nfs_invalidate_pages(struct inode *inode)
 {
-       dprintk("NFS:      nfs_invalidate_pages(%x/%ld)\n",
-                               inode->i_dev, inode->i_ino);
-
-       nfs_flush_pages(inode, 0, 0, 0, 1);
+       nfs_cancel_dirty(inode,0);
 }
 
 /*
@@ -783,21 +644,8 @@ nfs_truncate_dirty_pages(struct inode *inode, unsigned long offset)
 int
 nfs_check_error(struct inode *inode)
 {
-       struct nfs_wreq *req;
-       int             status = 0;
-
-       dprintk("nfs:      checking for write error inode %04x/%ld\n",
-                       inode->i_dev, inode->i_ino);
-
-       req = find_failed_request(inode, current->pid);
-       if (req) {
-               dprintk("nfs: write error %d inode %04x/%ld\n",
-                       req->wb_task.tk_status, inode->i_dev, inode->i_ino);
-
-               status = req->wb_task.tk_status;
-               remove_failed_request(req);
-       }
-       return status;
+       /* FIXME! */
+       return 0;
 }
 
 /*
@@ -807,23 +655,16 @@ nfs_check_error(struct inode *inode)
  *     set up the RPC call info, and pass to the call FSM.
  */
 static void
-nfs_wback_lock(struct rpc_task *task)
+nfs_wback_begin(struct rpc_task *task)
 {
        struct nfs_wreq *req = (struct nfs_wreq *) task->tk_calldata;
        struct page     *page = req->wb_page;
        struct dentry   *dentry = req->wb_dentry;
 
-       dprintk("NFS: %4d nfs_wback_lock (%s/%s, status=%d flags=%x)\n",
+       dprintk("NFS: %4d nfs_wback_begin (%s/%s, status=%d flags=%x)\n",
                task->tk_pid, dentry->d_parent->d_name.name,
                dentry->d_name.name, task->tk_status, req->wb_flags);
 
-       if (!WB_HAVELOCK(req))
-               req->wb_flags |= NFS_WRITE_WANTLOCK;
-
-       if (WB_WANTLOCK(req) && test_and_set_bit(PG_locked, &page->flags))
-               goto out_locked;
-       req->wb_flags &= ~NFS_WRITE_WANTLOCK;
-       req->wb_flags |=  NFS_WRITE_LOCKED;
        task->tk_status = 0;
 
        /* Setup the task struct for a writeback call */
@@ -836,12 +677,6 @@ nfs_wback_lock(struct rpc_task *task)
 
        req->wb_flags |= NFS_WRITE_INPROGRESS;
        return;
-
-out_locked:
-       printk("NFS: page already locked in writeback_lock!\n");
-       task->tk_timeout = 2 * HZ;
-       rpc_sleep_on(&write_queue, task, NULL, NULL);
-       return;
 }
 
 /*
@@ -861,15 +696,10 @@ nfs_wback_result(struct rpc_task *task)
 
        /* Set the WRITE_COMPLETE flag, but leave WRITE_INPROGRESS set */
        req->wb_flags |= NFS_WRITE_COMPLETE;
+       req->wb_status = status;
+
        if (status < 0) {
-               /*
-                * An error occurred. Report the error back to the
-                * application by adding the request to the failed
-                * requests list.
-                */
-               if (find_failed_request(inode, req->wb_pid))
-                       status = 0;
-               clear_bit(PG_uptodate, &page->flags);
+               req->wb_flags |= NFS_WRITE_INVALIDATE;
        } else if (!WB_CANCELLED(req)) {
                struct nfs_fattr *fattr = &req->wb_fattr;
                /* Update attributes as result of writeback. 
@@ -899,31 +729,27 @@ nfs_wback_result(struct rpc_task *task)
                }
        }
 
-       /*
-        * This call might block, so we defer removing the request
-        * from the inode's writeback list.
-        */
        rpc_release_task(task);
 
        if (WB_INVALIDATE(req))
                clear_bit(PG_uptodate, &page->flags);
-       if (WB_HAVELOCK(req))
-               nfs_unlock_page(page);
 
+       __free_page(page);
+
+       wake_up(&req->wb_wait);
+       
        /*
-        * Now it's safe to remove the request from the inode's 
-        * writeback list and wake up any tasks sleeping on it.
-        * If the request failed, add it to the failed list.
+        * FIXME!
+        *
+        * We should not free the request here if it has pending
+        * error status on it. We should just leave it around, to
+        * let the error be collected later. However, the error
+        * collecting routines are too stupid for that right now,
+        * so we just drop the error on the floor at this point
+        * for any async writes.
+        *
+        * This should not be a major headache to fix, but I want
+        * to validate basic operations first.
         */
-       remove_write_request(&NFS_WRITEBACK(inode), req);
-
-       if (status >= 0)
-               kfree(req);
-       else {
-               dprintk("NFS: %4d saving write failure code\n", task->tk_pid);
-               append_failed_request(req);
-       }
-
-       free_page(page_address(page));
-       nr_write_requests--;
+       free_write_request(req);
 }
index f26733d9a9ec0c00e27e15d4fd8d0ba42b65c49c..49998012677bc0a7b8ac0ba68c58b9baadcfd552 100644 (file)
@@ -180,11 +180,7 @@ static struct file_operations qnx4_file_operations =
 struct inode_operations qnx4_file_inode_operations =
 {
        &qnx4_file_operations,  /* default file operations */
-#ifdef CONFIG_QNX4FS_RW
-       qnx4_create,            /* create */
-#else
-       NULL,
-#endif
+       NULL,                   /* create? It's not a directory */
        NULL,                   /* lookup */
        NULL,                   /* link */
        NULL,                   /* unlink */
index f590d04a6d977f065e162217f7c9516a3d7f5db2..2fb7c748e79f652fcddf4fe3367b293cd6c83afd 100644 (file)
@@ -32,11 +32,7 @@ static struct dentry *qnx4_follow_link(struct dentry *, struct dentry *);
 struct inode_operations qnx4_symlink_inode_operations =
 {
        NULL,                   /* no file-operations */
-#ifdef CONFIG_QNX4FS_RW
-       qnx4_create,            /* create */
-#else
-       NULL,
-#endif
+       NULL,                   /* create */
        NULL,                   /* lookup */
        NULL,                   /* link */
        NULL,                   /* unlink */
index f517c9a87b8f588a9c637d2d5361a4bc91be12dd..305b1cc7476296391215f01cc984d5fab0103bbe 100644 (file)
@@ -6,12 +6,9 @@
 
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/file.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
index 3c3e87aa6a016d284430b7fcd894c8aa00633918..a6cf24ce1714cd040a02f66ad81e7cbd661ccba3 100644 (file)
@@ -195,40 +195,15 @@ smb_writepage(struct file *file, struct page *page)
 }
 
 static int
-smb_updatepage(struct file *file, struct page *page, const char *buffer,
-              unsigned long offset, unsigned int count, int sync)
+smb_updatepage(struct file *file, struct page *page, unsigned long offset, unsigned int count, int sync)
 {
        struct dentry *dentry = file->f_dentry;
-       unsigned long page_addr = page_address(page);
-       int result;
 
        pr_debug("SMBFS: smb_updatepage(%s/%s %d@%ld, sync=%d)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
                count, page->offset+offset, sync);
 
-#ifdef SMBFS_PARANOIA
-       if (test_bit(PG_locked, &page->flags))
-               printk("smb_updatepage: page already locked!\n");
-#endif
-       set_bit(PG_locked, &page->flags);
-       atomic_inc(&page->count);
-
-       if (copy_from_user((char *) page_addr + offset, buffer, count))
-               goto bad_fault;
-       result = smb_writepage_sync(dentry, page, offset, count);
-out:
-       free_page(page_addr);
-       return result;
-
-bad_fault:
-#ifdef SMBFS_PARANOIA
-printk("smb_updatepage: fault at addr=%lu, offset=%lu, buffer=%p\n", 
-page_addr, offset, buffer);
-#endif
-       result = -EFAULT;
-       clear_bit(PG_uptodate, &page->flags);
-       smb_unlock_page(page);
-       goto out;
+       return smb_writepage_sync(dentry, page, offset, count);
 }
 
 static ssize_t
index 170ffb10b6be37f05c28370c4c939505a2e31e08..6fc2245120128e85ddc1503b4b253419cacee5b9 100644 (file)
@@ -220,7 +220,7 @@ struct inode_operations ufs_dir_inode_operations = {
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
-       ufs_bmap,               /* bmap */
+       NULL,                   /* bmap */
        NULL,                   /* truncate */
        ufs_permission,         /* permission */
        NULL,                   /* smap */
index fe1565106806f2c88b37f94b5fc2816256be7f61..59622732ca4ae3e5c0c926be981ed53b6f370b33 100644 (file)
@@ -1846,7 +1846,7 @@ struct inode_operations vfat_dir_inode_operations = {
        NULL,                   /* followlink */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
-       fat_bmap,               /* bmap */
+       NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL                    /* permission */
 };
index e8df622ae8f9f70f57a0d356c826cfdb94d0d46d..c6ea474365ebcb283cfae55d011fabaa0e6e3f64 100644 (file)
@@ -101,31 +101,29 @@ struct nfs_wreq {
        struct dentry *         wb_dentry;      /* dentry referenced */
        struct inode *          wb_inode;       /* inode referenced */
        struct page *           wb_page;        /* page to be written */
+       struct wait_queue *     wb_wait;        /* wait for completion */
        unsigned int            wb_offset;      /* offset within page */
        unsigned int            wb_bytes;       /* dirty range */
+       unsigned int            wb_count;       /* user count */
+       int                     wb_status;
        pid_t                   wb_pid;         /* owner process */
        unsigned short          wb_flags;       /* status flags */
 
        struct nfs_writeargs    wb_args;        /* NFS RPC stuff */
        struct nfs_fattr        wb_fattr;       /* file attributes */
 };
-#define wb_status              wb_task.tk_status
 
 #define WB_NEXT(req)           ((struct nfs_wreq *) ((req)->wb_list.next))
 
 /*
  * Various flags for wb_flags
  */
-#define NFS_WRITE_WANTLOCK     0x0001  /* needs to lock page */
-#define NFS_WRITE_LOCKED       0x0002  /* holds lock on page */
 #define NFS_WRITE_CANCELLED    0x0004  /* has been cancelled */
 #define NFS_WRITE_UNCOMMITTED  0x0008  /* written but uncommitted (NFSv3) */
 #define NFS_WRITE_INVALIDATE   0x0010  /* invalidate after write */
 #define NFS_WRITE_INPROGRESS   0x0100  /* RPC call in progress */
 #define NFS_WRITE_COMPLETE     0x0200  /* RPC call completed */
 
-#define WB_WANTLOCK(req)       ((req)->wb_flags & NFS_WRITE_WANTLOCK)
-#define WB_HAVELOCK(req)       ((req)->wb_flags & NFS_WRITE_LOCKED)
 #define WB_CANCELLED(req)      ((req)->wb_flags & NFS_WRITE_CANCELLED)
 #define WB_UNCOMMITTED(req)    ((req)->wb_flags & NFS_WRITE_UNCOMMITTED)
 #define WB_INVALIDATE(req)     ((req)->wb_flags & NFS_WRITE_INVALIDATE)
@@ -217,6 +215,7 @@ extern int  nfs_writepage(struct file *, struct page *);
 extern int  nfs_find_dentry_request(struct inode *, struct dentry *);
 extern int  nfs_check_failed_request(struct inode *);
 extern int  nfs_check_error(struct inode *);
+extern int  nfs_flush_pages(struct inode *, pid_t, off_t, off_t);
 extern int  nfs_flush_dirty_pages(struct inode *, pid_t, off_t, off_t);
 extern int  nfs_truncate_dirty_pages(struct inode *, unsigned long);
 extern void nfs_invalidate_pages(struct inode *);
@@ -245,13 +244,10 @@ nfs_revalidate_inode(struct nfs_server *server, struct dentry *dentry)
        return _nfs_revalidate_inode(server, dentry);
 }
 
-extern struct nfs_wreq *       nfs_failed_requests;
 static inline int
 nfs_write_error(struct inode *inode)
 {
-       if (nfs_failed_requests == NULL)
-               return 0;
-       return nfs_check_error(inode);
+       return NFS_WRITEBACK(inode) && nfs_check_error(inode);
 }
 
 /* NFS root */
index bb9364e2b171d0428332bc5263125fa16f00f464..086cb1c95e06b18ab5cd1ecb00894eadbc5753a9 100644 (file)
@@ -20,7 +20,6 @@ extern unsigned long event;
 #include <linux/tty.h>
 #include <linux/sem.h>
 #include <linux/signal.h>
-#include <linux/capability.h>
 #include <linux/securebits.h>
 
 /*
@@ -65,11 +64,9 @@ extern int nr_running, nr_tasks;
 extern int last_pid;
 
 #include <linux/fs.h>
-#include <linux/signal.h>
 #include <linux/time.h>
 #include <linux/param.h>
 #include <linux/resource.h>
-#include <linux/ptrace.h>
 #include <linux/timer.h>
 
 #include <asm/processor.h>
index 4adf92e9d536b80f7440001e0a7ee7daa0186075..f208b17b672988e2ed0c23f97f555d2a75e44c88 100644 (file)
 
 #define __KERNEL_SYSCALLS__
 
-#include <linux/types.h>
+#include <linux/sched.h>
 #include <linux/fcntl.h>
 #include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
 #include <linux/unistd.h>
 #include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
@@ -34,7 +29,6 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 
-#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/bugs.h>
 
index ed0353184a530f4576790ac6a33fe6e6b3098e27..1c39c73f2ab722bd33d3b042afcb5fae6932c3e6 100644 (file)
 #include <linux/kernel.h>
 
 #ifdef CONFIG_BSD_PROCESS_ACCT
-#include <linux/fs.h>
+#include <linux/sched.h>
 #include <linux/vfs.h>
-#include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/stat.h>
-#include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/tty.h>
 #include <linux/acct.h>
 #include <linux/major.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/file.h>
 
index 1ba6db19245b2463d805e39b321e7d2cc720d4e1..45e24f6e4488299fb91da13ea69e06c3a8ccc5e9 100644 (file)
@@ -6,10 +6,8 @@
  */ 
 
 #include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/capability.h>
-#include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/mm.h>
 #include <linux/string.h>
 
 #include <asm/uaccess.h>
index 5d7e2f056c9cd15abb81e91f900cba052b6239a3..793b42c13dc4d2f56350daab03e4602aad4b38b7 100644 (file)
@@ -1,8 +1,5 @@
-#include <linux/personality.h>
-#include <linux/ptrace.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/module.h>
 
index dcb23ac974c4b4c26556bd71528a05c675ff87dc..44db626cb6e514fd803e32ffbde753d25af417a7 100644 (file)
@@ -7,16 +7,12 @@
 #include <linux/config.h>
 #include <linux/wait.h>
 #include <linux/errno.h>
-#include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>
 #include <linux/resource.h>
 #include <linux/mm.h>
-#include <linux/tty.h>
 #include <linux/malloc.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index a1ef239aa636ab37ffc2fc5ca9979bce29b550a6..dcb08b761f4fa262ae64590425a8587a11080c48 100644 (file)
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/unistd.h>
-#include <linux/ptrace.h>
 #include <linux/malloc.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/module.h>
 
-#include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 #include <asm/uaccess.h>
index ffaec7140e78e85f3333701727b851cb382906e4..8a56ce5f26233be1ea53d325a88f87aa2882497f 100644 (file)
@@ -9,10 +9,8 @@
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/unistd.h>
-#include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
index 192f80954f2696ab0e2c333b86eb7cab862f2c13..5709598a4d2aed24909b8d50b453ba211bedc45e 100644 (file)
@@ -6,13 +6,10 @@
 
 /* These are all the functions necessary to implement itimers */
 
-#include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/time.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
index 7a57d778e1f35f0fc4712a3028da92ca57cdde79..8b19e2415db307ec2cb699e2d60574e28782953d 100644 (file)
 #define __KERNEL_SYSCALLS__
 
 #include <linux/sched.h>
-#include <linux/types.h>
 #include <linux/unistd.h>
 #include <linux/smp_lock.h>
-#include <linux/signal.h>
 
 #include <asm/uaccess.h>
 
index 70be945efbbbec06f90d4b49e3f6c880996b744b..31ddd48bd4f7410cc7b41894b89bd89d55ffef6e 100644 (file)
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
+#include <linux/sched.h>
 #include <linux/blkdev.h>
 #include <linux/cdrom.h>
-#include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/ptrace.h>
 #include <linux/sys.h>
 #include <linux/utsname.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/binfmts.h>
-#include <linux/personality.h>
 #include <linux/termios.h>
 #include <linux/tqueue.h>
-#include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/locks.h>
 #include <linux/string.h>
 #include <linux/delay.h>
-#include <linux/sem.h>
 #include <linux/minix_fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/random.h>
@@ -51,9 +43,6 @@
 #include <linux/ctype.h>
 #include <linux/file.h>
 #include <linux/console.h>
-#include <linux/time.h>
-
-#include <asm/spinlock.h>
 
 #if defined(CONFIG_PROC_FS)
 #include <linux/proc_fs.h>
@@ -62,9 +51,6 @@
 #include <linux/kmod.h>
 #endif
 #include <asm/irq.h>
-#ifdef __SMP__
-#include <linux/smp.h>
-#endif
 
 extern char *get_options(char *str, int *ints);
 extern void set_device_ro(kdev_t dev,int flag);
index e367a747c3dbd901d2506c047986cb98bf0eda93..a71ff3de7385da9d058b864200a4800975aa48f0 100644 (file)
@@ -1,13 +1,11 @@
 #include <linux/errno.h>
-#include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/mm.h>          /* defines GFP_KERNEL */
 #include <linux/string.h>
 #include <linux/module.h>
-#include <linux/sched.h>
 #include <linux/config.h>
 #include <asm/uaccess.h>
 #include <linux/vmalloc.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <asm/pgtable.h>
 
index 14bb727fc33fe64e0a3655650318674e14e25ce4..bba75e3effc03a2fc5f578c1ff0111d632a8bb30 100644 (file)
  */
 #include <stdarg.h>
 
-#include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
-#include <linux/smp.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/sysrq.h>
index 0d8287fefaeeb1b5cac118f3e6429baa10a59032..66c09926c06460c6aed216fab7e37af7eeff243c 100644 (file)
 
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/tty.h>
 #include <linux/tty_driver.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/console.h>
 #include <linux/init.h>
 
-#include <asm/system.h>
 #include <asm/uaccess.h>
 
 #define LOG_BUF_LEN    (16384)
index 2d6b56eb0fd49158515be7f81a6250a83509e027..fa607edf8a71061396ef3838a2c8ef0b0927e045 100644 (file)
@@ -8,9 +8,7 @@
  */
 
 #include <linux/sched.h>
-#include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/types.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 
index 08bc754ae351ce33b7d9f325fa182d81cf1d5266..5b27103b412c7297ccfcd8a2fc536dbc787b7aa1 100644 (file)
  * current-task
  */
 
-#include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/kernel.h>
 #include <linux/kernel_stat.h>
 #include <linux/fdreg.h>
 #include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/ptrace.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/tqueue.h>
 #include <linux/resource.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 
-#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
index e519bcb22c21a5e6a6b718ea80ca803bb30aa204..ebfb88ad2771411431aa30acdfc37509f39a0d74 100644 (file)
@@ -8,14 +8,10 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
-#include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -333,10 +329,10 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
                if (nr_queued_signals < max_queued_signals) {
                        q = (struct signal_queue *)
                            kmem_cache_alloc(signal_queue_cachep, GFP_KERNEL);
-                       nr_queued_signals++;
                }
                
                if (q) {
+                       nr_queued_signals++;
                        q->next = NULL;
                        *t->sigqueue_tail = q;
                        t->sigqueue_tail = &q->next;
index 4bc5ee4b6f5533546506c4738565b377f4d29759..42bdd17523deff598610ff535e0092a2b574c77f 100644 (file)
@@ -8,17 +8,13 @@
  * bottom_half handler need not be re-entrant.
  */
 
-#include <linux/ptrace.h>
 #include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
 #include <linux/sched.h>
+#include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 
-#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/bitops.h>
index 062f9f5db8646ebaaddeff1776bc3d3288f7857e..0ef636bfb33c97af8dfcfd899f006fd313a5705d 100644 (file)
@@ -6,20 +6,13 @@
 
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/times.h>
 #include <linux/utsname.h>
-#include <linux/param.h>
 #include <linux/resource.h>
-#include <linux/signal.h>
 #include <linux/string.h>
-#include <linux/ptrace.h>
 #include <linux/stat.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/fcntl.h>
-#include <linux/tty.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
index f439d77db3878c8b42ae8a0cb6b9703d84c1d268..69b81fe508db1c0393443638b3f6a69e05b047d7 100644 (file)
 #include <linux/ctype.h>
 #include <linux/utsname.h>
 #include <linux/swapctl.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
-#include <linux/fs.h>
 
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
index 0f1094655828e58442ed81e7b83877fd97228cdb..884fa15194969acdde96a7cdd4441191aea8f02a 100644 (file)
 
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/timex.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
index 1691cc68c71a909756207eec6a863d4ffe3ddfc9..df82a952418d8d2bbe2ddb213d6b49393dd0cd17 100644 (file)
@@ -1567,7 +1567,8 @@ generic_file_write(struct file *file, const char *buf,
                        bytes = count;
 
                hash = page_hash(inode, pgpos);
-               if (!(page = __find_page(inode, pgpos, *hash))) {
+               page = __find_page(inode, pgpos, *hash);
+               if (!page) {
                        if (!page_cache) {
                                page_cache = __get_free_page(GFP_USER);
                                if (page_cache)
@@ -1580,21 +1581,25 @@ generic_file_write(struct file *file, const char *buf,
                        page_cache = 0;
                }
 
+               /* Get exclusive IO access to the page.. */
                wait_on_page(page);
                set_bit(PG_locked, &page->flags);
 
+               /*
+                * Do the real work.. If the writer ends up delaying the write,
+                * the writer needs to increment the page use counts until he
+                * is done with the page.
+                */
                bytes -= copy_from_user((u8*)page_address(page) + offset, buf, bytes);
-               if (!bytes) {
-                       status = -EFAULT;
-                       clear_bit(PG_locked, &page->flags);
-                       wake_up(&page->wait);
-                       __free_page(page);
-                       break;
-               }
-
-               status = inode->i_op->updatepage(file, page, offset, bytes, sync);
+               status = -EFAULT;
+               if (bytes)
+                       status = inode->i_op->updatepage(file, page, offset, bytes, sync);
 
+               /* Mark it unlocked again and drop the page.. */
+               clear_bit(PG_locked, &page->flags);
+               wake_up(&page->wait);
                __free_page(page);
+
                if (status < 0)
                        break;