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 branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2:
configfs: Fix race between configfs_readdir() and configfs_d_iput()
configfs: Don't try to d_delete() negative dentries.
ocfs2/dlm: Target node death during resource migration leads to thread spin
ocfs2: Skip mount recovery for hard-ro mounts
ocfs2/cluster: Heartbeat mismatch message improved
ocfs2/cluster: Increase the live threshold for global heartbeat
ocfs2/dlm: Use negotiated o2dlm protocol version
ocfs2: skip existing hole when removing the last extent_rec in punching-hole codes.
ocfs2: Initialize data_ac (might be used uninitialized)

+96 -27
+32 -7
fs/configfs/dir.c
··· 53 53 static void configfs_d_iput(struct dentry * dentry, 54 54 struct inode * inode) 55 55 { 56 - struct configfs_dirent * sd = dentry->d_fsdata; 56 + struct configfs_dirent *sd = dentry->d_fsdata; 57 57 58 58 if (sd) { 59 59 BUG_ON(sd->s_dentry != dentry); 60 + /* Coordinate with configfs_readdir */ 61 + spin_lock(&configfs_dirent_lock); 60 62 sd->s_dentry = NULL; 63 + spin_unlock(&configfs_dirent_lock); 61 64 configfs_put(sd); 62 65 } 63 66 iput(inode); ··· 692 689 sd = child->d_fsdata; 693 690 sd->s_type |= CONFIGFS_USET_DEFAULT; 694 691 } else { 695 - d_delete(child); 692 + BUG_ON(child->d_inode); 693 + d_drop(child); 696 694 dput(child); 697 695 } 698 696 } ··· 1549 1545 struct configfs_dirent * parent_sd = dentry->d_fsdata; 1550 1546 struct configfs_dirent *cursor = filp->private_data; 1551 1547 struct list_head *p, *q = &cursor->s_sibling; 1552 - ino_t ino; 1548 + ino_t ino = 0; 1553 1549 int i = filp->f_pos; 1554 1550 1555 1551 switch (i) { ··· 1577 1573 struct configfs_dirent *next; 1578 1574 const char * name; 1579 1575 int len; 1576 + struct inode *inode = NULL; 1580 1577 1581 1578 next = list_entry(p, struct configfs_dirent, 1582 1579 s_sibling); ··· 1586 1581 1587 1582 name = configfs_get_name(next); 1588 1583 len = strlen(name); 1589 - if (next->s_dentry) 1590 - ino = next->s_dentry->d_inode->i_ino; 1591 - else 1584 + 1585 + /* 1586 + * We'll have a dentry and an inode for 1587 + * PINNED items and for open attribute 1588 + * files. We lock here to prevent a race 1589 + * with configfs_d_iput() clearing 1590 + * s_dentry before calling iput(). 1591 + * 1592 + * Why do we go to the trouble? If 1593 + * someone has an attribute file open, 1594 + * the inode number should match until 1595 + * they close it. Beyond that, we don't 1596 + * care. 1597 + */ 1598 + spin_lock(&configfs_dirent_lock); 1599 + dentry = next->s_dentry; 1600 + if (dentry) 1601 + inode = dentry->d_inode; 1602 + if (inode) 1603 + ino = inode->i_ino; 1604 + spin_unlock(&configfs_dirent_lock); 1605 + if (!inode) 1592 1606 ino = iunique(configfs_sb, 2); 1593 1607 1594 1608 if (filldir(dirent, name, len, filp->f_pos, ino, ··· 1707 1683 err = configfs_attach_group(sd->s_element, &group->cg_item, 1708 1684 dentry); 1709 1685 if (err) { 1710 - d_delete(dentry); 1686 + BUG_ON(dentry->d_inode); 1687 + d_drop(dentry); 1711 1688 dput(dentry); 1712 1689 } else { 1713 1690 spin_lock(&configfs_dirent_lock);
+43 -18
fs/ocfs2/cluster/heartbeat.c
··· 539 539 540 540 /* We want to make sure that nobody is heartbeating on top of us -- 541 541 * this will help detect an invalid configuration. */ 542 - static int o2hb_check_last_timestamp(struct o2hb_region *reg) 542 + static void o2hb_check_last_timestamp(struct o2hb_region *reg) 543 543 { 544 - int node_num, ret; 545 544 struct o2hb_disk_slot *slot; 546 545 struct o2hb_disk_heartbeat_block *hb_block; 546 + char *errstr; 547 547 548 - node_num = o2nm_this_node(); 549 - 550 - ret = 1; 551 - slot = &reg->hr_slots[node_num]; 548 + slot = &reg->hr_slots[o2nm_this_node()]; 552 549 /* Don't check on our 1st timestamp */ 553 - if (slot->ds_last_time) { 554 - hb_block = slot->ds_raw_block; 550 + if (!slot->ds_last_time) 551 + return; 555 552 556 - if (le64_to_cpu(hb_block->hb_seq) != slot->ds_last_time) 557 - ret = 0; 558 - } 553 + hb_block = slot->ds_raw_block; 554 + if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time && 555 + le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation && 556 + hb_block->hb_node == slot->ds_node_num) 557 + return; 559 558 560 - return ret; 559 + #define ERRSTR1 "Another node is heartbeating on device" 560 + #define ERRSTR2 "Heartbeat generation mismatch on device" 561 + #define ERRSTR3 "Heartbeat sequence mismatch on device" 562 + 563 + if (hb_block->hb_node != slot->ds_node_num) 564 + errstr = ERRSTR1; 565 + else if (le64_to_cpu(hb_block->hb_generation) != 566 + slot->ds_last_generation) 567 + errstr = ERRSTR2; 568 + else 569 + errstr = ERRSTR3; 570 + 571 + mlog(ML_ERROR, "%s (%s): expected(%u:0x%llx, 0x%llx), " 572 + "ondisk(%u:0x%llx, 0x%llx)\n", errstr, reg->hr_dev_name, 573 + slot->ds_node_num, (unsigned long long)slot->ds_last_generation, 574 + (unsigned long long)slot->ds_last_time, hb_block->hb_node, 575 + (unsigned long long)le64_to_cpu(hb_block->hb_generation), 576 + (unsigned long long)le64_to_cpu(hb_block->hb_seq)); 561 577 } 562 578 563 579 static inline void o2hb_prepare_block(struct o2hb_region *reg, ··· 999 983 /* With an up to date view of the slots, we can check that no 1000 984 * other node has been improperly configured to heartbeat in 1001 985 * our slot. */ 1002 - if (!o2hb_check_last_timestamp(reg)) 1003 - mlog(ML_ERROR, "Device \"%s\": another node is heartbeating " 1004 - "in our slot!\n", reg->hr_dev_name); 986 + o2hb_check_last_timestamp(reg); 1005 987 1006 988 /* fill in the proper info for our next heartbeat */ 1007 989 o2hb_prepare_block(reg, reg->hr_generation); ··· 1013 999 } 1014 1000 1015 1001 i = -1; 1016 - while((i = find_next_bit(configured_nodes, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { 1017 - 1002 + while((i = find_next_bit(configured_nodes, 1003 + O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { 1018 1004 change |= o2hb_check_slot(reg, &reg->hr_slots[i]); 1019 1005 } 1020 1006 ··· 1704 1690 struct file *filp = NULL; 1705 1691 struct inode *inode = NULL; 1706 1692 ssize_t ret = -EINVAL; 1693 + int live_threshold; 1707 1694 1708 1695 if (reg->hr_bdev) 1709 1696 goto out; ··· 1781 1766 * A node is considered live after it has beat LIVE_THRESHOLD 1782 1767 * times. We're not steady until we've given them a chance 1783 1768 * _after_ our first read. 1769 + * The default threshold is bare minimum so as to limit the delay 1770 + * during mounts. For global heartbeat, the threshold doubled for the 1771 + * first region. 1784 1772 */ 1785 - atomic_set(&reg->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); 1773 + live_threshold = O2HB_LIVE_THRESHOLD; 1774 + if (o2hb_global_heartbeat_active()) { 1775 + spin_lock(&o2hb_live_lock); 1776 + if (o2hb_pop_count(&o2hb_region_bitmap, O2NM_MAX_REGIONS) == 1) 1777 + live_threshold <<= 1; 1778 + spin_unlock(&o2hb_live_lock); 1779 + } 1780 + atomic_set(&reg->hr_steady_iterations, live_threshold + 1); 1786 1781 1787 1782 hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", 1788 1783 reg->hr_item.ci_name);
+1 -1
fs/ocfs2/dir.c
··· 2868 2868 bytes = blocks_wanted << sb->s_blocksize_bits; 2869 2869 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); 2870 2870 struct ocfs2_inode_info *oi = OCFS2_I(dir); 2871 - struct ocfs2_alloc_context *data_ac; 2871 + struct ocfs2_alloc_context *data_ac = NULL; 2872 2872 struct ocfs2_alloc_context *meta_ac = NULL; 2873 2873 struct buffer_head *dirdata_bh = NULL; 2874 2874 struct buffer_head *dx_root_bh = NULL;
+2 -1
fs/ocfs2/dlm/dlmdomain.c
··· 1614 1614 spin_unlock(&dlm->spinlock); 1615 1615 1616 1616 /* Support for global heartbeat and node info was added in 1.1 */ 1617 - if (dlm_protocol.pv_major > 1 || dlm_protocol.pv_minor > 0) { 1617 + if (dlm->dlm_locking_proto.pv_major > 1 || 1618 + dlm->dlm_locking_proto.pv_minor > 0) { 1618 1619 status = dlm_send_nodeinfo(dlm, ctxt->yes_resp_map); 1619 1620 if (status) { 1620 1621 mlog_errno(status);
+3
fs/ocfs2/dlm/dlmmaster.c
··· 2574 2574 res->state &= ~DLM_LOCK_RES_MIGRATING; 2575 2575 wake = 1; 2576 2576 spin_unlock(&res->spinlock); 2577 + if (dlm_is_host_down(ret)) 2578 + dlm_wait_for_node_death(dlm, target, 2579 + DLM_NODE_DEATH_WAIT_MAX); 2577 2580 goto leave; 2578 2581 } 2579 2582
+12
fs/ocfs2/file.c
··· 1607 1607 range = le32_to_cpu(rec->e_cpos) + ocfs2_rec_clusters(el, rec); 1608 1608 1609 1609 if (le32_to_cpu(rec->e_cpos) >= trunc_start) { 1610 + /* 1611 + * remove an entire extent record. 1612 + */ 1610 1613 *trunc_cpos = le32_to_cpu(rec->e_cpos); 1611 1614 /* 1612 1615 * Skip holes if any. ··· 1620 1617 *blkno = le64_to_cpu(rec->e_blkno); 1621 1618 *trunc_end = le32_to_cpu(rec->e_cpos); 1622 1619 } else if (range > trunc_start) { 1620 + /* 1621 + * remove a partial extent record, which means we're 1622 + * removing the last extent record. 1623 + */ 1623 1624 *trunc_cpos = trunc_start; 1625 + /* 1626 + * skip hole if any. 1627 + */ 1628 + if (range < *trunc_end) 1629 + *trunc_end = range; 1624 1630 *trunc_len = *trunc_end - trunc_start; 1625 1631 coff = trunc_start - le32_to_cpu(rec->e_cpos); 1626 1632 *blkno = le64_to_cpu(rec->e_blkno) +
+3
fs/ocfs2/journal.c
··· 1260 1260 { 1261 1261 struct ocfs2_journal *journal = osb->journal; 1262 1262 1263 + if (ocfs2_is_hard_readonly(osb)) 1264 + return; 1265 + 1263 1266 /* No need to queue up our truncate_log as regular cleanup will catch 1264 1267 * that */ 1265 1268 ocfs2_queue_recovery_completion(journal, osb->slot_num,