Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/mfasheh/ocfs2

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/mfasheh/ocfs2:
ocfs2_dlm: Add missing locks in dlm_empty_lockres
ocfs2_dlm: Missing get/put lockres in dlm_run_purge_lockres
configfs: add missing mutex_unlock()
ocfs2: add some missing address space callbacks
ocfs2: Concurrent access of o2hb_region->hr_task was not locked
ocfs2: Proper cleanup in case of error in ocfs2_register_hb_callbacks()

+84 -54
+12 -15
fs/configfs/dir.c
··· 1141 1141 1142 1142 err = -ENOMEM; 1143 1143 dentry = d_alloc(configfs_sb->s_root, &name); 1144 - if (!dentry) 1145 - goto out_release; 1144 + if (dentry) { 1145 + d_add(dentry, NULL); 1146 1146 1147 - d_add(dentry, NULL); 1148 - 1149 - err = configfs_attach_group(sd->s_element, &group->cg_item, 1150 - dentry); 1151 - if (!err) 1152 - dentry = NULL; 1153 - else 1154 - d_delete(dentry); 1147 + err = configfs_attach_group(sd->s_element, &group->cg_item, 1148 + dentry); 1149 + if (err) { 1150 + d_delete(dentry); 1151 + dput(dentry); 1152 + } 1153 + } 1155 1154 1156 1155 mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); 1157 1156 1158 - if (dentry) { 1159 - dput(dentry); 1160 - out_release: 1161 - unlink_group(group); 1162 - configfs_release_fs(); 1157 + if (err) { 1158 + unlink_group(group); 1159 + configfs_release_fs(); 1163 1160 } 1164 1161 1165 1162 return err;
+25 -1
fs/ocfs2/aops.c
··· 614 614 ocfs2_rw_unlock(inode, 0); 615 615 } 616 616 617 + /* 618 + * ocfs2_invalidatepage() and ocfs2_releasepage() are shamelessly stolen 619 + * from ext3. PageChecked() bits have been removed as OCFS2 does not 620 + * do journalled data. 621 + */ 622 + static void ocfs2_invalidatepage(struct page *page, unsigned long offset) 623 + { 624 + journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; 625 + 626 + journal_invalidatepage(journal, page, offset); 627 + } 628 + 629 + static int ocfs2_releasepage(struct page *page, gfp_t wait) 630 + { 631 + journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; 632 + 633 + if (!page_has_buffers(page)) 634 + return 0; 635 + return journal_try_to_free_buffers(journal, page, wait); 636 + } 637 + 617 638 static ssize_t ocfs2_direct_IO(int rw, 618 639 struct kiocb *iocb, 619 640 const struct iovec *iov, ··· 682 661 .commit_write = ocfs2_commit_write, 683 662 .bmap = ocfs2_bmap, 684 663 .sync_page = block_sync_page, 685 - .direct_IO = ocfs2_direct_IO 664 + .direct_IO = ocfs2_direct_IO, 665 + .invalidatepage = ocfs2_invalidatepage, 666 + .releasepage = ocfs2_releasepage, 667 + .migratepage = buffer_migrate_page, 686 668 };
+34 -16
fs/ocfs2/cluster/heartbeat.c
··· 1234 1234 const char *page, 1235 1235 size_t count) 1236 1236 { 1237 + struct task_struct *hb_task; 1237 1238 long fd; 1238 1239 int sectsize; 1239 1240 char *p = (char *)page; ··· 1320 1319 */ 1321 1320 atomic_set(&reg->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); 1322 1321 1323 - reg->hr_task = kthread_run(o2hb_thread, reg, "o2hb-%s", 1324 - reg->hr_item.ci_name); 1325 - if (IS_ERR(reg->hr_task)) { 1326 - ret = PTR_ERR(reg->hr_task); 1322 + hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", 1323 + reg->hr_item.ci_name); 1324 + if (IS_ERR(hb_task)) { 1325 + ret = PTR_ERR(hb_task); 1327 1326 mlog_errno(ret); 1328 - reg->hr_task = NULL; 1329 1327 goto out; 1330 1328 } 1329 + 1330 + spin_lock(&o2hb_live_lock); 1331 + reg->hr_task = hb_task; 1332 + spin_unlock(&o2hb_live_lock); 1331 1333 1332 1334 ret = wait_event_interruptible(o2hb_steady_queue, 1333 1335 atomic_read(&reg->hr_steady_iterations) == 0); 1334 1336 if (ret) { 1335 - kthread_stop(reg->hr_task); 1337 + spin_lock(&o2hb_live_lock); 1338 + hb_task = reg->hr_task; 1336 1339 reg->hr_task = NULL; 1340 + spin_unlock(&o2hb_live_lock); 1341 + 1342 + if (hb_task) 1343 + kthread_stop(hb_task); 1337 1344 goto out; 1338 1345 } 1339 1346 ··· 1363 1354 static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, 1364 1355 char *page) 1365 1356 { 1366 - if (!reg->hr_task) 1357 + pid_t pid = 0; 1358 + 1359 + spin_lock(&o2hb_live_lock); 1360 + if (reg->hr_task) 1361 + pid = reg->hr_task->pid; 1362 + spin_unlock(&o2hb_live_lock); 1363 + 1364 + if (!pid) 1367 1365 return 0; 1368 1366 1369 - return sprintf(page, "%u\n", reg->hr_task->pid); 1367 + return sprintf(page, "%u\n", pid); 1370 1368 } 1371 1369 1372 1370 struct o2hb_region_attribute { ··· 1511 1495 static void o2hb_heartbeat_group_drop_item(struct config_group *group, 1512 1496 struct config_item *item) 1513 1497 { 1498 + struct task_struct *hb_task; 1514 1499 struct o2hb_region *reg = to_o2hb_region(item); 1515 1500 1516 1501 /* stop the thread when the user removes the region dir */ 1517 - if (reg->hr_task) { 1518 - kthread_stop(reg->hr_task); 1519 - reg->hr_task = NULL; 1520 - } 1502 + spin_lock(&o2hb_live_lock); 1503 + hb_task = reg->hr_task; 1504 + reg->hr_task = NULL; 1505 + spin_unlock(&o2hb_live_lock); 1506 + 1507 + if (hb_task) 1508 + kthread_stop(hb_task); 1521 1509 1522 1510 config_item_put(item); 1523 1511 } ··· 1702 1682 } 1703 1683 EXPORT_SYMBOL_GPL(o2hb_register_callback); 1704 1684 1705 - int o2hb_unregister_callback(struct o2hb_callback_func *hc) 1685 + void o2hb_unregister_callback(struct o2hb_callback_func *hc) 1706 1686 { 1707 1687 BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); 1708 1688 ··· 1710 1690 __builtin_return_address(0), hc); 1711 1691 1712 1692 if (list_empty(&hc->hc_item)) 1713 - return 0; 1693 + return; 1714 1694 1715 1695 down_write(&o2hb_callback_sem); 1716 1696 1717 1697 list_del_init(&hc->hc_item); 1718 1698 1719 1699 up_write(&o2hb_callback_sem); 1720 - 1721 - return 0; 1722 1700 } 1723 1701 EXPORT_SYMBOL_GPL(o2hb_unregister_callback); 1724 1702
+1 -1
fs/ocfs2/cluster/heartbeat.h
··· 70 70 void *data, 71 71 int priority); 72 72 int o2hb_register_callback(struct o2hb_callback_func *hc); 73 - int o2hb_unregister_callback(struct o2hb_callback_func *hc); 73 + void o2hb_unregister_callback(struct o2hb_callback_func *hc); 74 74 void o2hb_fill_node_map(unsigned long *map, 75 75 unsigned bytes); 76 76 void o2hb_init(void);
+2 -11
fs/ocfs2/cluster/tcp.c
··· 1638 1638 1639 1639 void o2net_unregister_hb_callbacks(void) 1640 1640 { 1641 - int ret; 1642 - 1643 - ret = o2hb_unregister_callback(&o2net_hb_up); 1644 - if (ret < 0) 1645 - mlog(ML_ERROR, "Status return %d unregistering heartbeat up " 1646 - "callback!\n", ret); 1647 - 1648 - ret = o2hb_unregister_callback(&o2net_hb_down); 1649 - if (ret < 0) 1650 - mlog(ML_ERROR, "Status return %d unregistering heartbeat down " 1651 - "callback!\n", ret); 1641 + o2hb_unregister_callback(&o2net_hb_up); 1642 + o2hb_unregister_callback(&o2net_hb_down); 1652 1643 } 1653 1644 1654 1645 int o2net_register_hb_callbacks(void)
+3
fs/ocfs2/dlm/dlmmaster.c
··· 2730 2730 int ret; 2731 2731 int lock_dropped = 0; 2732 2732 2733 + spin_lock(&res->spinlock); 2733 2734 if (res->owner != dlm->node_num) { 2734 2735 if (!__dlm_lockres_unused(res)) { 2735 2736 mlog(ML_ERROR, "%s:%.*s: this node is not master, " 2736 2737 "trying to free this but locks remain\n", 2737 2738 dlm->name, res->lockname.len, res->lockname.name); 2738 2739 } 2740 + spin_unlock(&res->spinlock); 2739 2741 goto leave; 2740 2742 } 2743 + spin_unlock(&res->spinlock); 2741 2744 2742 2745 /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ 2743 2746 spin_unlock(&dlm->spinlock);
+2
fs/ocfs2/dlm/dlmthread.c
··· 265 265 /* This may drop and reacquire the dlm spinlock if it 266 266 * has to do migration. */ 267 267 mlog(0, "calling dlm_purge_lockres!\n"); 268 + dlm_lockres_get(lockres); 268 269 if (dlm_purge_lockres(dlm, lockres)) 269 270 BUG(); 271 + dlm_lockres_put(lockres); 270 272 mlog(0, "DONE calling dlm_purge_lockres!\n"); 271 273 272 274 /* Avoid adding any scheduling latencies */
+5 -10
fs/ocfs2/heartbeat.c
··· 164 164 } 165 165 166 166 status = o2hb_register_callback(&osb->osb_hb_up); 167 - if (status < 0) 167 + if (status < 0) { 168 168 mlog_errno(status); 169 + o2hb_unregister_callback(&osb->osb_hb_down); 170 + } 169 171 170 172 bail: 171 173 return status; ··· 175 173 176 174 void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) 177 175 { 178 - int status; 179 - 180 176 if (ocfs2_mount_local(osb)) 181 177 return; 182 178 183 - status = o2hb_unregister_callback(&osb->osb_hb_down); 184 - if (status < 0) 185 - mlog_errno(status); 186 - 187 - status = o2hb_unregister_callback(&osb->osb_hb_up); 188 - if (status < 0) 189 - mlog_errno(status); 179 + o2hb_unregister_callback(&osb->osb_hb_down); 180 + o2hb_unregister_callback(&osb->osb_hb_up); 190 181 } 191 182 192 183 void ocfs2_stop_heartbeat(struct ocfs2_super *osb)