Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Jun 2009 19:11:57 +0000 (12:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Jun 2009 19:11:57 +0000 (12:11 -0700)
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2:
  ocfs2/net: Use wait_event() in o2net_send_message_vec()
  ocfs2: Adjust rightmost path in ocfs2_add_branch.
  ocfs2: fdatasync should skip unimportant metadata writeout
  ocfs2: Remove redundant gotos in ocfs2_mount_volume()
  ocfs2: Add statistics for the checksum and ecc operations.
  ocfs2 patch to track delayed orphan scan timer statistics
  ocfs2: timer to queue scan of all orphan slots
  ocfs2: Correct ordering of ip_alloc_sem and localloc locks for directories
  ocfs2: Fix possible deadlock in quota recovery
  ocfs2: Fix possible deadlock with quotas in ocfs2_setattr()
  ocfs2: Fix lock inversion in ocfs2_local_read_info()
  ocfs2: Fix possible deadlock in ocfs2_global_read_dquot()
  ocfs2: update comments in masklog.h
  ocfs2: Don't printk the error when listing too many xattrs.

1  2 
fs/ocfs2/super.c

diff --combined fs/ocfs2/super.c
index 201b40a441fe806073c03bbb9fcc046f6423def7,4e6b8e7c423d9552386c3489ff154f412dff1319..d33767f17ba39db14dc8725ca2494fcd6ee73222
@@@ -42,7 -42,6 +42,7 @@@
  #include <linux/mount.h>
  #include <linux/seq_file.h>
  #include <linux/quotaops.h>
 +#include <linux/smp_lock.h>
  
  #define MLOG_MASK_PREFIX ML_SUPER
  #include <cluster/masklog.h>
@@@ -119,14 -118,17 +119,16 @@@ static void ocfs2_release_system_inodes
  static int ocfs2_check_volume(struct ocfs2_super *osb);
  static int ocfs2_verify_volume(struct ocfs2_dinode *di,
                               struct buffer_head *bh,
-                              u32 sectsize);
+                              u32 sectsize,
+                              struct ocfs2_blockcheck_stats *stats);
  static int ocfs2_initialize_super(struct super_block *sb,
                                  struct buffer_head *bh,
-                                 int sector_size);
+                                 int sector_size,
+                                 struct ocfs2_blockcheck_stats *stats);
  static int ocfs2_get_sector(struct super_block *sb,
                            struct buffer_head **bh,
                            int block,
                            int sect_size);
 -static void ocfs2_write_super(struct super_block *sb);
  static struct inode *ocfs2_alloc_inode(struct super_block *sb);
  static void ocfs2_destroy_inode(struct inode *inode);
  static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend);
@@@ -141,6 -143,7 +143,6 @@@ static const struct super_operations oc
        .clear_inode    = ocfs2_clear_inode,
        .delete_inode   = ocfs2_delete_inode,
        .sync_fs        = ocfs2_sync_fs,
 -      .write_super    = ocfs2_write_super,
        .put_super      = ocfs2_put_super,
        .remount_fs     = ocfs2_remount,
        .show_options   = ocfs2_show_options,
@@@ -207,6 -210,7 +209,7 @@@ static int ocfs2_osb_dump(struct ocfs2_
        int i;
        struct ocfs2_cluster_connection *cconn = osb->cconn;
        struct ocfs2_recovery_map *rm = osb->recovery_map;
+       struct ocfs2_orphan_scan *os;
  
        out += snprintf(buf + out, len - out,
                        "%10s => Id: %-s  Uuid: %-s  Gen: 0x%X  Label: %-s\n",
                                i, osb->slot_recovery_generations[i]);
        }
  
+       os = &osb->osb_orphan_scan;
+       out += snprintf(buf + out, len - out, "Orphan Scan=> ");
+       out += snprintf(buf + out, len - out, "Local: %u  Global: %u ",
+                       os->os_count, os->os_seqno);
+       out += snprintf(buf + out, len - out, " Last Scan: %lu seconds ago\n",
+                       (get_seconds() - os->os_scantime.tv_sec));
        return out;
  }
  
@@@ -364,12 -375,24 +374,12 @@@ static struct file_operations ocfs2_osb
        .llseek =       generic_file_llseek,
  };
  
 -/*
 - * write_super and sync_fs ripped right out of ext3.
 - */
 -static void ocfs2_write_super(struct super_block *sb)
 -{
 -      if (mutex_trylock(&sb->s_lock) != 0)
 -              BUG();
 -      sb->s_dirt = 0;
 -}
 -
  static int ocfs2_sync_fs(struct super_block *sb, int wait)
  {
        int status;
        tid_t target;
        struct ocfs2_super *osb = OCFS2_SB(sb);
  
 -      sb->s_dirt = 0;
 -
        if (ocfs2_is_hard_readonly(osb))
                return -EROFS;
  
@@@ -582,8 -605,6 +592,8 @@@ static int ocfs2_remount(struct super_b
        struct mount_options parsed_options;
        struct ocfs2_super *osb = OCFS2_SB(sb);
  
 +      lock_kernel();
 +
        if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
                ret = -EINVAL;
                goto out;
@@@ -687,13 -708,13 +697,14 @@@ unlock_osb
                        ocfs2_set_journal_params(osb);
        }
  out:
 +      unlock_kernel();
        return ret;
  }
  
  static int ocfs2_sb_probe(struct super_block *sb,
                          struct buffer_head **bh,
-                         int *sector_size)
+                         int *sector_size,
+                         struct ocfs2_blockcheck_stats *stats)
  {
        int status, tmpstat;
        struct ocfs1_vol_disk_hdr *hdr;
        *bh = NULL;
  
        /* may be > 512 */
 -      *sector_size = bdev_hardsect_size(sb->s_bdev);
 +      *sector_size = bdev_logical_block_size(sb->s_bdev);
        if (*sector_size > OCFS2_MAX_BLOCKSIZE) {
                mlog(ML_ERROR, "Hardware sector size too large: %d (max=%d)\n",
                     *sector_size, OCFS2_MAX_BLOCKSIZE);
                        goto bail;
                }
                di = (struct ocfs2_dinode *) (*bh)->b_data;
-               status = ocfs2_verify_volume(di, *bh, blksize);
+               memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats));
+               status = ocfs2_verify_volume(di, *bh, blksize, stats);
                if (status >= 0)
                        goto bail;
                brelse(*bh);
@@@ -965,6 -987,7 +977,7 @@@ static int ocfs2_fill_super(struct supe
        struct ocfs2_super *osb = NULL;
        struct buffer_head *bh = NULL;
        char nodestr[8];
+       struct ocfs2_blockcheck_stats stats;
  
        mlog_entry("%p, %p, %i", sb, data, silent);
  
        }
  
        /* probe for superblock */
-       status = ocfs2_sb_probe(sb, &bh, &sector_size);
+       status = ocfs2_sb_probe(sb, &bh, &sector_size, &stats);
        if (status < 0) {
                mlog(ML_ERROR, "superblock probe failed!\n");
                goto read_super_error;
        }
  
-       status = ocfs2_initialize_super(sb, bh, sector_size);
+       status = ocfs2_initialize_super(sb, bh, sector_size, &stats);
        osb = OCFS2_SB(sb);
        if (status < 0) {
                mlog_errno(status);
                goto read_super_error;
        }
  
+       if (ocfs2_meta_ecc(osb)) {
+               status = ocfs2_blockcheck_stats_debugfs_install(
+                                               &osb->osb_ecc_stats,
+                                               osb->osb_debug_root);
+               if (status) {
+                       mlog(ML_ERROR,
+                            "Unable to create blockcheck statistics "
+                            "files\n");
+                       goto read_super_error;
+               }
+       }
        status = ocfs2_mount_volume(sb);
        if (osb->root_inode)
                inode = igrab(osb->root_inode);
@@@ -1540,13 -1575,9 +1565,13 @@@ static void ocfs2_put_super(struct supe
  {
        mlog_entry("(0x%p)\n", sb);
  
 +      lock_kernel();
 +
        ocfs2_sync_blockdev(sb);
        ocfs2_dismount_volume(sb, 0);
  
 +      unlock_kernel();
 +
        mlog_exit_void();
  }
  
@@@ -1760,13 -1791,8 +1785,8 @@@ static int ocfs2_mount_volume(struct su
        }
  
        status = ocfs2_truncate_log_init(osb);
-       if (status < 0) {
+       if (status < 0)
                mlog_errno(status);
-               goto leave;
-       }
-       if (ocfs2_mount_local(osb))
-               goto leave;
  
  leave:
        if (unlock_super)
@@@ -1796,6 -1822,8 +1816,8 @@@ static void ocfs2_dismount_volume(struc
  
        ocfs2_truncate_log_shutdown(osb);
  
+       ocfs2_orphan_scan_stop(osb);
        /* This will disable recovery and flush any recovery work. */
        ocfs2_recovery_exit(osb);
  
        if (osb->cconn)
                ocfs2_dlm_shutdown(osb, hangup_needed);
  
+       ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats);
        debugfs_remove(osb->osb_debug_root);
  
        if (hangup_needed)
@@@ -1880,7 -1909,8 +1903,8 @@@ static int ocfs2_setup_osb_uuid(struct 
  
  static int ocfs2_initialize_super(struct super_block *sb,
                                  struct buffer_head *bh,
-                                 int sector_size)
+                                 int sector_size,
+                                 struct ocfs2_blockcheck_stats *stats)
  {
        int status;
        int i, cbits, bbits;
        atomic_set(&osb->alloc_stats.bg_allocs, 0);
        atomic_set(&osb->alloc_stats.bg_extends, 0);
  
+       /* Copy the blockcheck stats from the superblock probe */
+       osb->osb_ecc_stats = *stats;
        ocfs2_init_node_maps(osb);
  
        snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
                goto bail;
        }
  
+       status = ocfs2_orphan_scan_init(osb);
+       if (status) {
+               mlog(ML_ERROR, "Unable to initialize delayed orphan scan\n");
+               mlog_errno(status);
+               goto bail;
+       }
        init_waitqueue_head(&osb->checkpoint_event);
        atomic_set(&osb->needs_checkpoint, 0);
  
@@@ -2169,7 -2209,8 +2203,8 @@@ bail
   */
  static int ocfs2_verify_volume(struct ocfs2_dinode *di,
                               struct buffer_head *bh,
-                              u32 blksz)
+                              u32 blksz,
+                              struct ocfs2_blockcheck_stats *stats)
  {
        int status = -EAGAIN;
  
                    OCFS2_FEATURE_INCOMPAT_META_ECC) {
                        status = ocfs2_block_check_validate(bh->b_data,
                                                            bh->b_size,
-                                                           &di->i_check);
+                                                           &di->i_check,
+                                                           stats);
                        if (status)
                                goto out;
                }