Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes

* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes:
GFS2: remove dcache entries for remote deleted inodes
GFS2: Fix incorrent statfs consistency check
GFS2: Don't put unlikely reclaim candidates on the reclaim list.
GFS2: Don't try and dealloc own inode
GFS2: Fix panic in glock memory shrinker
GFS2: keep statfs info in sync on grows
GFS2: Shrink the shrinker

+195 -75
+39
fs/gfs2/aops.c
··· 624 624 { 625 625 struct gfs2_inode *ip = GFS2_I(mapping->host); 626 626 struct gfs2_sbd *sdp = GFS2_SB(mapping->host); 627 + struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 627 628 unsigned int data_blocks = 0, ind_blocks = 0, rblocks; 628 629 int alloc_required; 629 630 int error = 0; ··· 638 637 error = gfs2_glock_nq(&ip->i_gh); 639 638 if (unlikely(error)) 640 639 goto out_uninit; 640 + if (&ip->i_inode == sdp->sd_rindex) { 641 + error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 642 + GL_NOCACHE, &m_ip->i_gh); 643 + if (unlikely(error)) { 644 + gfs2_glock_dq(&ip->i_gh); 645 + goto out_uninit; 646 + } 647 + } 641 648 642 649 error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); 643 650 if (error) ··· 676 667 rblocks += data_blocks ? data_blocks : 1; 677 668 if (ind_blocks || data_blocks) 678 669 rblocks += RES_STATFS + RES_QUOTA; 670 + if (&ip->i_inode == sdp->sd_rindex) 671 + rblocks += 2 * RES_STATFS; 679 672 680 673 error = gfs2_trans_begin(sdp, rblocks, 681 674 PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize); ··· 723 712 gfs2_alloc_put(ip); 724 713 } 725 714 out_unlock: 715 + if (&ip->i_inode == sdp->sd_rindex) { 716 + gfs2_glock_dq(&m_ip->i_gh); 717 + gfs2_holder_uninit(&m_ip->i_gh); 718 + } 726 719 gfs2_glock_dq(&ip->i_gh); 727 720 out_uninit: 728 721 gfs2_holder_uninit(&ip->i_gh); ··· 740 725 static void adjust_fs_space(struct inode *inode) 741 726 { 742 727 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; 728 + struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 729 + struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); 743 730 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; 744 731 struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; 732 + struct buffer_head *m_bh, *l_bh; 745 733 u64 fs_total, new_free; 746 734 747 735 /* Total up the file system space, according to the latest rindex. */ 748 736 fs_total = gfs2_ri_total(sdp); 737 + if (gfs2_meta_inode_buffer(m_ip, &m_bh) != 0) 738 + return; 749 739 750 740 spin_lock(&sdp->sd_statfs_spin); 741 + gfs2_statfs_change_in(m_sc, m_bh->b_data + 742 + sizeof(struct gfs2_dinode)); 751 743 if (fs_total > (m_sc->sc_total + l_sc->sc_total)) 752 744 new_free = fs_total - (m_sc->sc_total + l_sc->sc_total); 753 745 else ··· 763 741 fs_warn(sdp, "File system extended by %llu blocks.\n", 764 742 (unsigned long long)new_free); 765 743 gfs2_statfs_change(sdp, new_free, new_free, 0); 744 + 745 + if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0) 746 + goto out; 747 + update_statfs(sdp, m_bh, l_bh); 748 + brelse(l_bh); 749 + out: 750 + brelse(m_bh); 766 751 } 767 752 768 753 /** ··· 792 763 { 793 764 struct gfs2_inode *ip = GFS2_I(inode); 794 765 struct gfs2_sbd *sdp = GFS2_SB(inode); 766 + struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 795 767 u64 to = pos + copied; 796 768 void *kaddr; 797 769 unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode); ··· 824 794 825 795 brelse(dibh); 826 796 gfs2_trans_end(sdp); 797 + if (inode == sdp->sd_rindex) { 798 + gfs2_glock_dq(&m_ip->i_gh); 799 + gfs2_holder_uninit(&m_ip->i_gh); 800 + } 827 801 gfs2_glock_dq(&ip->i_gh); 828 802 gfs2_holder_uninit(&ip->i_gh); 829 803 return copied; ··· 857 823 struct inode *inode = page->mapping->host; 858 824 struct gfs2_inode *ip = GFS2_I(inode); 859 825 struct gfs2_sbd *sdp = GFS2_SB(inode); 826 + struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 860 827 struct buffer_head *dibh; 861 828 struct gfs2_alloc *al = ip->i_alloc; 862 829 unsigned int from = pos & (PAGE_CACHE_SIZE - 1); ··· 899 864 gfs2_inplace_release(ip); 900 865 gfs2_quota_unlock(ip); 901 866 gfs2_alloc_put(ip); 867 + } 868 + if (inode == sdp->sd_rindex) { 869 + gfs2_glock_dq(&m_ip->i_gh); 870 + gfs2_holder_uninit(&m_ip->i_gh); 902 871 } 903 872 gfs2_glock_dq(&ip->i_gh); 904 873 gfs2_holder_uninit(&ip->i_gh);
+91 -47
fs/gfs2/glock.c
··· 63 63 static DECLARE_RWSEM(gfs2_umount_flush_sem); 64 64 static struct dentry *gfs2_root; 65 65 static struct workqueue_struct *glock_workqueue; 66 + struct workqueue_struct *gfs2_delete_workqueue; 66 67 static LIST_HEAD(lru_list); 67 68 static atomic_t lru_count = ATOMIC_INIT(0); 68 69 static DEFINE_SPINLOCK(lru_lock); ··· 168 167 * 169 168 */ 170 169 171 - static void gfs2_glock_hold(struct gfs2_glock *gl) 170 + void gfs2_glock_hold(struct gfs2_glock *gl) 172 171 { 173 172 GLOCK_BUG_ON(gl, atomic_read(&gl->gl_ref) == 0); 174 173 atomic_inc(&gl->gl_ref); 174 + } 175 + 176 + /** 177 + * demote_ok - Check to see if it's ok to unlock a glock 178 + * @gl: the glock 179 + * 180 + * Returns: 1 if it's ok 181 + */ 182 + 183 + static int demote_ok(const struct gfs2_glock *gl) 184 + { 185 + const struct gfs2_glock_operations *glops = gl->gl_ops; 186 + 187 + if (gl->gl_state == LM_ST_UNLOCKED) 188 + return 0; 189 + if (!list_empty(&gl->gl_holders)) 190 + return 0; 191 + if (glops->go_demote_ok) 192 + return glops->go_demote_ok(gl); 193 + return 1; 175 194 } 176 195 177 196 /** ··· 202 181 203 182 static void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl) 204 183 { 184 + int may_reclaim; 185 + may_reclaim = (demote_ok(gl) && 186 + (atomic_read(&gl->gl_ref) == 1 || 187 + (gl->gl_name.ln_type == LM_TYPE_INODE && 188 + atomic_read(&gl->gl_ref) <= 2))); 205 189 spin_lock(&lru_lock); 206 - if (list_empty(&gl->gl_lru) && gl->gl_state != LM_ST_UNLOCKED) { 190 + if (list_empty(&gl->gl_lru) && may_reclaim) { 207 191 list_add_tail(&gl->gl_lru, &lru_list); 208 192 atomic_inc(&lru_count); 209 193 } 210 194 spin_unlock(&lru_lock); 195 + } 196 + 197 + /** 198 + * gfs2_glock_put_nolock() - Decrement reference count on glock 199 + * @gl: The glock to put 200 + * 201 + * This function should only be used if the caller has its own reference 202 + * to the glock, in addition to the one it is dropping. 203 + */ 204 + 205 + void gfs2_glock_put_nolock(struct gfs2_glock *gl) 206 + { 207 + if (atomic_dec_and_test(&gl->gl_ref)) 208 + GLOCK_BUG_ON(gl, 1); 209 + gfs2_glock_schedule_for_reclaim(gl); 211 210 } 212 211 213 212 /** ··· 255 214 rv = 1; 256 215 goto out; 257 216 } 258 - /* 1 for being hashed, 1 for having state != LM_ST_UNLOCKED */ 259 - if (atomic_read(&gl->gl_ref) == 2) 260 - gfs2_glock_schedule_for_reclaim(gl); 217 + spin_lock(&gl->gl_spin); 218 + gfs2_glock_schedule_for_reclaim(gl); 219 + spin_unlock(&gl->gl_spin); 261 220 write_unlock(gl_lock_addr(gl->gl_hash)); 262 221 out: 263 222 return rv; ··· 439 398 if (held2) 440 399 gfs2_glock_hold(gl); 441 400 else 442 - gfs2_glock_put(gl); 401 + gfs2_glock_put_nolock(gl); 443 402 } 444 403 445 404 gl->gl_state = new_state; ··· 674 633 out_sched: 675 634 gfs2_glock_hold(gl); 676 635 if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) 677 - gfs2_glock_put(gl); 636 + gfs2_glock_put_nolock(gl); 678 637 out_unlock: 679 638 clear_bit(GLF_LOCK, &gl->gl_flags); 680 639 goto out; 640 + } 641 + 642 + static void delete_work_func(struct work_struct *work) 643 + { 644 + struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete); 645 + struct gfs2_sbd *sdp = gl->gl_sbd; 646 + struct gfs2_inode *ip = NULL; 647 + struct inode *inode; 648 + u64 no_addr = 0; 649 + 650 + spin_lock(&gl->gl_spin); 651 + ip = (struct gfs2_inode *)gl->gl_object; 652 + if (ip) 653 + no_addr = ip->i_no_addr; 654 + spin_unlock(&gl->gl_spin); 655 + if (ip) { 656 + inode = gfs2_ilookup(sdp->sd_vfs, no_addr); 657 + if (inode) { 658 + d_prune_aliases(inode); 659 + iput(inode); 660 + } 661 + } 662 + gfs2_glock_put(gl); 681 663 } 682 664 683 665 static void glock_work_func(struct work_struct *work) ··· 781 717 gl->gl_sbd = sdp; 782 718 gl->gl_aspace = NULL; 783 719 INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); 720 + INIT_WORK(&gl->gl_delete, delete_work_func); 784 721 785 722 /* If this glock protects actual on-disk data or metadata blocks, 786 723 create a VFS inode to manage the pages/buffers holding them. */ ··· 923 858 gl->gl_demote_state != state) { 924 859 gl->gl_demote_state = LM_ST_UNLOCKED; 925 860 } 861 + if (gl->gl_ops->go_callback) 862 + gl->gl_ops->go_callback(gl); 926 863 trace_gfs2_demote_rq(gl); 927 864 } 928 865 ··· 1341 1274 gfs2_glock_put(gl); 1342 1275 } 1343 1276 1344 - /** 1345 - * demote_ok - Check to see if it's ok to unlock a glock 1346 - * @gl: the glock 1347 - * 1348 - * Returns: 1 if it's ok 1349 - */ 1350 - 1351 - static int demote_ok(const struct gfs2_glock *gl) 1352 - { 1353 - const struct gfs2_glock_operations *glops = gl->gl_ops; 1354 - 1355 - if (gl->gl_state == LM_ST_UNLOCKED) 1356 - return 0; 1357 - if (!list_empty(&gl->gl_holders)) 1358 - return 0; 1359 - if (glops->go_demote_ok) 1360 - return glops->go_demote_ok(gl); 1361 - return 1; 1362 - } 1363 - 1364 1277 1365 1278 static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask) 1366 1279 { 1367 1280 struct gfs2_glock *gl; 1368 1281 int may_demote; 1369 1282 int nr_skipped = 0; 1370 - int got_ref = 0; 1371 1283 LIST_HEAD(skipped); 1372 1284 1373 1285 if (nr == 0) ··· 1361 1315 list_del_init(&gl->gl_lru); 1362 1316 atomic_dec(&lru_count); 1363 1317 1318 + /* Check if glock is about to be freed */ 1319 + if (atomic_read(&gl->gl_ref) == 0) 1320 + continue; 1321 + 1364 1322 /* Test for being demotable */ 1365 1323 if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { 1366 1324 gfs2_glock_hold(gl); 1367 - got_ref = 1; 1368 1325 spin_unlock(&lru_lock); 1369 1326 spin_lock(&gl->gl_spin); 1370 1327 may_demote = demote_ok(gl); 1371 - spin_unlock(&gl->gl_spin); 1372 - clear_bit(GLF_LOCK, &gl->gl_flags); 1373 1328 if (may_demote) { 1374 1329 handle_callback(gl, LM_ST_UNLOCKED, 0); 1375 1330 nr--; 1376 - if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) 1377 - gfs2_glock_put(gl); 1378 - got_ref = 0; 1379 1331 } 1332 + if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) 1333 + gfs2_glock_put_nolock(gl); 1334 + spin_unlock(&gl->gl_spin); 1335 + clear_bit(GLF_LOCK, &gl->gl_flags); 1380 1336 spin_lock(&lru_lock); 1381 - if (may_demote) 1382 - continue; 1337 + continue; 1383 1338 } 1384 - if (list_empty(&gl->gl_lru) && 1385 - (atomic_read(&gl->gl_ref) <= (2 + got_ref))) { 1386 - nr_skipped++; 1387 - list_add(&gl->gl_lru, &skipped); 1388 - } 1389 - if (got_ref) { 1390 - spin_unlock(&lru_lock); 1391 - gfs2_glock_put(gl); 1392 - spin_lock(&lru_lock); 1393 - got_ref = 0; 1394 - } 1339 + nr_skipped++; 1340 + list_add(&gl->gl_lru, &skipped); 1395 1341 } 1396 1342 list_splice(&skipped, &lru_list); 1397 1343 atomic_add(nr_skipped, &lru_count); ··· 1765 1727 glock_workqueue = create_workqueue("glock_workqueue"); 1766 1728 if (IS_ERR(glock_workqueue)) 1767 1729 return PTR_ERR(glock_workqueue); 1730 + gfs2_delete_workqueue = create_workqueue("delete_workqueue"); 1731 + if (IS_ERR(gfs2_delete_workqueue)) { 1732 + destroy_workqueue(glock_workqueue); 1733 + return PTR_ERR(gfs2_delete_workqueue); 1734 + } 1768 1735 1769 1736 register_shrinker(&glock_shrinker); 1770 1737 ··· 1780 1737 { 1781 1738 unregister_shrinker(&glock_shrinker); 1782 1739 destroy_workqueue(glock_workqueue); 1740 + destroy_workqueue(gfs2_delete_workqueue); 1783 1741 } 1784 1742 1785 1743 static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
+3
fs/gfs2/glock.h
··· 143 143 144 144 #define GLR_TRYFAILED 13 145 145 146 + extern struct workqueue_struct *gfs2_delete_workqueue; 146 147 static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl) 147 148 { 148 149 struct gfs2_holder *gh; ··· 192 191 int gfs2_glock_get(struct gfs2_sbd *sdp, 193 192 u64 number, const struct gfs2_glock_operations *glops, 194 193 int create, struct gfs2_glock **glp); 194 + void gfs2_glock_hold(struct gfs2_glock *gl); 195 + void gfs2_glock_put_nolock(struct gfs2_glock *gl); 195 196 int gfs2_glock_put(struct gfs2_glock *gl); 196 197 void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags, 197 198 struct gfs2_holder *gh);
+21
fs/gfs2/glops.c
··· 323 323 324 324 if (gl->gl_state != LM_ST_UNLOCKED && 325 325 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { 326 + flush_workqueue(gfs2_delete_workqueue); 326 327 gfs2_meta_syncfs(sdp); 327 328 gfs2_log_shutdown(sdp); 328 329 } ··· 373 372 return 0; 374 373 } 375 374 375 + /** 376 + * iopen_go_callback - schedule the dcache entry for the inode to be deleted 377 + * @gl: the glock 378 + * 379 + * gl_spin lock is held while calling this 380 + */ 381 + static void iopen_go_callback(struct gfs2_glock *gl) 382 + { 383 + struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object; 384 + 385 + if (gl->gl_demote_state == LM_ST_UNLOCKED && 386 + gl->gl_state == LM_ST_SHARED && 387 + ip && test_bit(GIF_USER, &ip->i_flags)) { 388 + gfs2_glock_hold(gl); 389 + if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) 390 + gfs2_glock_put_nolock(gl); 391 + } 392 + } 393 + 376 394 const struct gfs2_glock_operations gfs2_meta_glops = { 377 395 .go_type = LM_TYPE_META, 378 396 }; ··· 426 406 427 407 const struct gfs2_glock_operations gfs2_iopen_glops = { 428 408 .go_type = LM_TYPE_IOPEN, 409 + .go_callback = iopen_go_callback, 429 410 }; 430 411 431 412 const struct gfs2_glock_operations gfs2_flock_glops = {
+2
fs/gfs2/incore.h
··· 159 159 int (*go_lock) (struct gfs2_holder *gh); 160 160 void (*go_unlock) (struct gfs2_holder *gh); 161 161 int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); 162 + void (*go_callback) (struct gfs2_glock *gl); 162 163 const int go_type; 163 164 const unsigned long go_min_hold_time; 164 165 }; ··· 229 228 struct list_head gl_ail_list; 230 229 atomic_t gl_ail_count; 231 230 struct delayed_work gl_work; 231 + struct work_struct gl_delete; 232 232 }; 233 233 234 234 #define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */
+9 -14
fs/gfs2/rgrp.c
··· 285 285 } 286 286 287 287 tmp = rgd->rd_data - rgd->rd_free - rgd->rd_dinodes; 288 - if (count[1] + count[2] != tmp) { 288 + if (count[1] != tmp) { 289 289 if (gfs2_consist_rgrpd(rgd)) 290 290 fs_err(sdp, "used data mismatch: %u != %u\n", 291 291 count[1], tmp); 292 292 return; 293 293 } 294 294 295 - if (count[3] != rgd->rd_dinodes) { 295 + if (count[2] + count[3] != rgd->rd_dinodes) { 296 296 if (gfs2_consist_rgrpd(rgd)) 297 297 fs_err(sdp, "used metadata mismatch: %u != %u\n", 298 - count[3], rgd->rd_dinodes); 298 + count[2] + count[3], rgd->rd_dinodes); 299 299 return; 300 300 } 301 - 302 - if (count[2] > count[3]) { 303 - if (gfs2_consist_rgrpd(rgd)) 304 - fs_err(sdp, "unlinked inodes > inodes: %u\n", 305 - count[2]); 306 - return; 307 - } 308 - 309 301 } 310 302 311 303 static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block) ··· 953 961 * Returns: The inode, if one has been found 954 962 */ 955 963 956 - static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) 964 + static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, 965 + u64 skip) 957 966 { 958 967 struct inode *inode; 959 968 u32 goal = 0, block; ··· 977 984 no_addr = block + rgd->rd_data0; 978 985 goal++; 979 986 if (*last_unlinked != NO_BLOCK && no_addr <= *last_unlinked) 987 + continue; 988 + if (no_addr == skip) 980 989 continue; 981 990 *last_unlinked = no_addr; 982 991 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, ··· 1099 1104 if (try_rgrp_fit(rgd, al)) 1100 1105 goto out; 1101 1106 if (rgd->rd_flags & GFS2_RDF_CHECK) 1102 - inode = try_rgrp_unlink(rgd, last_unlinked); 1107 + inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); 1103 1108 if (!rg_locked) 1104 1109 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1105 1110 if (inode) ··· 1133 1138 if (try_rgrp_fit(rgd, al)) 1134 1139 goto out; 1135 1140 if (rgd->rd_flags & GFS2_RDF_CHECK) 1136 - inode = try_rgrp_unlink(rgd, last_unlinked); 1141 + inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); 1137 1142 if (!rg_locked) 1138 1143 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1139 1144 if (inode)
+26 -14
fs/gfs2/super.c
··· 353 353 return error; 354 354 } 355 355 356 - static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) 356 + void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) 357 357 { 358 358 const struct gfs2_statfs_change *str = buf; 359 359 ··· 441 441 brelse(l_bh); 442 442 } 443 443 444 + void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, 445 + struct buffer_head *l_bh) 446 + { 447 + struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 448 + struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); 449 + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; 450 + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; 451 + 452 + gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); 453 + 454 + spin_lock(&sdp->sd_statfs_spin); 455 + m_sc->sc_total += l_sc->sc_total; 456 + m_sc->sc_free += l_sc->sc_free; 457 + m_sc->sc_dinodes += l_sc->sc_dinodes; 458 + memset(l_sc, 0, sizeof(struct gfs2_statfs_change)); 459 + memset(l_bh->b_data + sizeof(struct gfs2_dinode), 460 + 0, sizeof(struct gfs2_statfs_change)); 461 + spin_unlock(&sdp->sd_statfs_spin); 462 + 463 + gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); 464 + gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); 465 + } 466 + 444 467 int gfs2_statfs_sync(struct gfs2_sbd *sdp) 445 468 { 446 469 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); ··· 500 477 if (error) 501 478 goto out_bh2; 502 479 503 - gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); 504 - 505 - spin_lock(&sdp->sd_statfs_spin); 506 - m_sc->sc_total += l_sc->sc_total; 507 - m_sc->sc_free += l_sc->sc_free; 508 - m_sc->sc_dinodes += l_sc->sc_dinodes; 509 - memset(l_sc, 0, sizeof(struct gfs2_statfs_change)); 510 - memset(l_bh->b_data + sizeof(struct gfs2_dinode), 511 - 0, sizeof(struct gfs2_statfs_change)); 512 - spin_unlock(&sdp->sd_statfs_spin); 513 - 514 - gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); 515 - gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); 480 + update_statfs(sdp, m_bh, l_bh); 516 481 517 482 gfs2_trans_end(sdp); 518 483 ··· 691 680 struct gfs2_holder t_gh; 692 681 int error; 693 682 683 + flush_workqueue(gfs2_delete_workqueue); 694 684 gfs2_quota_sync(sdp); 695 685 gfs2_statfs_sync(sdp); 696 686
+4
fs/gfs2/super.h
··· 40 40 extern int gfs2_statfs_init(struct gfs2_sbd *sdp); 41 41 extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, 42 42 s64 dinodes); 43 + extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, 44 + const void *buf); 45 + extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, 46 + struct buffer_head *l_bh); 43 47 extern int gfs2_statfs_sync(struct gfs2_sbd *sdp); 44 48 45 49 extern int gfs2_freeze_fs(struct gfs2_sbd *sdp);