Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
[pandora-kernel.git] / fs / reiserfs / file.c
index f318b58..99b6f32 100644 (file)
@@ -37,8 +37,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
        int err;
        int jbegin_failure = 0;
 
-       if (!S_ISREG(inode->i_mode))
-               BUG();
+       BUG_ON(!S_ISREG(inode->i_mode));
 
        /* fast out for when nothing needs to be done */
        if ((atomic_read(&inode->i_count) > 1 ||
@@ -48,8 +47,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
                return 0;
        }
 
-       reiserfs_write_lock(inode->i_sb);
        mutex_lock(&inode->i_mutex);
+       reiserfs_write_lock(inode->i_sb);
        /* freeing preallocation only involves relogging blocks that
         * are already in the current transaction.  preallocation gets
         * freed at the end of each transaction, so it is impossible for
@@ -75,7 +74,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
                        igrab(inode);
                        reiserfs_warning(inode->i_sb,
                                         "pinning inode %lu because the "
-                                        "preallocation can't be freed");
+                                        "preallocation can't be freed",
+                                        inode->i_ino);
                        goto out;
                }
        }
@@ -124,13 +124,12 @@ static int reiserfs_sync_file(struct file *p_s_filp,
        int n_err;
        int barrier_done;
 
-       if (!S_ISREG(p_s_inode->i_mode))
-               BUG();
+       BUG_ON(!S_ISREG(p_s_inode->i_mode));
        n_err = sync_mapping_buffers(p_s_inode->i_mapping);
        reiserfs_write_lock(p_s_inode->i_sb);
        barrier_done = reiserfs_commit_for_inode(p_s_inode);
        reiserfs_write_unlock(p_s_inode->i_sb);
-       if (barrier_done != 1)
+       if (barrier_done != 1 && reiserfs_barrier_flush(p_s_inode->i_sb))
                blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
        if (barrier_done < 0)
                return barrier_done;
@@ -318,12 +317,11 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl
                        /* area filled with zeroes, to supply as list of zero blocknumbers
                           We allocate it outside of loop just in case loop would spin for
                           several iterations. */
-                       char *zeros = kmalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC);      // We cannot insert more than MAX_ITEM_LEN bytes anyway.
+                       char *zeros = kzalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC);      // We cannot insert more than MAX_ITEM_LEN bytes anyway.
                        if (!zeros) {
                                res = -ENOMEM;
                                goto error_exit_free_blocks;
                        }
-                       memset(zeros, 0, to_paste * UNFM_P_SIZE);
                        do {
                                to_paste =
                                    min_t(__u64, hole_size,
@@ -408,6 +406,8 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl
                                   we restart it. This will also free the path. */
                                if (journal_transaction_should_end
                                    (th, th->t_blocks_allocated)) {
+                                       inode->i_size = cpu_key_k_offset(&key) +
+                                               (to_paste << inode->i_blkbits);
                                        res =
                                            restart_transaction(th, inode,
                                                                &path);
@@ -1046,6 +1046,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode
                        char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
                        memset(kaddr, 0, from);
                        kunmap_atomic(kaddr, KM_USER0);
+                       flush_dcache_page(prepared_pages[0]);
                }
                if (to != PAGE_CACHE_SIZE) {    /* Last page needs to be partially zeroed */
                        char *kaddr =
@@ -1053,6 +1054,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode
                                        KM_USER0);
                        memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
                        kunmap_atomic(kaddr, KM_USER0);
+                       flush_dcache_page(prepared_pages[num_pages - 1]);
                }
 
                /* Since all blocks are new - use already calculated value */
@@ -1186,6 +1188,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode
                                        memset(kaddr + block_start, 0,
                                               from - block_start);
                                        kunmap_atomic(kaddr, KM_USER0);
+                                       flush_dcache_page(prepared_pages[0]);
                                        set_buffer_uptodate(bh);
                                }
                        }
@@ -1223,6 +1226,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode
                                                        KM_USER0);
                                        memset(kaddr + to, 0, block_end - to);
                                        kunmap_atomic(kaddr, KM_USER0);
