Merge branch 'upstream-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 28 Oct 2010 04:54:31 +0000 (21:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 28 Oct 2010 04:54:31 +0000 (21:54 -0700)
* 'upstream-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (50 commits)
  ext4,jbd2: convert tracepoints to use major/minor numbers
  ext4: optimize orphan_list handling for ext4_setattr
  ext4: fix unbalanced mutex unlock in error path of ext4_li_request_new
  ext4: fix compile error in ext4_fallocate()
  ext4: move ext4_mb_{get,put}_buddy_cache_lock and make them static
  ext4: rename mark_bitmap_end() to ext4_mark_bitmap_end()
  ext4: move flush_completed_IO to fs/ext4/fsync.c and make it static
  ext4: rename {ext,idx}_pblock and inline small extent functions
  ext4: make various ext4 functions be static
  ext4: rename {exit,init}_ext4_*() to ext4_{exit,init}_*()
  ext4: fix kernel oops if the journal superblock has a non-zero j_errno
  ext4: update writeback_index based on last page scanned
  ext4: implement writeback livelock avoidance using page tagging
  ext4: tidy up a void argument in inode.c
  ext4: add batched_discard into ext4 feature list
  ext4: Add batched discard support for ext4
  fs: Add FITRIM ioctl
  ext4: Use return value from sb_issue_discard()
  ext4: Check return value of sb_getblk() and friends
  ext4: use bio layer instead of buffer layer in mpage_da_submit_io
  ...

21 files changed:
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100_track.h
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/radeon_reg.h
fs/ext2/balloc.c
fs/ext3/balloc.c
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/resize.c
fs/ext3/super.c
fs/jbd/checkpoint.c
fs/jbd/commit.c
fs/jbd/journal.c
fs/jbd/recovery.c
fs/jbd/transaction.c
fs/jbd2/journal.c
fs/quota/Kconfig
fs/quota/dquot.c
fs/xfs/Kconfig

index 086b9b0..ac3b6dd 100644 (file)
@@ -495,6 +495,7 @@ done:
                dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
                return r;
        }
+       rdev->mc.active_vram_size = rdev->mc.real_vram_size;
        return 0;
 }
 
@@ -502,6 +503,7 @@ void evergreen_blit_fini(struct radeon_device *rdev)
 {
        int r;
 
+       rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
        if (rdev->r600_blit.shader_obj == NULL)
                return;
        /* If we can't reserve the bo, unref should be enough to destroy
index 6d1540c..0e8f28a 100644 (file)
@@ -3180,6 +3180,8 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
        for (u = 0; u < track->num_texture; u++) {
                if (!track->textures[u].enabled)
                        continue;
+               if (track->textures[u].lookup_disable)
+                       continue;
                robj = track->textures[u].robj;
                if (robj == NULL) {
                        DRM_ERROR("No texture bound to unit %u\n", u);
@@ -3414,6 +3416,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
                track->textures[i].robj = NULL;
                /* CS IB emission code makes sure texture unit are disabled */
                track->textures[i].enabled = false;
+               track->textures[i].lookup_disable = false;
                track->textures[i].roundup_w = true;
                track->textures[i].roundup_h = true;
                if (track->separate_cube)
index f47cdca..af65600 100644 (file)
@@ -46,6 +46,7 @@ struct r100_cs_track_texture {
        unsigned                height_11;
        bool                    use_pitch;
        bool                    enabled;
+       bool                    lookup_disable;
        bool                    roundup_w;
        bool                    roundup_h;
        unsigned                compress_format;
index 0266d72..d2408c3 100644 (file)
@@ -447,6 +447,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
                        track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
                }
+               if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
+                       track->textures[i].lookup_disable = true;
                switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
                case R200_TXFORMAT_I8:
                case R200_TXFORMAT_RGB332:
index 7b294c1..37cc2aa 100644 (file)
@@ -310,7 +310,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
        /* Check depth buffer */
        if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
                G_028800_Z_ENABLE(track->db_depth_control)) {
-               u32 nviews, bpe, ntiles, pitch, pitch_align, height, size;
+               u32 nviews, bpe, ntiles, pitch, pitch_align, height, size, slice_tile_max;
                if (track->db_bo == NULL) {
                        dev_warn(p->dev, "z/stencil with no depth buffer\n");
                        return -EINVAL;
@@ -354,11 +354,11 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                } else {
                        size = radeon_bo_size(track->db_bo);
                        pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1;
-                       height = size / (pitch * 8 * bpe);
-                       height &= ~0x7;
-                       if (!height)
-                               height = 8;
-
+                       slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
+                       slice_tile_max *= 64;
+                       height = slice_tile_max / (pitch * 8);
+                       if (height > 8192)
+                               height = 8192;
                        switch (G_028010_ARRAY_MODE(track->db_depth_info)) {
                        case V_028010_ARRAY_1D_TILED_THIN1:
                                pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8);
@@ -367,6 +367,8 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                                                 __func__, __LINE__, pitch);
                                        return -EINVAL;
                                }
