aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r--fs/ceph/inode.c124
1 files changed, 56 insertions, 68 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index f85355bf49c4..3acdd3cc6039 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -33,9 +33,7 @@
33 33
34static const struct inode_operations ceph_symlink_iops; 34static const struct inode_operations ceph_symlink_iops;
35 35
36static void ceph_invalidate_work(struct work_struct *work); 36static void ceph_inode_work(struct work_struct *work);
37static void ceph_writeback_work(struct work_struct *work);
38static void ceph_vmtruncate_work(struct work_struct *work);
39 37
40/* 38/*
41 * find or create an inode, given the ceph ino number 39 * find or create an inode, given the ceph ino number
@@ -509,10 +507,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
509 INIT_LIST_HEAD(&ci->i_snap_realm_item); 507 INIT_LIST_HEAD(&ci->i_snap_realm_item);
510 INIT_LIST_HEAD(&ci->i_snap_flush_item); 508 INIT_LIST_HEAD(&ci->i_snap_flush_item);
511 509
512 INIT_WORK(&ci->i_wb_work, ceph_writeback_work); 510 INIT_WORK(&ci->i_work, ceph_inode_work);
513 INIT_WORK(&ci->i_pg_inv_work, ceph_invalidate_work); 511 ci->i_work_mask = 0;
514
515 INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work);
516 512
517 ceph_fscache_inode_init(ci); 513 ceph_fscache_inode_init(ci);
518 514
@@ -1746,51 +1742,62 @@ bool ceph_inode_set_size(struct inode *inode, loff_t size)
1746 */ 1742 */
1747void ceph_queue_writeback(struct inode *inode) 1743void ceph_queue_writeback(struct inode *inode)
1748{ 1744{
1745 struct ceph_inode_info *ci = ceph_inode(inode);
1746 set_bit(CEPH_I_WORK_WRITEBACK, &ci->i_work_mask);
1747
1749 ihold(inode); 1748 ihold(inode);
1750 if (queue_work(ceph_inode_to_client(inode)->wb_wq, 1749 if (queue_work(ceph_inode_to_client(inode)->inode_wq,
1751 &ceph_inode(inode)->i_wb_work)) { 1750 &ci->i_work)) {
1752 dout("ceph_queue_writeback %p\n", inode); 1751 dout("ceph_queue_writeback %p\n", inode);
1753 } else { 1752 } else {
1754 dout("ceph_queue_writeback %p failed\n", inode); 1753 dout("ceph_queue_writeback %p already queued, mask=%lx\n",
1754 inode, ci->i_work_mask);
1755 iput(inode); 1755 iput(inode);
1756 } 1756 }
1757} 1757}
1758 1758
1759static void ceph_writeback_work(struct work_struct *work)
1760{
1761 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
1762 i_wb_work);
1763 struct inode *inode = &ci->vfs_inode;
1764
1765 dout("writeback %p\n", inode);
1766 filemap_fdatawrite(&inode->i_data);
1767 iput(inode);
1768}
1769
1770/* 1759/*
1771 * queue an async invalidation 1760 * queue an async invalidation
1772 */ 1761 */
1773void ceph_queue_invalidate(struct inode *inode) 1762void ceph_queue_invalidate(struct inode *inode)
1774{ 1763{
1764 struct ceph_inode_info *ci = ceph_inode(inode);
1765 set_bit(CEPH_I_WORK_INVALIDATE_PAGES, &ci->i_work_mask);
1766
1775 ihold(inode); 1767 ihold(inode);
1776 if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, 1768 if (queue_work(ceph_inode_to_client(inode)->inode_wq,
1777 &ceph_inode(inode)->i_pg_inv_work)) { 1769 &ceph_inode(inode)->i_work)) {
1778 dout("ceph_queue_invalidate %p\n", inode); 1770 dout("ceph_queue_invalidate %p\n", inode);
1779 } else { 1771 } else {
1780 dout("ceph_queue_invalidate %p failed\n", inode); 1772 dout("ceph_queue_invalidate %p already queued, mask=%lx\n",
1773 inode, ci->i_work_mask);
1781 iput(inode); 1774 iput(inode);
1782 } 1775 }
1783} 1776}
1784 1777
1785/* 1778/*
1786 * Invalidate inode pages in a worker thread. (This can't be done 1779 * Queue an async vmtruncate. If we fail to queue work, we will handle
1787 * in the message handler context.) 1780 * the truncation the next time we call __ceph_do_pending_vmtruncate.
1788 */ 1781 */
1789static void ceph_invalidate_work(struct work_struct *work) 1782void ceph_queue_vmtruncate(struct inode *inode)
1790{ 1783{
1791 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, 1784 struct ceph_inode_info *ci = ceph_inode(inode);
1792 i_pg_inv_work); 1785 set_bit(CEPH_I_WORK_VMTRUNCATE, &ci->i_work_mask);
1793 struct inode *inode = &ci->vfs_inode; 1786
1787 ihold(inode);
1788 if (queue_work(ceph_inode_to_client(inode)->inode_wq,
1789 &ci->i_work)) {
1790 dout("ceph_queue_vmtruncate %p\n", inode);
1791 } else {
1792 dout("ceph_queue_vmtruncate %p already queued, mask=%lx\n",
1793 inode, ci->i_work_mask);
1794 iput(inode);
1795 }
1796}
1797
1798static void ceph_do_invalidate_pages(struct inode *inode)
1799{
1800 struct ceph_inode_info *ci = ceph_inode(inode);
1794 struct ceph_fs_client *fsc = ceph_inode_to_client(inode); 1801 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
1795 u32 orig_gen; 1802 u32 orig_gen;
1796 int check = 0; 1803 int check = 0;
@@ -1842,44 +1849,6 @@ static void ceph_invalidate_work(struct work_struct *work)
1842out: 1849out:
1843 if (check) 1850 if (check)
1844 ceph_check_caps(ci, 0, NULL); 1851 ceph_check_caps(ci, 0, NULL);
1845 iput(inode);
1846}
1847
1848
1849/*
1850 * called by trunc_wq;
1851 *
1852 * We also truncate in a separate thread as well.
1853 */
1854static void ceph_vmtruncate_work(struct work_struct *work)
1855{
1856 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
1857 i_vmtruncate_work);
1858 struct inode *inode = &ci->vfs_inode;
1859
1860 dout("vmtruncate_work %p\n", inode);
1861 __ceph_do_pending_vmtruncate(inode);
1862 iput(inode);
1863}
1864
1865/*
1866 * Queue an async vmtruncate. If we fail to queue work, we will handle
1867 * the truncation the next time we call __ceph_do_pending_vmtruncate.
1868 */
1869void ceph_queue_vmtruncate(struct inode *inode)
1870{
1871 struct ceph_inode_info *ci = ceph_inode(inode);
1872
1873 ihold(inode);
1874
1875 if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq,
1876 &ci->i_vmtruncate_work)) {
1877 dout("ceph_queue_vmtruncate %p\n", inode);
1878 } else {
1879 dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
1880 inode, ci->i_truncate_pending);
1881 iput(inode);
1882 }
1883} 1852}
1884 1853
1885/* 1854/*
@@ -1943,6 +1912,25 @@ retry:
1943 wake_up_all(&ci->i_cap_wq); 1912 wake_up_all(&ci->i_cap_wq);
1944} 1913}
1945 1914
1915static void ceph_inode_work(struct work_struct *work)
1916{
1917 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
1918 i_work);
1919 struct inode *inode = &ci->vfs_inode;
1920
1921 if (test_and_clear_bit(CEPH_I_WORK_WRITEBACK, &ci->i_work_mask)) {
1922 dout("writeback %p\n", inode);
1923 filemap_fdatawrite(&inode->i_data);
1924 }
1925 if (test_and_clear_bit(CEPH_I_WORK_INVALIDATE_PAGES, &ci->i_work_mask))
1926 ceph_do_invalidate_pages(inode);
1927
1928 if (test_and_clear_bit(CEPH_I_WORK_VMTRUNCATE, &ci->i_work_mask))
1929 __ceph_do_pending_vmtruncate(inode);
1930
1931 iput(inode);
1932}
1933
1946/* 1934/*
1947 * symlinks 1935 * symlinks
1948 */ 1936 */