+                                       flush_dcache_page(prepared_pages[num_pages - 1]);
                                        set_buffer_uptodate(bh);
                                }
                        }
@@ -1284,7 +1288,7 @@ static ssize_t reiserfs_file_write(struct file *file,     /* the file we are going t
        loff_t pos;             // Current position in the file.
        ssize_t res;            // return value of various functions that we call.
        int err = 0;
-       struct inode *inode = file->f_dentry->d_inode;  // Inode of the file that we are writing to.
+       struct inode *inode = file->f_path.dentry->d_inode;     // Inode of the file that we are writing to.
        /* To simplify coding at this time, we store
           locked pages in array for now */
        struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
@@ -1308,56 +1312,8 @@ static ssize_t reiserfs_file_write(struct file *file,    /* the file we are going t
                        count = MAX_NON_LFS - (unsigned long)*ppos;
        }
 
-       if (file->f_flags & O_DIRECT) { // Direct IO needs treatment
-               ssize_t result, after_file_end = 0;
-               if ((*ppos + count >= inode->i_size)
-                   || (file->f_flags & O_APPEND)) {
-                       /* If we are appending a file, we need to put this savelink in here.
-                          If we will crash while doing direct io, finish_unfinished will
-                          cut the garbage from the file end. */
-                       reiserfs_write_lock(inode->i_sb);
-                       err =
-                           journal_begin(&th, inode->i_sb,
-                                         JOURNAL_PER_BALANCE_CNT);
-                       if (err) {
-                               reiserfs_write_unlock(inode->i_sb);
-                               return err;
-                       }
-                       reiserfs_update_inode_transaction(inode);
-                       add_save_link(&th, inode, 1 /* Truncate */ );
-                       after_file_end = 1;
-                       err =
-                           journal_end(&th, inode->i_sb,
-                                       JOURNAL_PER_BALANCE_CNT);
-                       reiserfs_write_unlock(inode->i_sb);
-                       if (err)
-                               return err;
-               }
-               result = generic_file_write(file, buf, count, ppos);
-
-               if (after_file_end) {   /* Now update i_size and remove the savelink */
-                       struct reiserfs_transaction_handle th;
-                       reiserfs_write_lock(inode->i_sb);
-                       err = journal_begin(&th, inode->i_sb, 1);
-                       if (err) {
-                               reiserfs_write_unlock(inode->i_sb);
-                               return err;
-                       }
-                       reiserfs_update_inode_transaction(inode);
-                       mark_inode_dirty(inode);
-                       err = journal_end(&th, inode->i_sb, 1);
-                       if (err) {
-                               reiserfs_write_unlock(inode->i_sb);
-                               return err;
-                       }
-                       err = remove_save_link(inode, 1 /* truncate */ );
-                       reiserfs_write_unlock(inode->i_sb);
-                       if (err)
-                               return err;
-               }
-
-               return result;
-       }
+       if (file->f_flags & O_DIRECT)
+               return do_sync_write(file, buf, count, ppos);
 
        if (unlikely((ssize_t) count < 0))
                return -EINVAL;
@@ -1379,7 +1335,7 @@ static ssize_t reiserfs_file_write(struct file *file,     /* the file we are going t
        if (count == 0)
                goto out;
 
-       res = remove_suid(file->f_dentry);
+       res = remove_suid(file->f_path.dentry);
        if (res)
                goto out;
 
@@ -1565,10 +1521,14 @@ static ssize_t reiserfs_file_write(struct file *file,   /* the file we are going t
 }
 
 const struct file_operations reiserfs_file_operations = {
-       .read = generic_file_read,
+       .read = do_sync_read,
        .write = reiserfs_file_write,
        .ioctl = reiserfs_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = reiserfs_compat_ioctl,
+#endif
        .mmap = generic_file_mmap,
+       .open = generic_file_open,
        .release = reiserfs_file_release,
        .fsync = reiserfs_sync_file,
        .sendfile = generic_file_sendfile,