+                               /* don't break userspace */
+                               height &= ~0x7;
                                if (!IS_ALIGNED(height, 8)) {
                                        dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
                                                 __func__, __LINE__, height);
index c332f46..6492881 100644 (file)
 #       define R200_TXFORMAT_ST_ROUTE_STQ5     (5 << 24)
 #       define R200_TXFORMAT_ST_ROUTE_MASK     (7 << 24)
 #       define R200_TXFORMAT_ST_ROUTE_SHIFT    24
+#       define R200_TXFORMAT_LOOKUP_DISABLE    (1 << 27)
 #       define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28)
 #       define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29)
 #       define R200_TXFORMAT_CUBIC_MAP_ENABLE          (1 << 30)
index c6c684b..0d06f4e 100644 (file)
@@ -646,10 +646,9 @@ find_next_usable_block(int start, struct buffer_head *bh, int maxblocks)
        return here;
 }
 
-/*
+/**
  * ext2_try_to_allocate()
  * @sb:                        superblock
- * @handle:            handle to this transaction
  * @group:             given allocation block group
  * @bitmap_bh:         bufferhead holds the block bitmap
  * @grp_goal:          given target block within the group
index 4a32511..b3db226 100644 (file)
@@ -792,9 +792,9 @@ find_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh,
        if (here < 0)
                here = 0;
 
-       p = ((char *)bh->b_data) + (here >> 3);
+       p = bh->b_data + (here >> 3);
        r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3));
-       next = (r - ((char *)bh->b_data)) << 3;
+       next = (r - bh->b_data) << 3;
 
        if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh))
                return next;
@@ -810,8 +810,9 @@ find_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh,
 
 /**
  * claim_block()
+ * @lock:              the spin lock for this block group
  * @block:             the free block (group relative) to allocate
- * @bh:                        the bufferhead containts the block group bitmap
+ * @bh:                        the buffer_head contains the block group bitmap
  *
  * We think we can allocate this block in this bitmap.  Try to set the bit.
  * If that succeeds then check that nobody has allocated and then freed the
@@ -956,9 +957,11 @@ fail_access:
  *             but we will shift to the place where start_block is,
  *             then start from there, when looking for a reservable space.
  *
- *     @size: the target new reservation window size
+ *     @my_rsv: the reservation window
  *
- *     @group_first_block: the first block we consider to start
+ *     @sb: the super block
+ *
+ *     @start_block: the first block we consider to start
  *                     the real search from
  *
  *     @last_block:
@@ -1084,7 +1087,7 @@ static int find_next_reservable_window(
  *
  *     failed: we failed to find a reservation window in this group
  *
- *     @rsv: the reservation
+ *     @my_rsv: the reservation window
  *
  *     @grp_goal: The goal (group-relative).  It is where the search for a
  *             free reservable space should start from.
@@ -1273,8 +1276,8 @@ static void try_to_extend_reservation(struct ext3_reserve_window_node *my_rsv,
  * @group:             given allocation block group
  * @bitmap_bh:         bufferhead holds the block bitmap
  * @grp_goal:          given target block within the group
- * @count:             target number of blocks to allocate
  * @my_rsv:            reservation window
+ * @count:             target number of blocks to allocate
  * @errp:              pointer to store the error code
  *
  * This is the main function used to allocate a new block and its reservation
index 4ab72db..9724aef 100644 (file)
@@ -570,9 +570,14 @@ got:
        ei->i_state_flags = 0;
        ext3_set_inode_state(inode, EXT3_STATE_NEW);
 
-       ei->i_extra_isize =
-               (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
-               sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
+       /* See comment in ext3_iget for explanation */
+       if (ino >= EXT3_FIRST_INO(sb) + 1 &&
+           EXT3_INODE_SIZE(sb) > EXT3_GOOD_OLD_INODE_SIZE) {
+               ei->i_extra_isize =
+                       sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE;
+       } else {
+               ei->i_extra_isize = 0;
+       }
 
        ret = inode;
        dquot_initialize(inode);
