Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
ceph: keep reference to parent inode on ceph_dentry
ceph: queue cap_snaps once per realm
libceph: fix socket write error handling
libceph: fix socket read error handling

+46 -36
+4 -1
fs/ceph/dir.c
··· 60 60 } 61 61 di->dentry = dentry; 62 62 di->lease_session = NULL; 63 + di->parent_inode = igrab(dentry->d_parent->d_inode); 63 64 dentry->d_fsdata = di; 64 65 dentry->d_time = jiffies; 65 66 ceph_dentry_lru_add(dentry); ··· 1034 1033 u64 snapid = CEPH_NOSNAP; 1035 1034 1036 1035 if (!IS_ROOT(dentry)) { 1037 - parent_inode = dentry->d_parent->d_inode; 1036 + parent_inode = di->parent_inode; 1038 1037 if (parent_inode) 1039 1038 snapid = ceph_snap(parent_inode); 1040 1039 } ··· 1059 1058 kmem_cache_free(ceph_dentry_cachep, di); 1060 1059 dentry->d_fsdata = NULL; 1061 1060 } 1061 + if (parent_inode) 1062 + iput(parent_inode); 1062 1063 } 1063 1064 1064 1065 static int ceph_snapdir_d_revalidate(struct dentry *dentry,
+10 -4
fs/ceph/snap.c
··· 584 584 if (lastinode) 585 585 iput(lastinode); 586 586 587 - dout("queue_realm_cap_snaps %p %llx children\n", realm, realm->ino); 588 - list_for_each_entry(child, &realm->children, child_item) 589 - queue_realm_cap_snaps(child); 587 + list_for_each_entry(child, &realm->children, child_item) { 588 + dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n", 589 + realm, realm->ino, child, child->ino); 590 + list_del_init(&child->dirty_item); 591 + list_add(&child->dirty_item, &realm->dirty_item); 592 + } 590 593 594 + list_del_init(&realm->dirty_item); 591 595 dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); 592 596 } 593 597 ··· 687 683 * queue cap snaps _after_ we've built the new snap contexts, 688 684 * so that i_head_snapc can be set appropriately. 689 685 */ 690 - list_for_each_entry(realm, &dirty_realms, dirty_item) { 686 + while (!list_empty(&dirty_realms)) { 687 + realm = list_first_entry(&dirty_realms, struct ceph_snap_realm, 688 + dirty_item); 691 689 queue_realm_cap_snaps(realm); 692 690 } 693 691
+1
fs/ceph/super.h
··· 207 207 struct dentry *dentry; 208 208 u64 time; 209 209 u64 offset; 210 + struct inode *parent_inode; 210 211 }; 211 212 212 213 struct ceph_inode_xattrs_info {
+31 -31
net/ceph/messenger.c
··· 252 252 { 253 253 struct kvec iov = {buf, len}; 254 254 struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; 255 + int r; 255 256 256 - return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags); 257 + r = kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags); 258 + if (r == -EAGAIN) 259 + r = 0; 260 + return r; 257 261 } 258 262 259 263 /* ··· 268 264 size_t kvlen, size_t len, int more) 269 265 { 270 266 struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; 267 + int r; 271 268 272 269 if (more) 273 270 msg.msg_flags |= MSG_MORE; 274 271 else 275 272 msg.msg_flags |= MSG_EOR; /* superfluous, but what the hell */ 276 273 277 - return kernel_sendmsg(sock, &msg, iov, kvlen, len); 274 + r = kernel_sendmsg(sock, &msg, iov, kvlen, len); 275 + if (r == -EAGAIN) 276 + r = 0; 277 + return r; 278 278 } 279 279 280 280 ··· 855 847 (msg->pages || msg->pagelist || msg->bio || in_trail)) 856 848 kunmap(page); 857 849 850 + if (ret == -EAGAIN) 851 + ret = 0; 858 852 if (ret <= 0) 859 853 goto out; 860 854 ··· 1747 1737 if (con->out_skip) { 1748 1738 ret = write_partial_skip(con); 1749 1739 if (ret <= 0) 1750 - goto done; 1751 - if (ret < 0) { 1752 - dout("try_write write_partial_skip err %d\n", ret); 1753 - goto done; 1754 - } 1740 + goto out; 1755 1741 } 1756 1742 if (con->out_kvec_left) { 1757 1743 ret = write_partial_kvec(con); 1758 1744 if (ret <= 0) 1759 - goto done; 1745 + goto out; 1760 1746 } 1761 1747 1762 1748 /* msg pages? */ ··· 1767 1761 if (ret == 1) 1768 1762 goto more_kvec; /* we need to send the footer, too! */ 1769 1763 if (ret == 0) 1770 - goto done; 1764 + goto out; 1771 1765 if (ret < 0) { 1772 1766 dout("try_write write_partial_msg_pages err %d\n", 1773 1767 ret); 1774 - goto done; 1768 + goto out; 1775 1769 } 1776 1770 } 1777 1771 ··· 1795 1789 /* Nothing to do! */ 1796 1790 clear_bit(WRITE_PENDING, &con->state); 1797 1791 dout("try_write nothing else to write.\n"); 1798 - done: 1799 1792 ret = 0; 1800 1793 out: 1801 - dout("try_write done on %p\n", con); 1794 + dout("try_write done on %p ret %d\n", con, ret); 1802 1795 return ret; 1803 1796 } 1804 1797 ··· 1826 1821 dout("try_read connecting\n"); 1827 1822 ret = read_partial_banner(con); 1828 1823 if (ret <= 0) 1829 - goto done; 1830 - if (process_banner(con) < 0) { 1831 - ret = -1; 1832 1824 goto out; 1833 - } 1825 + ret = process_banner(con); 1826 + if (ret < 0) 1827 + goto out; 1834 1828 } 1835 1829 ret = read_partial_connect(con); 1836 1830 if (ret <= 0) 1837 - goto done; 1838 - if (process_connect(con) < 0) { 1839 - ret = -1; 1840 1831 goto out; 1841 - } 1832 + ret = process_connect(con); 1833 + if (ret < 0) 1834 + goto out; 1842 1835 goto more; 1843 1836 } 1844 1837 ··· 1851 1848 dout("skipping %d / %d bytes\n", skip, -con->in_base_pos); 1852 1849 ret = ceph_tcp_recvmsg(con->sock, buf, skip); 1853 1850 if (ret <= 0) 1854 - goto done; 1851 + goto out; 1855 1852 con->in_base_pos += ret; 1856 1853 if (con->in_base_pos) 1857 1854 goto more; ··· 1862 1859 */ 1863 1860 ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1); 1864 1861 if (ret <= 0) 1865 - goto done; 1862 + goto out; 1866 1863 dout("try_read got tag %d\n", (int)con->in_tag); 1867 1864 switch (con->in_tag) { 1868 1865 case CEPH_MSGR_TAG_MSG: ··· 1873 1870 break; 1874 1871 case CEPH_MSGR_TAG_CLOSE: 1875 1872 set_bit(CLOSED, &con->state); /* fixme */ 1876 - goto done; 1873 + goto out; 1877 1874 default: 1878 1875 goto bad_tag; 1879 1876 } ··· 1885 1882 case -EBADMSG: 1886 1883 con->error_msg = "bad crc"; 1887 1884 ret = -EIO; 1888 - goto out; 1885 + break; 1889 1886 case -EIO: 1890 1887 con->error_msg = "io error"; 1891 - goto out; 1892 - default: 1893 - goto done; 1888 + break; 1894 1889 } 1890 + goto out; 1895 1891 } 1896 1892 if (con->in_tag == CEPH_MSGR_TAG_READY) 1897 1893 goto more; ··· 1900 1898 if (con->in_tag == CEPH_MSGR_TAG_ACK) { 1901 1899 ret = read_partial_ack(con); 1902 1900 if (ret <= 0) 1903 - goto done; 1901 + goto out; 1904 1902 process_ack(con); 1905 1903 goto more; 1906 1904 } 1907 1905 1908 - done: 1909 - ret = 0; 1910 1906 out: 1911 - dout("try_read done on %p\n", con); 1907 + dout("try_read done on %p ret %d\n", con, ret); 1912 1908 return ret; 1913 1909 1914 1910 bad_tag: