diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 15:11:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 15:11:57 -0400 |
commit | 300df7dc89cc276377fc020704e34875d5c473b6 (patch) | |
tree | 6b280000815b0562255cecf3da1a8c9597bce702 /fs/ocfs2/super.c | |
parent | 661adc423d70203a56723701aaf255e16950dfdb (diff) | |
parent | 9af0b38ff3f4f79c62dd909405b113bf7c1a23aa (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* '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.
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r-- | fs/ocfs2/super.c | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 201b40a441fe..d33767f17ba3 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -119,10 +119,12 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb); | |||
119 | static int ocfs2_check_volume(struct ocfs2_super *osb); | 119 | static int ocfs2_check_volume(struct ocfs2_super *osb); |
120 | static int ocfs2_verify_volume(struct ocfs2_dinode *di, | 120 | static int ocfs2_verify_volume(struct ocfs2_dinode *di, |
121 | struct buffer_head *bh, | 121 | struct buffer_head *bh, |
122 | u32 sectsize); | 122 | u32 sectsize, |
123 | struct ocfs2_blockcheck_stats *stats); | ||
123 | static int ocfs2_initialize_super(struct super_block *sb, | 124 | static int ocfs2_initialize_super(struct super_block *sb, |
124 | struct buffer_head *bh, | 125 | struct buffer_head *bh, |
125 | int sector_size); | 126 | int sector_size, |
127 | struct ocfs2_blockcheck_stats *stats); | ||
126 | static int ocfs2_get_sector(struct super_block *sb, | 128 | static int ocfs2_get_sector(struct super_block *sb, |
127 | struct buffer_head **bh, | 129 | struct buffer_head **bh, |
128 | int block, | 130 | int block, |
@@ -207,6 +209,7 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
207 | int i; | 209 | int i; |
208 | struct ocfs2_cluster_connection *cconn = osb->cconn; | 210 | struct ocfs2_cluster_connection *cconn = osb->cconn; |
209 | struct ocfs2_recovery_map *rm = osb->recovery_map; | 211 | struct ocfs2_recovery_map *rm = osb->recovery_map; |
212 | struct ocfs2_orphan_scan *os; | ||
210 | 213 | ||
211 | out += snprintf(buf + out, len - out, | 214 | out += snprintf(buf + out, len - out, |
212 | "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n", | 215 | "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n", |
@@ -308,6 +311,13 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
308 | i, osb->slot_recovery_generations[i]); | 311 | i, osb->slot_recovery_generations[i]); |
309 | } | 312 | } |
310 | 313 | ||
314 | os = &osb->osb_orphan_scan; | ||
315 | out += snprintf(buf + out, len - out, "Orphan Scan=> "); | ||
316 | out += snprintf(buf + out, len - out, "Local: %u Global: %u ", | ||
317 | os->os_count, os->os_seqno); | ||
318 | out += snprintf(buf + out, len - out, " Last Scan: %lu seconds ago\n", | ||
319 | (get_seconds() - os->os_scantime.tv_sec)); | ||
320 | |||
311 | return out; | 321 | return out; |
312 | } | 322 | } |
313 | 323 | ||
@@ -693,7 +703,8 @@ out: | |||
693 | 703 | ||
694 | static int ocfs2_sb_probe(struct super_block *sb, | 704 | static int ocfs2_sb_probe(struct super_block *sb, |
695 | struct buffer_head **bh, | 705 | struct buffer_head **bh, |
696 | int *sector_size) | 706 | int *sector_size, |
707 | struct ocfs2_blockcheck_stats *stats) | ||
697 | { | 708 | { |
698 | int status, tmpstat; | 709 | int status, tmpstat; |
699 | struct ocfs1_vol_disk_hdr *hdr; | 710 | struct ocfs1_vol_disk_hdr *hdr; |
@@ -759,7 +770,8 @@ static int ocfs2_sb_probe(struct super_block *sb, | |||
759 | goto bail; | 770 | goto bail; |
760 | } | 771 | } |
761 | di = (struct ocfs2_dinode *) (*bh)->b_data; | 772 | di = (struct ocfs2_dinode *) (*bh)->b_data; |
762 | status = ocfs2_verify_volume(di, *bh, blksize); | 773 | memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats)); |
774 | status = ocfs2_verify_volume(di, *bh, blksize, stats); | ||
763 | if (status >= 0) | 775 | if (status >= 0) |
764 | goto bail; | 776 | goto bail; |
765 | brelse(*bh); | 777 | brelse(*bh); |
@@ -965,6 +977,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
965 | struct ocfs2_super *osb = NULL; | 977 | struct ocfs2_super *osb = NULL; |
966 | struct buffer_head *bh = NULL; | 978 | struct buffer_head *bh = NULL; |
967 | char nodestr[8]; | 979 | char nodestr[8]; |
980 | struct ocfs2_blockcheck_stats stats; | ||
968 | 981 | ||
969 | mlog_entry("%p, %p, %i", sb, data, silent); | 982 | mlog_entry("%p, %p, %i", sb, data, silent); |
970 | 983 | ||
@@ -974,13 +987,13 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
974 | } | 987 | } |
975 | 988 | ||
976 | /* probe for superblock */ | 989 | /* probe for superblock */ |
977 | status = ocfs2_sb_probe(sb, &bh, §or_size); | 990 | status = ocfs2_sb_probe(sb, &bh, §or_size, &stats); |
978 | if (status < 0) { | 991 | if (status < 0) { |
979 | mlog(ML_ERROR, "superblock probe failed!\n"); | 992 | mlog(ML_ERROR, "superblock probe failed!\n"); |
980 | goto read_super_error; | 993 | goto read_super_error; |
981 | } | 994 | } |
982 | 995 | ||
983 | status = ocfs2_initialize_super(sb, bh, sector_size); | 996 | status = ocfs2_initialize_super(sb, bh, sector_size, &stats); |
984 | osb = OCFS2_SB(sb); | 997 | osb = OCFS2_SB(sb); |
985 | if (status < 0) { | 998 | if (status < 0) { |
986 | mlog_errno(status); | 999 | mlog_errno(status); |
@@ -1090,6 +1103,18 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
1090 | goto read_super_error; | 1103 | goto read_super_error; |
1091 | } | 1104 | } |
1092 | 1105 | ||
1106 | if (ocfs2_meta_ecc(osb)) { | ||
1107 | status = ocfs2_blockcheck_stats_debugfs_install( | ||
1108 | &osb->osb_ecc_stats, | ||
1109 | osb->osb_debug_root); | ||
1110 | if (status) { | ||
1111 | mlog(ML_ERROR, | ||
1112 | "Unable to create blockcheck statistics " | ||
1113 | "files\n"); | ||
1114 | goto read_super_error; | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1093 | status = ocfs2_mount_volume(sb); | 1118 | status = ocfs2_mount_volume(sb); |
1094 | if (osb->root_inode) | 1119 | if (osb->root_inode) |
1095 | inode = igrab(osb->root_inode); | 1120 | inode = igrab(osb->root_inode); |
@@ -1760,13 +1785,8 @@ static int ocfs2_mount_volume(struct super_block *sb) | |||
1760 | } | 1785 | } |
1761 | 1786 | ||
1762 | status = ocfs2_truncate_log_init(osb); | 1787 | status = ocfs2_truncate_log_init(osb); |
1763 | if (status < 0) { | 1788 | if (status < 0) |
1764 | mlog_errno(status); | 1789 | mlog_errno(status); |
1765 | goto leave; | ||
1766 | } | ||
1767 | |||
1768 | if (ocfs2_mount_local(osb)) | ||
1769 | goto leave; | ||
1770 | 1790 | ||
1771 | leave: | 1791 | leave: |
1772 | if (unlock_super) | 1792 | if (unlock_super) |
@@ -1796,6 +1816,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
1796 | 1816 | ||
1797 | ocfs2_truncate_log_shutdown(osb); | 1817 | ocfs2_truncate_log_shutdown(osb); |
1798 | 1818 | ||
1819 | ocfs2_orphan_scan_stop(osb); | ||
1820 | |||
1799 | /* This will disable recovery and flush any recovery work. */ | 1821 | /* This will disable recovery and flush any recovery work. */ |
1800 | ocfs2_recovery_exit(osb); | 1822 | ocfs2_recovery_exit(osb); |
1801 | 1823 | ||
@@ -1833,6 +1855,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
1833 | if (osb->cconn) | 1855 | if (osb->cconn) |
1834 | ocfs2_dlm_shutdown(osb, hangup_needed); | 1856 | ocfs2_dlm_shutdown(osb, hangup_needed); |
1835 | 1857 | ||
1858 | ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats); | ||
1836 | debugfs_remove(osb->osb_debug_root); | 1859 | debugfs_remove(osb->osb_debug_root); |
1837 | 1860 | ||
1838 | if (hangup_needed) | 1861 | if (hangup_needed) |
@@ -1880,7 +1903,8 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu | |||
1880 | 1903 | ||
1881 | static int ocfs2_initialize_super(struct super_block *sb, | 1904 | static int ocfs2_initialize_super(struct super_block *sb, |
1882 | struct buffer_head *bh, | 1905 | struct buffer_head *bh, |
1883 | int sector_size) | 1906 | int sector_size, |
1907 | struct ocfs2_blockcheck_stats *stats) | ||
1884 | { | 1908 | { |
1885 | int status; | 1909 | int status; |
1886 | int i, cbits, bbits; | 1910 | int i, cbits, bbits; |
@@ -1939,6 +1963,9 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1939 | atomic_set(&osb->alloc_stats.bg_allocs, 0); | 1963 | atomic_set(&osb->alloc_stats.bg_allocs, 0); |
1940 | atomic_set(&osb->alloc_stats.bg_extends, 0); | 1964 | atomic_set(&osb->alloc_stats.bg_extends, 0); |
1941 | 1965 | ||
1966 | /* Copy the blockcheck stats from the superblock probe */ | ||
1967 | osb->osb_ecc_stats = *stats; | ||
1968 | |||
1942 | ocfs2_init_node_maps(osb); | 1969 | ocfs2_init_node_maps(osb); |
1943 | 1970 | ||
1944 | snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", | 1971 | snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", |
@@ -1951,6 +1978,13 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1951 | goto bail; | 1978 | goto bail; |
1952 | } | 1979 | } |
1953 | 1980 | ||
1981 | status = ocfs2_orphan_scan_init(osb); | ||
1982 | if (status) { | ||
1983 | mlog(ML_ERROR, "Unable to initialize delayed orphan scan\n"); | ||
1984 | mlog_errno(status); | ||
1985 | goto bail; | ||
1986 | } | ||
1987 | |||
1954 | init_waitqueue_head(&osb->checkpoint_event); | 1988 | init_waitqueue_head(&osb->checkpoint_event); |
1955 | atomic_set(&osb->needs_checkpoint, 0); | 1989 | atomic_set(&osb->needs_checkpoint, 0); |
1956 | 1990 | ||
@@ -2169,7 +2203,8 @@ bail: | |||
2169 | */ | 2203 | */ |
2170 | static int ocfs2_verify_volume(struct ocfs2_dinode *di, | 2204 | static int ocfs2_verify_volume(struct ocfs2_dinode *di, |
2171 | struct buffer_head *bh, | 2205 | struct buffer_head *bh, |
2172 | u32 blksz) | 2206 | u32 blksz, |
2207 | struct ocfs2_blockcheck_stats *stats) | ||
2173 | { | 2208 | { |
2174 | int status = -EAGAIN; | 2209 | int status = -EAGAIN; |
2175 | 2210 | ||
@@ -2182,7 +2217,8 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, | |||
2182 | OCFS2_FEATURE_INCOMPAT_META_ECC) { | 2217 | OCFS2_FEATURE_INCOMPAT_META_ECC) { |
2183 | status = ocfs2_block_check_validate(bh->b_data, | 2218 | status = ocfs2_block_check_validate(bh->b_data, |
2184 | bh->b_size, | 2219 | bh->b_size, |
2185 | &di->i_check); | 2220 | &di->i_check, |
2221 | stats); | ||
2186 | if (status) | 2222 | if (status) |
2187 | goto out; | 2223 | goto out; |
2188 | } | 2224 | } |