index ad05353..a958061 100644 (file)
@@ -498,7 +498,7 @@ static ext3_fsblk_t ext3_find_goal(struct inode *inode, long block,
 }
 
 /**
- *     ext3_blks_to_allocate: Look up the block map and count the number
+ *     ext3_blks_to_allocate - Look up the block map and count the number
  *     of direct blocks need to be allocated for the given branch.
  *
  *     @branch: chain of indirect blocks
@@ -536,14 +536,18 @@ static int ext3_blks_to_allocate(Indirect *branch, int k, unsigned long blks,
 }
 
 /**
- *     ext3_alloc_blocks: multiple allocate blocks needed for a branch
+ *     ext3_alloc_blocks - multiple allocate blocks needed for a branch
+ *     @handle: handle for this transaction
+ *     @inode: owner
+ *     @goal: preferred place for allocation
  *     @indirect_blks: the number of blocks need to allocate for indirect
  *                     blocks
- *
+ *     @blks:  number of blocks need to allocated for direct blocks
  *     @new_blocks: on return it will store the new block numbers for
  *     the indirect blocks(if needed) and the first direct block,
- *     @blks:  on return it will store the total number of allocated
- *             direct blocks
+ *     @err: here we store the error value
+ *
+ *     return the number of direct blocks allocated
  */
 static int ext3_alloc_blocks(handle_t *handle, struct inode *inode,
                        ext3_fsblk_t goal, int indirect_blks, int blks,
@@ -598,9 +602,11 @@ failed_out:
 
 /**
  *     ext3_alloc_branch - allocate and set up a chain of blocks.
+ *     @handle: handle for this transaction
  *     @inode: owner
  *     @indirect_blks: number of allocated indirect blocks
  *     @blks: number of allocated direct blocks
+ *     @goal: preferred place for allocation
  *     @offsets: offsets (in the blocks) to store the pointers to next.
  *     @branch: place to store the chain in.
  *
@@ -700,10 +706,9 @@ failed:
 
 /**
  * ext3_splice_branch - splice the allocated branch onto inode.
+ * @handle: handle for this transaction
  * @inode: owner
  * @block: (logical) number of block we are adding
- * @chain: chain of indirect blocks (with a missing link - see
- *     ext3_alloc_branch)
  * @where: location of missing link
  * @num:   number of indirect blocks we are adding
  * @blks:  number of direct blocks we are adding
@@ -2530,7 +2535,6 @@ void ext3_truncate(struct inode *inode)
                         */
                } else {
                        /* Shared branch grows from an indirect block */
-                       BUFFER_TRACE(partial->bh, "get_write_access");
                        ext3_free_branches(handle, inode, partial->bh,
                                        partial->p,
                                        partial->p+1, (chain+n-1) - partial);
index 0ccd7b1..e746d30 100644 (file)
@@ -977,7 +977,8 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
        o_blocks_count = le32_to_cpu(es->s_blocks_count);
 
        if (test_opt(sb, DEBUG))
-               printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK" uto "E3FSBLK" blocks\n",
+               printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK
+                      " upto "E3FSBLK" blocks\n",
                       o_blocks_count, n_blocks_count);
 
        if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
@@ -985,7 +986,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
 
        if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
                printk(KERN_ERR "EXT3-fs: filesystem on %s:"
-                       " too large to resize to %lu blocks safely\n",
+                       " too large to resize to "E3FSBLK" blocks safely\n",
                        sb->s_id, n_blocks_count);
                if (sizeof(sector_t) < 8)
                        ext3_warning(sb, __func__,
@@ -1065,11 +1066,11 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
        es->s_blocks_count = cpu_to_le32(o_blocks_count + add);
        ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
        mutex_unlock(&EXT3_SB(sb)->s_resize_lock);
-       ext3_debug("freeing blocks %lu through "E3FSBLK"\n", o_blocks_count,
-                  o_blocks_count + add);
+       ext3_debug("freeing blocks "E3FSBLK" through "E3FSBLK"\n",
+                  o_blocks_count, o_blocks_count + add);
        ext3_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks);
-       ext3_debug("freed blocks "E3FSBLK" through "E3FSBLK"\n", o_blocks_count,
-                  o_blocks_count + add);
+       ext3_debug("freed blocks "E3FSBLK" through "E3FSBLK"\n",
+                  o_blocks_count, o_blocks_count + add);
        if ((err = ext3_journal_stop(handle)))
                goto exit_put;
        if (test_opt(sb, DEBUG))
index 3777680..db87413 100644 (file)
@@ -1301,9 +1301,9 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
                ext3_msg(sb, KERN_WARNING,
                        "warning: mounting fs with errors, "
                        "running e2fsck is recommended");
-       else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
+       else if ((__s16) le16_to_cpu(es->s_max_mnt_count) > 0 &&
                 le16_to_cpu(es->s_mnt_count) >=
-                (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
+                       le16_to_cpu(es->s_max_mnt_count))
                ext3_msg(sb, KERN_WARNING,
                        "warning: maximal mount count reached, "
                        "running e2fsck is recommended");
@@ -1320,7 +1320,7 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
                    valid forever! :) */
        es->s_state &= cpu_to_le16(~EXT3_VALID_FS);
 #endif
-       if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
+       if (!le16_to_cpu(es->s_max_mnt_count))
                es->s_max_mnt_count = cpu_to_le16(EXT3_DFL_MAX_MNT_COUNT);
        le16_add_cpu(&es->s_mnt_count, 1);
        es->s_mtime = cpu_to_le32(get_seconds());
@@ -1647,7 +1647,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
         * Note: s_es must be initialized as soon as possible because
         *       some ext3 macro-instructions depend on its value
         */
-       es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);
+       es = (struct ext3_super_block *) (bh->b_data + offset);
        sbi->s_es = es;
        sb->s_magic = le16_to_cpu(es->s_magic);
        if (sb->s_magic != EXT3_SUPER_MAGIC)
@@ -1758,7 +1758,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                               "error: can't read superblock on 2nd try");
                        goto failed_mount;
                }
-               es = (struct ext3_super_block *)(((char *)bh->b_data) + offset);
+               es = (struct ext3_super_block *)(bh->b_data + offset);
                sbi->s_es = es;
                if (es->s_magic != cpu_to_le16(EXT3_SUPER_MAGIC)) {
                        ext3_msg(sb, KERN_ERR,
@@ -1857,13 +1857,13 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
                               le32_to_cpu(es->s_first_data_block) - 1)
                                       / EXT3_BLOCKS_PER_GROUP(sb)) + 1;
-       db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) /
-                  EXT3_DESC_PER_BLOCK(sb);
+       db_count = DIV_ROUND_UP(sbi->s_groups_count, EXT3_DESC_PER_BLOCK(sb));
        sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
                                    GFP_KERNEL);
        if (sbi->s_group_desc == NULL) {
                ext3_msg(sb, KERN_ERR,
                        "error: not enough memory");
+               ret = -ENOMEM;
                goto failed_mount;
        }
 
@@ -1951,6 +1951,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        }
        if (err) {
                ext3_msg(sb, KERN_ERR, "error: insufficient memory");
+               ret = err;
                goto failed_mount3;
        }
 
@@ -2159,7 +2160,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
                goto out_bdev;
        }
 
-       es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);
+       es = (struct ext3_super_block *) (bh->b_data + offset);
        if ((le16_to_cpu(es->s_magic) != EXT3_SUPER_MAGIC) ||
            !(le32_to_cpu(es->s_feature_incompat) &
              EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
@@ -2352,6 +2353,21 @@ static int ext3_commit_super(struct super_block *sb,
 
        if (!sbh)
                return error;
+
+       if (buffer_write_io_error(sbh)) {
+               /*
+                * Oh, dear.  A previous attempt to write the
+                * superblock failed.  This could happen because the
+                * USB device was yanked out.  Or it could happen to
+                * be a transient write error and maybe the block will
+                * be remapped.  Nothing we can do but to retry the
+                * write and hope for the best.
+                */
+               ext3_msg(sb, KERN_ERR, "previous I/O error to "
+                      "superblock detected");
+               clear_buffer_write_io_error(sbh);
+               set_buffer_uptodate(sbh);
+       }
        /*
         * If the file system is mounted read-only, don't update the
         * superblock write time.  This avoids updating the superblock
@@ -2368,8 +2384,15 @@ static int ext3_commit_super(struct super_block *sb,
        es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
        BUFFER_TRACE(sbh, "marking dirty");
        mark_buffer_dirty(sbh);
-       if (sync)
+       if (sync) {
                error = sync_dirty_buffer(sbh);
+               if (buffer_write_io_error(sbh)) {
+                       ext3_msg(sb, KERN_ERR, "I/O error while writing "
+                              "superblock");
+                       clear_buffer_write_io_error(sbh);
+                       set_buffer_uptodate(sbh);
+               }
+       }
        return error;
 }
 
index 05a38b9..e4b87bc 100644 (file)
@@ -221,7 +221,7 @@ restart:
                        goto restart;
                }
                if (buffer_locked(bh)) {
-                       atomic_inc(&bh->b_count);
+                       get_bh(bh);
                        spin_unlock(&journal->j_list_lock);
                        jbd_unlock_bh_state(bh);
                        wait_on_buffer(bh);
@@ -283,7 +283,7 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
        int ret = 0;
 
        if (buffer_locked(bh)) {
-               atomic_inc(&bh->b_count);
+               get_bh(bh);
                spin_unlock(&journal->j_list_lock);
                jbd_unlock_bh_state(bh);
                wait_on_buffer(bh);
index 85a6883..34a4861 100644 (file)
@@ -587,13 +587,13 @@ void journal_commit_transaction(journal_t *journal)
                /* Bump b_count to prevent truncate from stumbling over
                    the shadowed buffer!  @@@ This can go if we ever get
                    rid of the BJ_IO/BJ_Shadow pairing of buffers. */
-               atomic_inc(&jh2bh(jh)->b_count);
+               get_bh(jh2bh(jh));
 
                /* Make a temporary IO buffer with which to write it out
                    (this will requeue both the metadata buffer and the
                    temporary IO buffer). new_bh goes on BJ_IO*/
 
-               set_bit(BH_JWrite, &jh2bh(jh)->b_state);
+               set_buffer_jwrite(jh2bh(jh));
                /*
                 * akpm: journal_write_metadata_buffer() sets
                 * new_bh->b_transaction to commit_transaction.
@@ -603,7 +603,7 @@ void journal_commit_transaction(journal_t *journal)
                JBUFFER_TRACE(jh, "ph3: write metadata");
                flags = journal_write_metadata_buffer(commit_transaction,
                                                      jh, &new_jh, blocknr);
-               set_bit(BH_JWrite, &jh2bh(new_jh)->b_state);
+               set_buffer_jwrite(jh2bh(new_jh));
                wbuf[bufs++] = jh2bh(new_jh);
 
                /* Record the new block's tag in the current descriptor
@@ -713,7 +713,7 @@ wait_for_iobuf:
                    shadowed buffer */
                jh = commit_transaction->t_shadow_list->b_tprev;
                bh = jh2bh(jh);
-               clear_bit(BH_JWrite, &bh->b_state);
+               clear_buffer_jwrite(bh);
                J_ASSERT_BH(bh, buffer_jbddirty(bh));
 
                /* The metadata is now released for reuse, but we need
index 2c4b1f1..da1b5e4 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/poison.h>
 #include <linux/proc_fs.h>
 #include <linux/debugfs.h>
+#include <linux/ratelimit.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -84,6 +85,7 @@ EXPORT_SYMBOL(journal_force_commit);
 
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
+static const char *journal_dev_name(journal_t *journal, char *buffer);
 
 /*
  * Helper function used to manage commit timeouts
@@ -439,7 +441,7 @@ int __log_start_commit(journal_t *journal, tid_t target)
         */
        if (!tid_geq(journal->j_commit_request, target)) {
                /*
-                * We want a new commit: OK, mark the request and wakup the
+                * We want a new commit: OK, mark the request and wakeup the
                 * commit thread.  We do _not_ do the commit ourselves.
                 */
 
@@ -950,6 +952,8 @@ int journal_create(journal_t *journal)
                if (err)
                        return err;
                bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+               if (unlikely(!bh))
+                       return -ENOMEM;
                lock_buffer(bh);
                memset (bh->b_data, 0, journal->j_blocksize);
                BUFFER_TRACE(bh, "marking dirty");
@@ -1010,6 +1014,23 @@ void journal_update_superblock(journal_t *journal, int wait)
                goto out;
        }
 
+       if (buffer_write_io_error(bh)) {
+               char b[BDEVNAME_SIZE];
+               /*
+                * Oh, dear.  A previous attempt to write the journal
+                * superblock failed.  This could happen because the
+                * USB device was yanked out.  Or it could happen to
+                * be a transient write error and maybe the block will
+                * be remapped.  Nothing we can do but to retry the
+                * write and hope for the best.
+                */
+               printk(KERN_ERR "JBD: previous I/O error detected "
+                      "for journal superblock update for %s.\n",
+                      journal_dev_name(journal, b));
+               clear_buffer_write_io_error(bh);
+               set_buffer_uptodate(bh);
+       }
+
        spin_lock(&journal->j_state_lock);
        jbd_debug(1,"JBD: updating superblock (start %u, seq %d, errno %d)\n",
                  journal->j_tail, journal->j_tail_sequence, journal->j_errno);
@@ -1021,9 +1042,17 @@ void journal_update_superblock(journal_t *journal, int wait)
 
        BUFFER_TRACE(bh, "marking dirty");
        mark_buffer_dirty(bh);
-       if (wait)
+       if (wait) {
                sync_dirty_buffer(bh);
-       else
+               if (buffer_write_io_error(bh)) {
+                       char b[BDEVNAME_SIZE];
+                       printk(KERN_ERR "JBD: I/O error detected "
+                              "when updating journal superblock for %s.\n",
+                              journal_dev_name(journal, b));
+                       clear_buffer_write_io_error(bh);
+                       set_buffer_uptodate(bh);
+               }
+       } else
                write_dirty_buffer(bh, WRITE);
 
 out:
@@ -1719,7 +1748,6 @@ static void journal_destroy_journal_head_cache(void)
 static struct journal_head *journal_alloc_journal_head(void)
 {
        struct journal_head *ret;
-       static unsigned long last_warning;
 
 #ifdef CONFIG_JBD_DEBUG
        atomic_inc(&nr_journal_heads);
@@ -1727,11 +1755,9 @@ static struct journal_head *journal_alloc_journal_head(void)
        ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
        if (ret == NULL) {
                jbd_debug(1, "out of memory for journal_head\n");
-               if (time_after(jiffies, last_warning + 5*HZ)) {
-                       printk(KERN_NOTICE "ENOMEM in %s, retrying.\n",
-                              __func__);
-                       last_warning = jiffies;
-               }
+               printk_ratelimited(KERN_NOTICE "ENOMEM in %s, retrying.\n",
+                                  __func__);
+
                while (ret == NULL) {
                        yield();
                        ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
index 81051da..5b43e96 100644 (file)
@@ -296,10 +296,10 @@ int journal_skip_recovery(journal_t *journal)
 #ifdef CONFIG_JBD_DEBUG
                int dropped = info.end_transaction -
                              be32_to_cpu(journal->j_superblock->s_sequence);
-#endif
                jbd_debug(1,
                          "JBD: ignoring %d transaction%s from the journal.\n",
                          dropped, (dropped == 1) ? "" : "s");
+#endif
                journal->j_transaction_sequence = ++info.end_transaction;
        }
 
index 5ae71e7..846a3f3 100644 (file)
@@ -293,9 +293,7 @@ handle_t *journal_start(journal_t *journal, int nblocks)
                jbd_free_handle(handle);
                current->journal_info = NULL;
                handle = ERR_PTR(err);
-               goto out;
        }
-out:
        return handle;
 }
 
@@ -528,7 +526,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
        transaction = handle->h_transaction;
        journal = transaction->t_journal;
 
-       jbd_debug(5, "buffer_head %p, force_copy %d\n", jh, force_copy);
+       jbd_debug(5, "journal_head %p, force_copy %d\n", jh, force_copy);
 
        JBUFFER_TRACE(jh, "entry");
 repeat:
@@ -713,7 +711,7 @@ done:
                J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)),
                            "Possible IO failure.\n");
                page = jh2bh(jh)->b_page;
-               offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK;
+               offset = offset_in_page(jh2bh(jh)->b_data);
                source = kmap_atomic(page, KM_USER0);
                memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
                kunmap_atomic(source, KM_USER0);
index 13b0a92..538417c 100644 (file)
@@ -480,7 +480,7 @@ int __jbd2_log_start_commit(journal_t *journal, tid_t target)
         */
        if (!tid_geq(journal->j_commit_request, target)) {
                /*
-                * We want a new commit: OK, mark the request and wakup the
+                * We want a new commit: OK, mark the request and wakeup the
                 * commit thread.  We do _not_ do the commit ourselves.
                 */
 
index 3e21b1e..880fd98 100644 (file)
@@ -4,6 +4,7 @@
 
 config QUOTA
        bool "Quota support"
+       select QUOTACTL
        help
          If you say Y here, you will be able to set per user limits for disk
          usage (also called disk quotas). Currently, it works for the
@@ -65,8 +66,7 @@ config QFMT_V2
 
 config QUOTACTL
        bool
-       depends on XFS_QUOTA || QUOTA
-       default y
+       default n
 
 config QUOTACTL_COMPAT
        bool
index aad1316..0fed41e 100644 (file)
@@ -1386,6 +1386,9 @@ static void __dquot_initialize(struct inode *inode, int type)
                /* Avoid races with quotaoff() */
                if (!sb_has_quota_active(sb, cnt))
                        continue;
+               /* We could race with quotaon or dqget() could have failed */
+               if (!got[cnt])
+                       continue;
                if (!inode->i_dquot[cnt]) {
                        inode->i_dquot[cnt] = got[cnt];
                        got[cnt] = NULL;
@@ -1736,6 +1739,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
        qsize_t rsv_space = 0;
        struct dquot *transfer_from[MAXQUOTAS] = {};
        int cnt, ret = 0;
+       char is_valid[MAXQUOTAS] = {};
        char warntype_to[MAXQUOTAS];
        char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
 
@@ -1757,8 +1761,15 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
        space = cur_space + rsv_space;
        /* Build the transfer_from list and check the limits */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+               /*
+                * Skip changes for same uid or gid or for turned off quota-type.
+                */
                if (!transfer_to[cnt])
                        continue;
+               /* Avoid races with quotaoff() */
+               if (!sb_has_quota_active(inode->i_sb, cnt))
+                       continue;
+               is_valid[cnt] = 1;
                transfer_from[cnt] = inode->i_dquot[cnt];
                ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt);
                if (ret)
@@ -1772,12 +1783,8 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
         * Finally perform the needed transfer from transfer_from to transfer_to
         */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               /*
-                * Skip changes for same uid or gid or for turned off quota-type.
-                */
-               if (!transfer_to[cnt])
+               if (!is_valid[cnt])
                        continue;
-
                /* Due to IO error we might not have transfer_from[] structure */
                if (transfer_from[cnt]) {
                        warntype_from_inodes[cnt] =
@@ -1801,18 +1808,19 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
 
        mark_all_dquot_dirty(transfer_from);
        mark_all_dquot_dirty(transfer_to);
-       /* Pass back references to put */
-       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-               transfer_to[cnt] = transfer_from[cnt];
-warn:
        flush_warnings(transfer_to, warntype_to);
        flush_warnings(transfer_from, warntype_from_inodes);
        flush_warnings(transfer_from, warntype_from_space);
-       return ret;
+       /* Pass back references to put */
+       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+               if (is_valid[cnt])
+                       transfer_to[cnt] = transfer_from[cnt];
+       return 0;
 over_quota:
        spin_unlock(&dq_data_lock);
        up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
-       goto warn;
+       flush_warnings(transfer_to, warntype_to);
+       return ret;
 }
 EXPORT_SYMBOL(__dquot_transfer);
 
index 480f281..6100ec0 100644 (file)
@@ -22,6 +22,7 @@ config XFS_FS
 config XFS_QUOTA
        bool "XFS Quota support"
        depends on XFS_FS
+       select QUOTACTL
        help
          If you say Y here, you will be able to set limits for disk usage on
          a per user and/or a per group basis under XFS.  XFS considers quota