[libata] blacklist Maxtor*BANC* using new wildcard blacklist matching
[safe/jmp/linux-2.6] / fs / reiserfs / inode.c
index 5f82352..ddde489 100644 (file)
@@ -2,12 +2,12 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-#include <linux/config.h>
 #include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/reiserfs_acl.h>
 #include <linux/reiserfs_xattr.h>
+#include <linux/exportfs.h>
 #include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
@@ -18,8 +18,6 @@
 #include <linux/writeback.h>
 #include <linux/quotaops.h>
 
-extern int reiserfs_default_io_size;   /* default io size devuned in super.c */
-
 static int reiserfs_commit_write(struct file *f, struct page *page,
                                 unsigned from, unsigned to);
 static int reiserfs_prepare_write(struct file *f, struct page *page,
@@ -32,6 +30,7 @@ void reiserfs_delete_inode(struct inode *inode)
            JOURNAL_PER_BALANCE_CNT * 2 +
            2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
        struct reiserfs_transaction_handle th;
+       int err;
 
        truncate_inode_pages(&inode->i_data, 0);
 
@@ -39,32 +38,28 @@ void reiserfs_delete_inode(struct inode *inode)
 
        /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
        if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) {  /* also handles bad_inode case */
-               down(&inode->i_sem);
-
                reiserfs_delete_xattrs(inode);
 
-               if (journal_begin(&th, inode->i_sb, jbegin_count)) {
-                       up(&inode->i_sem);
+               if (journal_begin(&th, inode->i_sb, jbegin_count))
                        goto out;
-               }
                reiserfs_update_inode_transaction(inode);
 
-               if (reiserfs_delete_object(&th, inode)) {
-                       up(&inode->i_sem);
-                       goto out;
-               }
+               err = reiserfs_delete_object(&th, inode);
 
                /* Do quota update inside a transaction for journaled quotas. We must do that
                 * after delete_object so that quota updates go into the same transaction as
                 * stat data deletion */
-               DQUOT_FREE_INODE(inode);
+               if (!err) 
+                       DQUOT_FREE_INODE(inode);
 
-               if (journal_end(&th, inode->i_sb, jbegin_count)) {
-                       up(&inode->i_sem);
+               if (journal_end(&th, inode->i_sb, jbegin_count))
                        goto out;
-               }
 
-               up(&inode->i_sem);
+               /* check return value from reiserfs_delete_object after
+                * ending the transaction
+                */
+               if (err)
+                   goto out;
 
                /* all items of file are deleted, so we can remove "save" link */
                remove_save_link(inode, 0 /* not truncate */ ); /* we can't do anything
@@ -213,7 +208,7 @@ static int file_capable(struct inode *inode, long block)
 }
 
 /*static*/ int restart_transaction(struct reiserfs_transaction_handle *th,
-                                  struct inode *inode, struct path *path)
+                                  struct inode *inode, struct treepath *path)
 {
        struct super_block *s = th->t_super;
        int len = th->t_blocks_allocated;
@@ -222,11 +217,12 @@ static int file_capable(struct inode *inode, long block)
        BUG_ON(!th->t_trans_id);
        BUG_ON(!th->t_refcount);
 
+       pathrelse(path);
+
        /* we cannot restart while nested */
        if (th->t_refcount > 1) {
                return 0;
        }
-       pathrelse(path);
        reiserfs_update_sd(th, inode);
        err = journal_end(th, s, len);
        if (!err) {
@@ -461,7 +457,6 @@ static int reiserfs_get_block_create_0(struct inode *inode, sector_t block,
    direct_IO request. */
 static int reiserfs_get_blocks_direct_io(struct inode *inode,
                                         sector_t iblock,
-                                        unsigned long max_blocks,
                                         struct buffer_head *bh_result,
                                         int create)
 {
@@ -546,7 +541,7 @@ static int convert_tail_for_hole(struct inode *inode,
 
        /* we don't have to make sure the conversion did not happen while
         ** we were locking the page because anyone that could convert
-        ** must first take i_sem.
+        ** must first take i_mutex.
         **
         ** We must fix the tail page for writing because it might have buffers
         ** that are mapped, but have a block number of 0.  This indicates tail
@@ -576,12 +571,12 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th,
                                  long block,
                                  struct inode *inode,
                                  b_blocknr_t * allocated_block_nr,
-                                 struct path *path, int flags)
+                                 struct treepath *path, int flags)
 {
        BUG_ON(!th->t_trans_id);
 
 #ifdef REISERFS_PREALLOCATE
-       if (!(flags & GET_BLOCK_NO_ISEM)) {
+       if (!(flags & GET_BLOCK_NO_IMUX)) {
                return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr,
                                                  path, block);
        }
@@ -622,11 +617,6 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
        reiserfs_write_lock(inode->i_sb);
        version = get_inode_item_key_version(inode);
 
-       if (block < 0) {
-               reiserfs_write_unlock(inode->i_sb);
-               return -EIO;
-       }
-
        if (!file_capable(inode, block)) {
                reiserfs_write_unlock(inode->i_sb);
                return -EFBIG;
@@ -929,25 +919,23 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
                                     //pos_in_item * inode->i_sb->s_blocksize,
                                     TYPE_INDIRECT, 3); // key type is unimportant
 
+                       RFALSE(cpu_key_k_offset(&tmp_key) > cpu_key_k_offset(&key),
+                              "green-805: invalid offset");
                        blocks_needed =
                            1 +
                            ((cpu_key_k_offset(&key) -
                              cpu_key_k_offset(&tmp_key)) >> inode->i_sb->
                             s_blocksize_bits);
-                       RFALSE(blocks_needed < 0, "green-805: invalid offset");
 
                        if (blocks_needed == 1) {
                                un = &unf_single;
                        } else {
-                               un = kmalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC);      // We need to avoid scheduling.
+                               un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC);      // We need to avoid scheduling.
                                if (!un) {
                                        un = &unf_single;
                                        blocks_needed = 1;
                                        max_to_insert = 0;
-                               } else
-                                       memset(un, 0,
-                                              UNFM_P_SIZE * min(blocks_needed,
-                                                                max_to_insert));
+                               }
                        }
                        if (blocks_needed <= max_to_insert) {
                                /* we are going to add target block to the file. Use allocated
@@ -1120,7 +1108,7 @@ static inline ulong to_fake_used_blocks(struct inode *inode, int sd_size)
 //
 
 // called by read_locked_inode
-static void init_inode(struct inode *inode, struct path *path)
+static void init_inode(struct inode *inode, struct treepath *path)
 {
        struct buffer_head *bh;
        struct item_head *ih;
@@ -1131,7 +1119,6 @@ static void init_inode(struct inode *inode, struct path *path)
        ih = PATH_PITEM_HEAD(path);
 
        copy_key(INODE_PKEY(inode), &(ih->ih_key));
-       inode->i_blksize = reiserfs_default_io_size;
 
        INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list));
        REISERFS_I(inode)->i_flags = 0;
@@ -1139,9 +1126,10 @@ static void init_inode(struct inode *inode, struct path *path)
        REISERFS_I(inode)->i_prealloc_count = 0;
        REISERFS_I(inode)->i_trans_id = 0;
        REISERFS_I(inode)->i_jl = NULL;
-       REISERFS_I(inode)->i_acl_access = NULL;
-       REISERFS_I(inode)->i_acl_default = NULL;
-       init_rwsem(&REISERFS_I(inode)->xattr_sem);
+       mutex_init(&(REISERFS_I(inode)->i_mmap));
+       reiserfs_init_acl_access(inode);
+       reiserfs_init_acl_default(inode);
+       reiserfs_init_xattr_rwsem(inode);
 
        if (stat_data_v1(ih)) {
                struct stat_data_v1 *sd =
@@ -1298,7 +1286,7 @@ static void inode2sd_v1(void *sd, struct inode *inode, loff_t size)
 /* NOTE, you must prepare the buffer head before sending it here,
 ** and then log it after the call
 */
-static void update_stat_data(struct path *path, struct inode *inode,
+static void update_stat_data(struct treepath *path, struct inode *inode,
                             loff_t size)
 {
        struct buffer_head *bh;
@@ -1667,7 +1655,7 @@ int reiserfs_write_inode(struct inode *inode, int do_sync)
    containing "." and ".." entries */
 static int reiserfs_new_directory(struct reiserfs_transaction_handle *th,
                                  struct inode *inode,
-                                 struct item_head *ih, struct path *path,
+                                 struct item_head *ih, struct treepath *path,
                                  struct inode *dir)
 {
        struct super_block *sb = th->t_super;
@@ -1726,7 +1714,7 @@ static int reiserfs_new_directory(struct reiserfs_transaction_handle *th,
    containing the body of symlink */
 static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct inode *inode,   /* Inode of symlink */
                                struct item_head *ih,
-                               struct path *path, const char *symname,
+                               struct treepath *path, const char *symname,
                                int item_len)
 {
        struct super_block *sb = th->t_super;
@@ -1792,7 +1780,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                err = -EDQUOT;
                goto out_end_trans;
        }
-       if (!dir || !dir->i_nlink) {
+       if (!dir->i_nlink) {
                err = -EPERM;
                goto out_bad_inode;
        }
@@ -1846,9 +1834,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        REISERFS_I(inode)->i_attrs =
            REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
        sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
-       REISERFS_I(inode)->i_acl_access = NULL;
-       REISERFS_I(inode)->i_acl_default = NULL;
-       init_rwsem(&REISERFS_I(inode)->xattr_sem);
+       mutex_init(&(REISERFS_I(inode)->i_mmap));
+       reiserfs_init_acl_access(inode);
+       reiserfs_init_acl_default(inode);
+       reiserfs_init_xattr_rwsem(inode);
 
        if (old_format_only(sb))
                make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET,
@@ -1886,7 +1875,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        }
        // these do not go to on-disk stat data
        inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid);
-       inode->i_blksize = reiserfs_default_io_size;
 
        // store in in-core inode the key of stat data and version all
        // object items will have (directory items will have old offset
@@ -1987,11 +1975,13 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
         * iput doesn't deadlock in reiserfs_delete_xattrs. The locking
         * code really needs to be reworked, but this will take care of it
         * for now. -jeffm */
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
        if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) {
                reiserfs_write_unlock_xattrs(dir->i_sb);
                iput(inode);
                reiserfs_write_lock_xattrs(dir->i_sb);
        } else
+#endif
                iput(inode);
        return err;
 }
@@ -2099,6 +2089,7 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps)
        struct page *page = NULL;
        int error;
        struct buffer_head *bh = NULL;
+       int err2;
 
        reiserfs_write_lock(p_s_inode->i_sb);
 
@@ -2136,14 +2127,18 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps)
                   transaction of truncating gets committed - on reboot the file
                   either appears truncated properly or not truncated at all */
                add_save_link(&th, p_s_inode, 1);
-       error = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps);
-       if (error)
-               goto out;
+       err2 = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps);
        error =
            journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1);
        if (error)
                goto out;
 
+       /* check reiserfs_do_truncate after ending the transaction */
+       if (err2) {
+               error = err2;
+               goto out;
+       }
+       
        if (update_timestamps) {
                error = remove_save_link(p_s_inode, 1 /* truncate */ );
                if (error)
@@ -2154,13 +2149,8 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps)
                length = offset & (blocksize - 1);
                /* if we are not on a block boundary */
                if (length) {
-                       char *kaddr;
-
                        length = blocksize - length;
-                       kaddr = kmap_atomic(page, KM_USER0);
-                       memset(kaddr + offset, 0, length);
-                       flush_dcache_page(page);
-                       kunmap_atomic(kaddr, KM_USER0);
+                       zero_user_page(page, offset, length, KM_USER0);
                        if (buffer_mapped(bh) && bh->b_blocknr != 0) {
                                mark_buffer_dirty(bh);
                        }
@@ -2194,7 +2184,7 @@ static int map_block_for_writepage(struct inode *inode,
        INITIALIZE_PATH(path);
        int pos_in_item;
        int jbegin_count = JOURNAL_PER_BALANCE_CNT;
-       loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1;
+       loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1;
        int retval;
        int use_get_block = 0;
        int bytes_copied = 0;
@@ -2308,7 +2298,7 @@ static int map_block_for_writepage(struct inode *inode,
        /* this is where we fill in holes in the file. */
        if (use_get_block) {
                retval = reiserfs_get_block(inode, block, bh_result,
-                                           GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM
+                                           GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX
                                            | GET_BLOCK_NO_DANGLE);
                if (!retval) {
                        if (!buffer_mapped(bh_result)
@@ -2344,6 +2334,7 @@ static int reiserfs_write_full_page(struct page *page,
        unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
        int error = 0;
        unsigned long block;
+       sector_t last_block;
        struct buffer_head *head, *bh;
        int partial = 0;
        int nr = 0;
@@ -2353,6 +2344,13 @@ static int reiserfs_write_full_page(struct page *page,
        int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
        th.t_trans_id = 0;
 
+       /* no logging allowed when nonblocking or from PF_MEMALLOC */
+       if (checked && (current->flags & PF_MEMALLOC)) {
+               redirty_page_for_writepage(wbc, page);
+               unlock_page(page);
+               return 0;
+       }
+
        /* The page dirty bit is cleared before writepage is called, which
         * means we have to tell create_empty_buffers to make dirty buffers
         * The page really should be up to date at this point, so tossing
@@ -2368,7 +2366,6 @@ static int reiserfs_write_full_page(struct page *page,
         ** last byte in the file
         */
        if (page->index >= end_index) {
-               char *kaddr;
                unsigned last_offset;
 
                last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1);
@@ -2377,17 +2374,23 @@ static int reiserfs_write_full_page(struct page *page,
                        unlock_page(page);
                        return 0;
                }
-               kaddr = kmap_atomic(page, KM_USER0);
-               memset(kaddr + last_offset, 0, PAGE_CACHE_SIZE - last_offset);
-               flush_dcache_page(page);
-               kunmap_atomic(kaddr, KM_USER0);
+               zero_user_page(page, last_offset, PAGE_CACHE_SIZE - last_offset, KM_USER0);
        }
        bh = head;
        block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits);
+       last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
        /* first map all the buffers, logging any direct items we find */
        do {
-               if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
-                                                     (buffer_mapped(bh)
+               if (block > last_block) {
+                       /*
+                        * This can happen when the block size is less than
+                        * the page size.  The corresponding bytes in the page
+                        * were zero filled above
+                        */
+                       clear_buffer_dirty(bh);
+                       set_buffer_uptodate(bh);
+               } else if ((checked || buffer_dirty(bh)) &&
+                          (!buffer_mapped(bh) || (buffer_mapped(bh)
                                                       && bh->b_blocknr ==
                                                       0))) {
                        /* not mapped yet, or it points to a direct item, search
@@ -2733,6 +2736,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
        int ret = 1;
        struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
 
+       lock_buffer(bh);
        spin_lock(&j->j_dirty_buffers_lock);
        if (!buffer_mapped(bh)) {
                goto free_jh;
@@ -2748,7 +2752,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
                if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
                        ret = 0;
                }
-       } else if (buffer_dirty(bh) || buffer_locked(bh)) {
+       } else  if (buffer_dirty(bh)) {
                struct reiserfs_journal_list *jl;
                struct reiserfs_jh *jh = bh->b_private;
 
@@ -2774,11 +2778,12 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
                reiserfs_free_jh(bh);
        }
        spin_unlock(&j->j_dirty_buffers_lock);
+       unlock_buffer(bh);
        return ret;
 }
 
 /* clm -- taken from fs/buffer.c:block_invalidate_page */
-static int reiserfs_invalidatepage(struct page *page, unsigned long offset)
+static void reiserfs_invalidatepage(struct page *page, unsigned long offset)
 {
        struct buffer_head *head, *bh, *next;
        struct inode *inode = page->mapping->host;
@@ -2817,10 +2822,12 @@ static int reiserfs_invalidatepage(struct page *page, unsigned long offset)
         * The get_block cached value has been unconditionally invalidated,
         * so real IO is not possible anymore.
         */
-       if (!offset && ret)
+       if (!offset && ret) {
                ret = try_to_release_page(page, 0);
+               /* maybe should BUG_ON(!ret); - neilb */
+       }
       out:
-       return ret;
+       return;
 }
 
 static int reiserfs_set_page_dirty(struct page *page)
@@ -2917,6 +2924,11 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                        }
                        if (error)
                                goto out;
+                       /*
+                        * file size is changed, ctime and mtime are
+                        * to be updated
+                        */
+                       attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME);
                }
        }
 
@@ -2980,7 +2992,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
        return error;
 }
 
-struct address_space_operations reiserfs_address_space_operations = {
+const struct address_space_operations reiserfs_address_space_operations = {
        .writepage = reiserfs_writepage,
        .readpage = reiserfs_readpage,
        .readpages = reiserfs_readpages,