* [ceph-client:wip-fscrypt 48/59] fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3
@ 2022-07-06 11:04 kernel test robot
2022-07-06 12:44 ` Xiubo Li
0 siblings, 1 reply; 3+ messages in thread
From: kernel test robot @ 2022-07-06 11:04 UTC (permalink / raw)
To: Jeff Layton; +Cc: llvm, kbuild-all, ceph-devel, Xiubo Li
tree: https://github.com/ceph/ceph-client.git wip-fscrypt
head: 55b265c1fd41c55be5e56d9eb4b24da48ac04a8c
commit: 3c062ae4472df769c1a740ed55ccc252f9e104c1 [48/59] ceph: add read/modify/write to ceph_sync_write
config: i386-randconfig-a006 (https://download.01.org/0day-ci/archive/20220706/202207061958.I86cqkif-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f553287b588916de09c66e3e32bf75e5060f967f)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/ceph/ceph-client/commit/3c062ae4472df769c1a740ed55ccc252f9e104c1
git remote add ceph-client https://github.com/ceph/ceph-client.git
git fetch --no-tags ceph-client wip-fscrypt
git checkout 3c062ae4472df769c1a740ed55ccc252f9e104c1
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash fs/ceph/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3
ret = ceph_osdc_start_request(osdc, req, false);
~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
include/linux/ceph/osd_client.h:583:6: note: 'ceph_osdc_start_request' declared here
void ceph_osdc_start_request(struct ceph_osd_client *osdc,
^
fs/ceph/file.c:1896:38: error: too many arguments to function call, expected 2, have 3
ceph_osdc_start_request(osdc, req, false);
~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
include/linux/ceph/osd_client.h:583:6: note: 'ceph_osdc_start_request' declared here
void ceph_osdc_start_request(struct ceph_osd_client *osdc,
^
2 errors generated.
vim +1727 fs/ceph/file.c
1553
1554 /*
1555 * Synchronous write, straight from __user pointer or user pages.
1556 *
1557 * If write spans object boundary, just do multiple writes. (For a
1558 * correct atomic write, we should e.g. take write locks on all
1559 * objects, rollback on failure, etc.)
1560 */
1561 static ssize_t
1562 ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
1563 struct ceph_snap_context *snapc)
1564 {
1565 struct file *file = iocb->ki_filp;
1566 struct inode *inode = file_inode(file);
1567 struct ceph_inode_info *ci = ceph_inode(inode);
1568 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
1569 struct ceph_osd_client *osdc = &fsc->client->osdc;
1570 struct ceph_osd_request *req;
1571 struct page **pages;
1572 u64 len;
1573 int num_pages;
1574 int written = 0;
1575 int ret;
1576 bool check_caps = false;
1577 struct timespec64 mtime = current_time(inode);
1578 size_t count = iov_iter_count(from);
1579
1580 if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
1581 return -EROFS;
1582
1583 dout("sync_write on file %p %lld~%u snapc %p seq %lld\n",
1584 file, pos, (unsigned)count, snapc, snapc->seq);
1585
1586 ret = filemap_write_and_wait_range(inode->i_mapping,
1587 pos, pos + count - 1);
1588 if (ret < 0)
1589 return ret;
1590
1591 ceph_fscache_invalidate(inode, false);
1592 ret = invalidate_inode_pages2_range(inode->i_mapping,
1593 pos >> PAGE_SHIFT,
1594 (pos + count - 1) >> PAGE_SHIFT);
1595 if (ret < 0)
1596 dout("invalidate_inode_pages2_range returned %d\n", ret);
1597
1598 while ((len = iov_iter_count(from)) > 0) {
1599 size_t left;
1600 int n;
1601 u64 write_pos = pos;
1602 u64 write_len = len;
1603 u64 objnum, objoff;
1604 u32 xlen;
1605 u64 assert_ver = 0;
1606 bool rmw;
1607 bool first, last;
1608 struct iov_iter saved_iter = *from;
1609 size_t off;
1610
1611 ceph_fscrypt_adjust_off_and_len(inode, &write_pos, &write_len);
1612
1613 /* clamp the length to the end of first object */
1614 ceph_calc_file_object_mapping(&ci->i_layout, write_pos,
1615 write_len, &objnum, &objoff,
1616 &xlen);
1617 write_len = xlen;
1618
1619 /* adjust len downward if it goes beyond current object */
1620 if (pos + len > write_pos + write_len)
1621 len = write_pos + write_len - pos;
1622
1623 /*
1624 * If we had to adjust the length or position to align with a
1625 * crypto block, then we must do a read/modify/write cycle. We
1626 * use a version assertion to redrive the thing if something
1627 * changes in between.
1628 */
1629 first = pos != write_pos;
1630 last = (pos + len) != (write_pos + write_len);
1631 rmw = first || last;
1632
1633 dout("sync_write ino %llx %lld~%llu adjusted %lld~%llu -- %srmw\n",
1634 ci->i_vino.ino, pos, len, write_pos, write_len, rmw ? "" : "no ");
1635
1636 /*
1637 * The data is emplaced into the page as it would be if it were in
1638 * an array of pagecache pages.
1639 */
1640 num_pages = calc_pages_for(write_pos, write_len);
1641 pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
1642 if (IS_ERR(pages)) {
1643 ret = PTR_ERR(pages);
1644 break;
1645 }
1646
1647 /* Do we need to preload the pages? */
1648 if (rmw) {
1649 u64 first_pos = write_pos;
1650 u64 last_pos = (write_pos + write_len) - CEPH_FSCRYPT_BLOCK_SIZE;
1651 u64 read_len = CEPH_FSCRYPT_BLOCK_SIZE;
1652 struct ceph_osd_req_op *op;
1653
1654 /* We should only need to do this for encrypted inodes */
1655 WARN_ON_ONCE(!IS_ENCRYPTED(inode));
1656
1657 /* No need to do two reads if first and last blocks are same */
1658 if (first && last_pos == first_pos)
1659 last = false;
1660
1661 /*
1662 * Allocate a read request for one or two extents, depending
1663 * on how the request was aligned.
1664 */
1665 req = ceph_osdc_new_request(osdc, &ci->i_layout,
1666 ci->i_vino, first ? first_pos : last_pos,
1667 &read_len, 0, (first && last) ? 2 : 1,
1668 CEPH_OSD_OP_SPARSE_READ, CEPH_OSD_FLAG_READ,
1669 NULL, ci->i_truncate_seq,
1670 ci->i_truncate_size, false);
1671 if (IS_ERR(req)) {
1672 ceph_release_page_vector(pages, num_pages);
1673 ret = PTR_ERR(req);
1674 break;
1675 }
1676
1677 /* Something is misaligned! */
1678 if (read_len != CEPH_FSCRYPT_BLOCK_SIZE) {
1679 ceph_osdc_put_request(req);
1680 ceph_release_page_vector(pages, num_pages);
1681 ret = -EIO;
1682 break;
1683 }
1684
1685 /* Add extent for first block? */
1686 op = &req->r_ops[0];
1687
1688 if (first) {
1689 osd_req_op_extent_osd_data_pages(req, 0, pages,
1690 CEPH_FSCRYPT_BLOCK_SIZE,
1691 offset_in_page(first_pos),
1692 false, false);
1693 /* We only expect a single extent here */
1694 ret = __ceph_alloc_sparse_ext_map(op, 1);
1695 if (ret) {
1696 ceph_osdc_put_request(req);
1697 ceph_release_page_vector(pages, num_pages);
1698 break;
1699 }
1700 }
1701
1702 /* Add extent for last block */
1703 if (last) {
1704 /* Init the other extent if first extent has been used */
1705 if (first) {
1706 op = &req->r_ops[1];
1707 osd_req_op_extent_init(req, 1, CEPH_OSD_OP_SPARSE_READ,
1708 last_pos, CEPH_FSCRYPT_BLOCK_SIZE,
1709 ci->i_truncate_size,
1710 ci->i_truncate_seq);
1711 }
1712
1713 ret = __ceph_alloc_sparse_ext_map(op, 1);
1714 if (ret) {
1715 ceph_osdc_put_request(req);
1716 ceph_release_page_vector(pages, num_pages);
1717 break;
1718 }
1719
1720 osd_req_op_extent_osd_data_pages(req, first ? 1 : 0,
1721 &pages[num_pages - 1],
1722 CEPH_FSCRYPT_BLOCK_SIZE,
1723 offset_in_page(last_pos),
1724 false, false);
1725 }
1726
> 1727 ret = ceph_osdc_start_request(osdc, req, false);
1728 if (!ret)
1729 ret = ceph_osdc_wait_request(osdc, req);
1730
1731 /* FIXME: length field is wrong if there are 2 extents */
1732 ceph_update_read_metrics(&fsc->mdsc->metric,
1733 req->r_start_latency,
1734 req->r_end_latency,
1735 read_len, ret);
1736
1737 /* Ok if object is not already present */
1738 if (ret == -ENOENT) {
1739 /*
1740 * If there is no object, then we can't assert
1741 * on its version. Set it to 0, and we'll use an
1742 * exclusive create instead.
1743 */
1744 ceph_osdc_put_request(req);
1745 ret = 0;
1746
1747 /*
1748 * zero out the soon-to-be uncopied parts of the
1749 * first and last pages.
1750 */
1751 if (first)
1752 zero_user_segment(pages[0], 0,
1753 offset_in_page(first_pos));
1754 if (last)
1755 zero_user_segment(pages[num_pages - 1],
1756 offset_in_page(last_pos),
1757 PAGE_SIZE);
1758 } else {
1759 if (ret < 0) {
1760 ceph_osdc_put_request(req);
1761 ceph_release_page_vector(pages, num_pages);
1762 break;
1763 }
1764
1765 op = &req->r_ops[0];
1766 if (op->extent.sparse_ext_cnt == 0) {
1767 if (first)
1768 zero_user_segment(pages[0], 0,
1769 offset_in_page(first_pos));
1770 else
1771 zero_user_segment(pages[num_pages - 1],
1772 offset_in_page(last_pos),
1773 PAGE_SIZE);
1774 } else if (op->extent.sparse_ext_cnt != 1 ||
1775 ceph_sparse_ext_map_end(op) !=
1776 CEPH_FSCRYPT_BLOCK_SIZE) {
1777 ret = -EIO;
1778 ceph_osdc_put_request(req);
1779 ceph_release_page_vector(pages, num_pages);
1780 break;
1781 }
1782
1783 if (first && last) {
1784 op = &req->r_ops[1];
1785 if (op->extent.sparse_ext_cnt == 0) {
1786 zero_user_segment(pages[num_pages - 1],
1787 offset_in_page(last_pos),
1788 PAGE_SIZE);
1789 } else if (op->extent.sparse_ext_cnt != 1 ||
1790 ceph_sparse_ext_map_end(op) !=
1791 CEPH_FSCRYPT_BLOCK_SIZE) {
1792 ret = -EIO;
1793 ceph_osdc_put_request(req);
1794 ceph_release_page_vector(pages, num_pages);
1795 break;
1796 }
1797 }
1798
1799 /* Grab assert version. It must be non-zero. */
1800 assert_ver = req->r_version;
1801 WARN_ON_ONCE(ret > 0 && assert_ver == 0);
1802
1803 ceph_osdc_put_request(req);
1804 if (first) {
1805 ret = ceph_fscrypt_decrypt_block_inplace(inode,
1806 pages[0],
1807 CEPH_FSCRYPT_BLOCK_SIZE,
1808 offset_in_page(first_pos),
1809 first_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
1810 if (ret < 0) {
1811 ceph_release_page_vector(pages, num_pages);
1812 break;
1813 }
1814 }
1815 if (last) {
1816 ret = ceph_fscrypt_decrypt_block_inplace(inode,
1817 pages[num_pages - 1],
1818 CEPH_FSCRYPT_BLOCK_SIZE,
1819 offset_in_page(last_pos),
1820 last_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
1821 if (ret < 0) {
1822 ceph_release_page_vector(pages, num_pages);
1823 break;
1824 }
1825 }
1826 }
1827 }
1828
1829 left = len;
1830 off = offset_in_page(pos);
1831 for (n = 0; n < num_pages; n++) {
1832 size_t plen = min_t(size_t, left, PAGE_SIZE - off);
1833
1834 /* copy the data */
1835 ret = copy_page_from_iter(pages[n], off, plen, from);
1836 if (ret != plen) {
1837 ret = -EFAULT;
1838 break;
1839 }
1840 off = 0;
1841 left -= ret;
1842 }
1843 if (ret < 0) {
1844 dout("sync_write write failed with %d\n", ret);
1845 ceph_release_page_vector(pages, num_pages);
1846 break;
1847 }
1848
1849 if (IS_ENCRYPTED(inode)) {
1850 ret = ceph_fscrypt_encrypt_pages(inode, pages,
1851 write_pos, write_len,
1852 GFP_KERNEL);
1853 if (ret < 0) {
1854 dout("encryption failed with %d\n", ret);
1855 ceph_release_page_vector(pages, num_pages);
1856 break;
1857 }
1858 }
1859
1860 req = ceph_osdc_new_request(osdc, &ci->i_layout,
1861 ci->i_vino, write_pos, &write_len,
1862 rmw ? 1 : 0, rmw ? 2 : 1,
1863 CEPH_OSD_OP_WRITE,
1864 CEPH_OSD_FLAG_WRITE,
1865 snapc, ci->i_truncate_seq,
1866 ci->i_truncate_size, false);
1867 if (IS_ERR(req)) {
1868 ret = PTR_ERR(req);
1869 ceph_release_page_vector(pages, num_pages);
1870 break;
1871 }
1872
1873 dout("sync_write write op %lld~%llu\n", write_pos, write_len);
1874 osd_req_op_extent_osd_data_pages(req, rmw ? 1 : 0, pages, write_len,
1875 offset_in_page(write_pos), false,
1876 true);
1877 req->r_inode = inode;
1878 req->r_mtime = mtime;
1879
1880 /* Set up the assertion */
1881 if (rmw) {
1882 /*
1883 * Set up the assertion. If we don't have a version number,
1884 * then the object doesn't exist yet. Use an exclusive create
1885 * instead of a version assertion in that case.
1886 */
1887 if (assert_ver) {
1888 osd_req_op_init(req, 0, CEPH_OSD_OP_ASSERT_VER, 0);
1889 req->r_ops[0].assert_ver.ver = assert_ver;
1890 } else {
1891 osd_req_op_init(req, 0, CEPH_OSD_OP_CREATE,
1892 CEPH_OSD_OP_FLAG_EXCL);
1893 }
1894 }
1895
1896 ceph_osdc_start_request(osdc, req, false);
1897
1898 ceph_update_write_metrics(&fsc->mdsc->metric, req->r_start_latency,
1899 req->r_end_latency, len, ret);
1900 ceph_osdc_put_request(req);
1901 if (ret != 0) {
1902 dout("sync_write osd write returned %d\n", ret);
1903 /* Version changed! Must re-do the rmw cycle */
1904 if ((assert_ver && (ret == -ERANGE || ret == -EOVERFLOW)) ||
1905 (!assert_ver && ret == -EEXIST)) {
1906 /* We should only ever see this on a rmw */
1907 WARN_ON_ONCE(!rmw);
1908
1909 /* The version should never go backward */
1910 WARN_ON_ONCE(ret == -EOVERFLOW);
1911
1912 *from = saved_iter;
1913
1914 /* FIXME: limit number of times we loop? */
1915 continue;
1916 }
1917 ceph_set_error_write(ci);
1918 break;
1919 }
1920 ceph_clear_error_write(ci);
1921 pos += len;
1922 written += len;
1923 dout("sync_write written %d\n", written);
1924 if (pos > i_size_read(inode)) {
1925 check_caps = ceph_inode_set_size(inode, pos);
1926 if (check_caps)
1927 ceph_check_caps(ceph_inode(inode),
1928 CHECK_CAPS_AUTHONLY,
1929 NULL);
1930 }
1931
1932 }
1933
1934 if (ret != -EOLDSNAPC && written > 0) {
1935 ret = written;
1936 iocb->ki_pos = pos;
1937 }
1938 dout("sync_write returning %d\n", ret);
1939 return ret;
1940 }
1941
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [ceph-client:wip-fscrypt 48/59] fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3
2022-07-06 11:04 [ceph-client:wip-fscrypt 48/59] fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3 kernel test robot
@ 2022-07-06 12:44 ` Xiubo Li
0 siblings, 0 replies; 3+ messages in thread
From: Xiubo Li @ 2022-07-06 12:44 UTC (permalink / raw)
To: kernel test robot, Jeff Layton; +Cc: llvm, kbuild-all, ceph-devel
Fixed it in the wip-fscrypt branch.
Thanks!
On 7/6/22 7:04 PM, kernel test robot wrote:
> tree: https://github.com/ceph/ceph-client.git wip-fscrypt
> head: 55b265c1fd41c55be5e56d9eb4b24da48ac04a8c
> commit: 3c062ae4472df769c1a740ed55ccc252f9e104c1 [48/59] ceph: add read/modify/write to ceph_sync_write
> config: i386-randconfig-a006 (https://download.01.org/0day-ci/archive/20220706/202207061958.I86cqkif-lkp@intel.com/config)
> compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f553287b588916de09c66e3e32bf75e5060f967f)
> reproduce (this is a W=1 build):
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # https://github.com/ceph/ceph-client/commit/3c062ae4472df769c1a740ed55ccc252f9e104c1
> git remote add ceph-client https://github.com/ceph/ceph-client.git
> git fetch --no-tags ceph-client wip-fscrypt
> git checkout 3c062ae4472df769c1a740ed55ccc252f9e104c1
> # save the config file
> mkdir build_dir && cp config build_dir/.config
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash fs/ceph/
>
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>>> fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3
> ret = ceph_osdc_start_request(osdc, req, false);
> ~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
> include/linux/ceph/osd_client.h:583:6: note: 'ceph_osdc_start_request' declared here
> void ceph_osdc_start_request(struct ceph_osd_client *osdc,
> ^
> fs/ceph/file.c:1896:38: error: too many arguments to function call, expected 2, have 3
> ceph_osdc_start_request(osdc, req, false);
> ~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
> include/linux/ceph/osd_client.h:583:6: note: 'ceph_osdc_start_request' declared here
> void ceph_osdc_start_request(struct ceph_osd_client *osdc,
> ^
> 2 errors generated.
>
>
> vim +1727 fs/ceph/file.c
>
> 1553
> 1554 /*
> 1555 * Synchronous write, straight from __user pointer or user pages.
> 1556 *
> 1557 * If write spans object boundary, just do multiple writes. (For a
> 1558 * correct atomic write, we should e.g. take write locks on all
> 1559 * objects, rollback on failure, etc.)
> 1560 */
> 1561 static ssize_t
> 1562 ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
> 1563 struct ceph_snap_context *snapc)
> 1564 {
> 1565 struct file *file = iocb->ki_filp;
> 1566 struct inode *inode = file_inode(file);
> 1567 struct ceph_inode_info *ci = ceph_inode(inode);
> 1568 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
> 1569 struct ceph_osd_client *osdc = &fsc->client->osdc;
> 1570 struct ceph_osd_request *req;
> 1571 struct page **pages;
> 1572 u64 len;
> 1573 int num_pages;
> 1574 int written = 0;
> 1575 int ret;
> 1576 bool check_caps = false;
> 1577 struct timespec64 mtime = current_time(inode);
> 1578 size_t count = iov_iter_count(from);
> 1579
> 1580 if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
> 1581 return -EROFS;
> 1582
> 1583 dout("sync_write on file %p %lld~%u snapc %p seq %lld\n",
> 1584 file, pos, (unsigned)count, snapc, snapc->seq);
> 1585
> 1586 ret = filemap_write_and_wait_range(inode->i_mapping,
> 1587 pos, pos + count - 1);
> 1588 if (ret < 0)
> 1589 return ret;
> 1590
> 1591 ceph_fscache_invalidate(inode, false);
> 1592 ret = invalidate_inode_pages2_range(inode->i_mapping,
> 1593 pos >> PAGE_SHIFT,
> 1594 (pos + count - 1) >> PAGE_SHIFT);
> 1595 if (ret < 0)
> 1596 dout("invalidate_inode_pages2_range returned %d\n", ret);
> 1597
> 1598 while ((len = iov_iter_count(from)) > 0) {
> 1599 size_t left;
> 1600 int n;
> 1601 u64 write_pos = pos;
> 1602 u64 write_len = len;
> 1603 u64 objnum, objoff;
> 1604 u32 xlen;
> 1605 u64 assert_ver = 0;
> 1606 bool rmw;
> 1607 bool first, last;
> 1608 struct iov_iter saved_iter = *from;
> 1609 size_t off;
> 1610
> 1611 ceph_fscrypt_adjust_off_and_len(inode, &write_pos, &write_len);
> 1612
> 1613 /* clamp the length to the end of first object */
> 1614 ceph_calc_file_object_mapping(&ci->i_layout, write_pos,
> 1615 write_len, &objnum, &objoff,
> 1616 &xlen);
> 1617 write_len = xlen;
> 1618
> 1619 /* adjust len downward if it goes beyond current object */
> 1620 if (pos + len > write_pos + write_len)
> 1621 len = write_pos + write_len - pos;
> 1622
> 1623 /*
> 1624 * If we had to adjust the length or position to align with a
> 1625 * crypto block, then we must do a read/modify/write cycle. We
> 1626 * use a version assertion to redrive the thing if something
> 1627 * changes in between.
> 1628 */
> 1629 first = pos != write_pos;
> 1630 last = (pos + len) != (write_pos + write_len);
> 1631 rmw = first || last;
> 1632
> 1633 dout("sync_write ino %llx %lld~%llu adjusted %lld~%llu -- %srmw\n",
> 1634 ci->i_vino.ino, pos, len, write_pos, write_len, rmw ? "" : "no ");
> 1635
> 1636 /*
> 1637 * The data is emplaced into the page as it would be if it were in
> 1638 * an array of pagecache pages.
> 1639 */
> 1640 num_pages = calc_pages_for(write_pos, write_len);
> 1641 pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
> 1642 if (IS_ERR(pages)) {
> 1643 ret = PTR_ERR(pages);
> 1644 break;
> 1645 }
> 1646
> 1647 /* Do we need to preload the pages? */
> 1648 if (rmw) {
> 1649 u64 first_pos = write_pos;
> 1650 u64 last_pos = (write_pos + write_len) - CEPH_FSCRYPT_BLOCK_SIZE;
> 1651 u64 read_len = CEPH_FSCRYPT_BLOCK_SIZE;
> 1652 struct ceph_osd_req_op *op;
> 1653
> 1654 /* We should only need to do this for encrypted inodes */
> 1655 WARN_ON_ONCE(!IS_ENCRYPTED(inode));
> 1656
> 1657 /* No need to do two reads if first and last blocks are same */
> 1658 if (first && last_pos == first_pos)
> 1659 last = false;
> 1660
> 1661 /*
> 1662 * Allocate a read request for one or two extents, depending
> 1663 * on how the request was aligned.
> 1664 */
> 1665 req = ceph_osdc_new_request(osdc, &ci->i_layout,
> 1666 ci->i_vino, first ? first_pos : last_pos,
> 1667 &read_len, 0, (first && last) ? 2 : 1,
> 1668 CEPH_OSD_OP_SPARSE_READ, CEPH_OSD_FLAG_READ,
> 1669 NULL, ci->i_truncate_seq,
> 1670 ci->i_truncate_size, false);
> 1671 if (IS_ERR(req)) {
> 1672 ceph_release_page_vector(pages, num_pages);
> 1673 ret = PTR_ERR(req);
> 1674 break;
> 1675 }
> 1676
> 1677 /* Something is misaligned! */
> 1678 if (read_len != CEPH_FSCRYPT_BLOCK_SIZE) {
> 1679 ceph_osdc_put_request(req);
> 1680 ceph_release_page_vector(pages, num_pages);
> 1681 ret = -EIO;
> 1682 break;
> 1683 }
> 1684
> 1685 /* Add extent for first block? */
> 1686 op = &req->r_ops[0];
> 1687
> 1688 if (first) {
> 1689 osd_req_op_extent_osd_data_pages(req, 0, pages,
> 1690 CEPH_FSCRYPT_BLOCK_SIZE,
> 1691 offset_in_page(first_pos),
> 1692 false, false);
> 1693 /* We only expect a single extent here */
> 1694 ret = __ceph_alloc_sparse_ext_map(op, 1);
> 1695 if (ret) {
> 1696 ceph_osdc_put_request(req);
> 1697 ceph_release_page_vector(pages, num_pages);
> 1698 break;
> 1699 }
> 1700 }
> 1701
> 1702 /* Add extent for last block */
> 1703 if (last) {
> 1704 /* Init the other extent if first extent has been used */
> 1705 if (first) {
> 1706 op = &req->r_ops[1];
> 1707 osd_req_op_extent_init(req, 1, CEPH_OSD_OP_SPARSE_READ,
> 1708 last_pos, CEPH_FSCRYPT_BLOCK_SIZE,
> 1709 ci->i_truncate_size,
> 1710 ci->i_truncate_seq);
> 1711 }
> 1712
> 1713 ret = __ceph_alloc_sparse_ext_map(op, 1);
> 1714 if (ret) {
> 1715 ceph_osdc_put_request(req);
> 1716 ceph_release_page_vector(pages, num_pages);
> 1717 break;
> 1718 }
> 1719
> 1720 osd_req_op_extent_osd_data_pages(req, first ? 1 : 0,
> 1721 &pages[num_pages - 1],
> 1722 CEPH_FSCRYPT_BLOCK_SIZE,
> 1723 offset_in_page(last_pos),
> 1724 false, false);
> 1725 }
> 1726
>> 1727 ret = ceph_osdc_start_request(osdc, req, false);
> 1728 if (!ret)
> 1729 ret = ceph_osdc_wait_request(osdc, req);
> 1730
> 1731 /* FIXME: length field is wrong if there are 2 extents */
> 1732 ceph_update_read_metrics(&fsc->mdsc->metric,
> 1733 req->r_start_latency,
> 1734 req->r_end_latency,
> 1735 read_len, ret);
> 1736
> 1737 /* Ok if object is not already present */
> 1738 if (ret == -ENOENT) {
> 1739 /*
> 1740 * If there is no object, then we can't assert
> 1741 * on its version. Set it to 0, and we'll use an
> 1742 * exclusive create instead.
> 1743 */
> 1744 ceph_osdc_put_request(req);
> 1745 ret = 0;
> 1746
> 1747 /*
> 1748 * zero out the soon-to-be uncopied parts of the
> 1749 * first and last pages.
> 1750 */
> 1751 if (first)
> 1752 zero_user_segment(pages[0], 0,
> 1753 offset_in_page(first_pos));
> 1754 if (last)
> 1755 zero_user_segment(pages[num_pages - 1],
> 1756 offset_in_page(last_pos),
> 1757 PAGE_SIZE);
> 1758 } else {
> 1759 if (ret < 0) {
> 1760 ceph_osdc_put_request(req);
> 1761 ceph_release_page_vector(pages, num_pages);
> 1762 break;
> 1763 }
> 1764
> 1765 op = &req->r_ops[0];
> 1766 if (op->extent.sparse_ext_cnt == 0) {
> 1767 if (first)
> 1768 zero_user_segment(pages[0], 0,
> 1769 offset_in_page(first_pos));
> 1770 else
> 1771 zero_user_segment(pages[num_pages - 1],
> 1772 offset_in_page(last_pos),
> 1773 PAGE_SIZE);
> 1774 } else if (op->extent.sparse_ext_cnt != 1 ||
> 1775 ceph_sparse_ext_map_end(op) !=
> 1776 CEPH_FSCRYPT_BLOCK_SIZE) {
> 1777 ret = -EIO;
> 1778 ceph_osdc_put_request(req);
> 1779 ceph_release_page_vector(pages, num_pages);
> 1780 break;
> 1781 }
> 1782
> 1783 if (first && last) {
> 1784 op = &req->r_ops[1];
> 1785 if (op->extent.sparse_ext_cnt == 0) {
> 1786 zero_user_segment(pages[num_pages - 1],
> 1787 offset_in_page(last_pos),
> 1788 PAGE_SIZE);
> 1789 } else if (op->extent.sparse_ext_cnt != 1 ||
> 1790 ceph_sparse_ext_map_end(op) !=
> 1791 CEPH_FSCRYPT_BLOCK_SIZE) {
> 1792 ret = -EIO;
> 1793 ceph_osdc_put_request(req);
> 1794 ceph_release_page_vector(pages, num_pages);
> 1795 break;
> 1796 }
> 1797 }
> 1798
> 1799 /* Grab assert version. It must be non-zero. */
> 1800 assert_ver = req->r_version;
> 1801 WARN_ON_ONCE(ret > 0 && assert_ver == 0);
> 1802
> 1803 ceph_osdc_put_request(req);
> 1804 if (first) {
> 1805 ret = ceph_fscrypt_decrypt_block_inplace(inode,
> 1806 pages[0],
> 1807 CEPH_FSCRYPT_BLOCK_SIZE,
> 1808 offset_in_page(first_pos),
> 1809 first_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
> 1810 if (ret < 0) {
> 1811 ceph_release_page_vector(pages, num_pages);
> 1812 break;
> 1813 }
> 1814 }
> 1815 if (last) {
> 1816 ret = ceph_fscrypt_decrypt_block_inplace(inode,
> 1817 pages[num_pages - 1],
> 1818 CEPH_FSCRYPT_BLOCK_SIZE,
> 1819 offset_in_page(last_pos),
> 1820 last_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
> 1821 if (ret < 0) {
> 1822 ceph_release_page_vector(pages, num_pages);
> 1823 break;
> 1824 }
> 1825 }
> 1826 }
> 1827 }
> 1828
> 1829 left = len;
> 1830 off = offset_in_page(pos);
> 1831 for (n = 0; n < num_pages; n++) {
> 1832 size_t plen = min_t(size_t, left, PAGE_SIZE - off);
> 1833
> 1834 /* copy the data */
> 1835 ret = copy_page_from_iter(pages[n], off, plen, from);
> 1836 if (ret != plen) {
> 1837 ret = -EFAULT;
> 1838 break;
> 1839 }
> 1840 off = 0;
> 1841 left -= ret;
> 1842 }
> 1843 if (ret < 0) {
> 1844 dout("sync_write write failed with %d\n", ret);
> 1845 ceph_release_page_vector(pages, num_pages);
> 1846 break;
> 1847 }
> 1848
> 1849 if (IS_ENCRYPTED(inode)) {
> 1850 ret = ceph_fscrypt_encrypt_pages(inode, pages,
> 1851 write_pos, write_len,
> 1852 GFP_KERNEL);
> 1853 if (ret < 0) {
> 1854 dout("encryption failed with %d\n", ret);
> 1855 ceph_release_page_vector(pages, num_pages);
> 1856 break;
> 1857 }
> 1858 }
> 1859
> 1860 req = ceph_osdc_new_request(osdc, &ci->i_layout,
> 1861 ci->i_vino, write_pos, &write_len,
> 1862 rmw ? 1 : 0, rmw ? 2 : 1,
> 1863 CEPH_OSD_OP_WRITE,
> 1864 CEPH_OSD_FLAG_WRITE,
> 1865 snapc, ci->i_truncate_seq,
> 1866 ci->i_truncate_size, false);
> 1867 if (IS_ERR(req)) {
> 1868 ret = PTR_ERR(req);
> 1869 ceph_release_page_vector(pages, num_pages);
> 1870 break;
> 1871 }
> 1872
> 1873 dout("sync_write write op %lld~%llu\n", write_pos, write_len);
> 1874 osd_req_op_extent_osd_data_pages(req, rmw ? 1 : 0, pages, write_len,
> 1875 offset_in_page(write_pos), false,
> 1876 true);
> 1877 req->r_inode = inode;
> 1878 req->r_mtime = mtime;
> 1879
> 1880 /* Set up the assertion */
> 1881 if (rmw) {
> 1882 /*
> 1883 * Set up the assertion. If we don't have a version number,
> 1884 * then the object doesn't exist yet. Use an exclusive create
> 1885 * instead of a version assertion in that case.
> 1886 */
> 1887 if (assert_ver) {
> 1888 osd_req_op_init(req, 0, CEPH_OSD_OP_ASSERT_VER, 0);
> 1889 req->r_ops[0].assert_ver.ver = assert_ver;
> 1890 } else {
> 1891 osd_req_op_init(req, 0, CEPH_OSD_OP_CREATE,
> 1892 CEPH_OSD_OP_FLAG_EXCL);
> 1893 }
> 1894 }
> 1895
> 1896 ceph_osdc_start_request(osdc, req, false);
> 1897
> 1898 ceph_update_write_metrics(&fsc->mdsc->metric, req->r_start_latency,
> 1899 req->r_end_latency, len, ret);
> 1900 ceph_osdc_put_request(req);
> 1901 if (ret != 0) {
> 1902 dout("sync_write osd write returned %d\n", ret);
> 1903 /* Version changed! Must re-do the rmw cycle */
> 1904 if ((assert_ver && (ret == -ERANGE || ret == -EOVERFLOW)) ||
> 1905 (!assert_ver && ret == -EEXIST)) {
> 1906 /* We should only ever see this on a rmw */
> 1907 WARN_ON_ONCE(!rmw);
> 1908
> 1909 /* The version should never go backward */
> 1910 WARN_ON_ONCE(ret == -EOVERFLOW);
> 1911
> 1912 *from = saved_iter;
> 1913
> 1914 /* FIXME: limit number of times we loop? */
> 1915 continue;
> 1916 }
> 1917 ceph_set_error_write(ci);
> 1918 break;
> 1919 }
> 1920 ceph_clear_error_write(ci);
> 1921 pos += len;
> 1922 written += len;
> 1923 dout("sync_write written %d\n", written);
> 1924 if (pos > i_size_read(inode)) {
> 1925 check_caps = ceph_inode_set_size(inode, pos);
> 1926 if (check_caps)
> 1927 ceph_check_caps(ceph_inode(inode),
> 1928 CHECK_CAPS_AUTHONLY,
> 1929 NULL);
> 1930 }
> 1931
> 1932 }
> 1933
> 1934 if (ret != -EOLDSNAPC && written > 0) {
> 1935 ret = written;
> 1936 iocb->ki_pos = pos;
> 1937 }
> 1938 dout("sync_write returning %d\n", ret);
> 1939 return ret;
> 1940 }
> 1941
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [ceph-client:wip-fscrypt 48/59] fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3
@ 2022-07-06 12:44 ` Xiubo Li
0 siblings, 0 replies; 3+ messages in thread
From: Xiubo Li @ 2022-07-06 12:44 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 17223 bytes --]
Fixed it in the wip-fscrypt branch.
Thanks!
On 7/6/22 7:04 PM, kernel test robot wrote:
> tree: https://github.com/ceph/ceph-client.git wip-fscrypt
> head: 55b265c1fd41c55be5e56d9eb4b24da48ac04a8c
> commit: 3c062ae4472df769c1a740ed55ccc252f9e104c1 [48/59] ceph: add read/modify/write to ceph_sync_write
> config: i386-randconfig-a006 (https://download.01.org/0day-ci/archive/20220706/202207061958.I86cqkif-lkp(a)intel.com/config)
> compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f553287b588916de09c66e3e32bf75e5060f967f)
> reproduce (this is a W=1 build):
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # https://github.com/ceph/ceph-client/commit/3c062ae4472df769c1a740ed55ccc252f9e104c1
> git remote add ceph-client https://github.com/ceph/ceph-client.git
> git fetch --no-tags ceph-client wip-fscrypt
> git checkout 3c062ae4472df769c1a740ed55ccc252f9e104c1
> # save the config file
> mkdir build_dir && cp config build_dir/.config
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash fs/ceph/
>
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>>> fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3
> ret = ceph_osdc_start_request(osdc, req, false);
> ~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
> include/linux/ceph/osd_client.h:583:6: note: 'ceph_osdc_start_request' declared here
> void ceph_osdc_start_request(struct ceph_osd_client *osdc,
> ^
> fs/ceph/file.c:1896:38: error: too many arguments to function call, expected 2, have 3
> ceph_osdc_start_request(osdc, req, false);
> ~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
> include/linux/ceph/osd_client.h:583:6: note: 'ceph_osdc_start_request' declared here
> void ceph_osdc_start_request(struct ceph_osd_client *osdc,
> ^
> 2 errors generated.
>
>
> vim +1727 fs/ceph/file.c
>
> 1553
> 1554 /*
> 1555 * Synchronous write, straight from __user pointer or user pages.
> 1556 *
> 1557 * If write spans object boundary, just do multiple writes. (For a
> 1558 * correct atomic write, we should e.g. take write locks on all
> 1559 * objects, rollback on failure, etc.)
> 1560 */
> 1561 static ssize_t
> 1562 ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
> 1563 struct ceph_snap_context *snapc)
> 1564 {
> 1565 struct file *file = iocb->ki_filp;
> 1566 struct inode *inode = file_inode(file);
> 1567 struct ceph_inode_info *ci = ceph_inode(inode);
> 1568 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
> 1569 struct ceph_osd_client *osdc = &fsc->client->osdc;
> 1570 struct ceph_osd_request *req;
> 1571 struct page **pages;
> 1572 u64 len;
> 1573 int num_pages;
> 1574 int written = 0;
> 1575 int ret;
> 1576 bool check_caps = false;
> 1577 struct timespec64 mtime = current_time(inode);
> 1578 size_t count = iov_iter_count(from);
> 1579
> 1580 if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
> 1581 return -EROFS;
> 1582
> 1583 dout("sync_write on file %p %lld~%u snapc %p seq %lld\n",
> 1584 file, pos, (unsigned)count, snapc, snapc->seq);
> 1585
> 1586 ret = filemap_write_and_wait_range(inode->i_mapping,
> 1587 pos, pos + count - 1);
> 1588 if (ret < 0)
> 1589 return ret;
> 1590
> 1591 ceph_fscache_invalidate(inode, false);
> 1592 ret = invalidate_inode_pages2_range(inode->i_mapping,
> 1593 pos >> PAGE_SHIFT,
> 1594 (pos + count - 1) >> PAGE_SHIFT);
> 1595 if (ret < 0)
> 1596 dout("invalidate_inode_pages2_range returned %d\n", ret);
> 1597
> 1598 while ((len = iov_iter_count(from)) > 0) {
> 1599 size_t left;
> 1600 int n;
> 1601 u64 write_pos = pos;
> 1602 u64 write_len = len;
> 1603 u64 objnum, objoff;
> 1604 u32 xlen;
> 1605 u64 assert_ver = 0;
> 1606 bool rmw;
> 1607 bool first, last;
> 1608 struct iov_iter saved_iter = *from;
> 1609 size_t off;
> 1610
> 1611 ceph_fscrypt_adjust_off_and_len(inode, &write_pos, &write_len);
> 1612
> 1613 /* clamp the length to the end of first object */
> 1614 ceph_calc_file_object_mapping(&ci->i_layout, write_pos,
> 1615 write_len, &objnum, &objoff,
> 1616 &xlen);
> 1617 write_len = xlen;
> 1618
> 1619 /* adjust len downward if it goes beyond current object */
> 1620 if (pos + len > write_pos + write_len)
> 1621 len = write_pos + write_len - pos;
> 1622
> 1623 /*
> 1624 * If we had to adjust the length or position to align with a
> 1625 * crypto block, then we must do a read/modify/write cycle. We
> 1626 * use a version assertion to redrive the thing if something
> 1627 * changes in between.
> 1628 */
> 1629 first = pos != write_pos;
> 1630 last = (pos + len) != (write_pos + write_len);
> 1631 rmw = first || last;
> 1632
> 1633 dout("sync_write ino %llx %lld~%llu adjusted %lld~%llu -- %srmw\n",
> 1634 ci->i_vino.ino, pos, len, write_pos, write_len, rmw ? "" : "no ");
> 1635
> 1636 /*
> 1637 * The data is emplaced into the page as it would be if it were in
> 1638 * an array of pagecache pages.
> 1639 */
> 1640 num_pages = calc_pages_for(write_pos, write_len);
> 1641 pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
> 1642 if (IS_ERR(pages)) {
> 1643 ret = PTR_ERR(pages);
> 1644 break;
> 1645 }
> 1646
> 1647 /* Do we need to preload the pages? */
> 1648 if (rmw) {
> 1649 u64 first_pos = write_pos;
> 1650 u64 last_pos = (write_pos + write_len) - CEPH_FSCRYPT_BLOCK_SIZE;
> 1651 u64 read_len = CEPH_FSCRYPT_BLOCK_SIZE;
> 1652 struct ceph_osd_req_op *op;
> 1653
> 1654 /* We should only need to do this for encrypted inodes */
> 1655 WARN_ON_ONCE(!IS_ENCRYPTED(inode));
> 1656
> 1657 /* No need to do two reads if first and last blocks are same */
> 1658 if (first && last_pos == first_pos)
> 1659 last = false;
> 1660
> 1661 /*
> 1662 * Allocate a read request for one or two extents, depending
> 1663 * on how the request was aligned.
> 1664 */
> 1665 req = ceph_osdc_new_request(osdc, &ci->i_layout,
> 1666 ci->i_vino, first ? first_pos : last_pos,
> 1667 &read_len, 0, (first && last) ? 2 : 1,
> 1668 CEPH_OSD_OP_SPARSE_READ, CEPH_OSD_FLAG_READ,
> 1669 NULL, ci->i_truncate_seq,
> 1670 ci->i_truncate_size, false);
> 1671 if (IS_ERR(req)) {
> 1672 ceph_release_page_vector(pages, num_pages);
> 1673 ret = PTR_ERR(req);
> 1674 break;
> 1675 }
> 1676
> 1677 /* Something is misaligned! */
> 1678 if (read_len != CEPH_FSCRYPT_BLOCK_SIZE) {
> 1679 ceph_osdc_put_request(req);
> 1680 ceph_release_page_vector(pages, num_pages);
> 1681 ret = -EIO;
> 1682 break;
> 1683 }
> 1684
> 1685 /* Add extent for first block? */
> 1686 op = &req->r_ops[0];
> 1687
> 1688 if (first) {
> 1689 osd_req_op_extent_osd_data_pages(req, 0, pages,
> 1690 CEPH_FSCRYPT_BLOCK_SIZE,
> 1691 offset_in_page(first_pos),
> 1692 false, false);
> 1693 /* We only expect a single extent here */
> 1694 ret = __ceph_alloc_sparse_ext_map(op, 1);
> 1695 if (ret) {
> 1696 ceph_osdc_put_request(req);
> 1697 ceph_release_page_vector(pages, num_pages);
> 1698 break;
> 1699 }
> 1700 }
> 1701
> 1702 /* Add extent for last block */
> 1703 if (last) {
> 1704 /* Init the other extent if first extent has been used */
> 1705 if (first) {
> 1706 op = &req->r_ops[1];
> 1707 osd_req_op_extent_init(req, 1, CEPH_OSD_OP_SPARSE_READ,
> 1708 last_pos, CEPH_FSCRYPT_BLOCK_SIZE,
> 1709 ci->i_truncate_size,
> 1710 ci->i_truncate_seq);
> 1711 }
> 1712
> 1713 ret = __ceph_alloc_sparse_ext_map(op, 1);
> 1714 if (ret) {
> 1715 ceph_osdc_put_request(req);
> 1716 ceph_release_page_vector(pages, num_pages);
> 1717 break;
> 1718 }
> 1719
> 1720 osd_req_op_extent_osd_data_pages(req, first ? 1 : 0,
> 1721 &pages[num_pages - 1],
> 1722 CEPH_FSCRYPT_BLOCK_SIZE,
> 1723 offset_in_page(last_pos),
> 1724 false, false);
> 1725 }
> 1726
>> 1727 ret = ceph_osdc_start_request(osdc, req, false);
> 1728 if (!ret)
> 1729 ret = ceph_osdc_wait_request(osdc, req);
> 1730
> 1731 /* FIXME: length field is wrong if there are 2 extents */
> 1732 ceph_update_read_metrics(&fsc->mdsc->metric,
> 1733 req->r_start_latency,
> 1734 req->r_end_latency,
> 1735 read_len, ret);
> 1736
> 1737 /* Ok if object is not already present */
> 1738 if (ret == -ENOENT) {
> 1739 /*
> 1740 * If there is no object, then we can't assert
> 1741 * on its version. Set it to 0, and we'll use an
> 1742 * exclusive create instead.
> 1743 */
> 1744 ceph_osdc_put_request(req);
> 1745 ret = 0;
> 1746
> 1747 /*
> 1748 * zero out the soon-to-be uncopied parts of the
> 1749 * first and last pages.
> 1750 */
> 1751 if (first)
> 1752 zero_user_segment(pages[0], 0,
> 1753 offset_in_page(first_pos));
> 1754 if (last)
> 1755 zero_user_segment(pages[num_pages - 1],
> 1756 offset_in_page(last_pos),
> 1757 PAGE_SIZE);
> 1758 } else {
> 1759 if (ret < 0) {
> 1760 ceph_osdc_put_request(req);
> 1761 ceph_release_page_vector(pages, num_pages);
> 1762 break;
> 1763 }
> 1764
> 1765 op = &req->r_ops[0];
> 1766 if (op->extent.sparse_ext_cnt == 0) {
> 1767 if (first)
> 1768 zero_user_segment(pages[0], 0,
> 1769 offset_in_page(first_pos));
> 1770 else
> 1771 zero_user_segment(pages[num_pages - 1],
> 1772 offset_in_page(last_pos),
> 1773 PAGE_SIZE);
> 1774 } else if (op->extent.sparse_ext_cnt != 1 ||
> 1775 ceph_sparse_ext_map_end(op) !=
> 1776 CEPH_FSCRYPT_BLOCK_SIZE) {
> 1777 ret = -EIO;
> 1778 ceph_osdc_put_request(req);
> 1779 ceph_release_page_vector(pages, num_pages);
> 1780 break;
> 1781 }
> 1782
> 1783 if (first && last) {
> 1784 op = &req->r_ops[1];
> 1785 if (op->extent.sparse_ext_cnt == 0) {
> 1786 zero_user_segment(pages[num_pages - 1],
> 1787 offset_in_page(last_pos),
> 1788 PAGE_SIZE);
> 1789 } else if (op->extent.sparse_ext_cnt != 1 ||
> 1790 ceph_sparse_ext_map_end(op) !=
> 1791 CEPH_FSCRYPT_BLOCK_SIZE) {
> 1792 ret = -EIO;
> 1793 ceph_osdc_put_request(req);
> 1794 ceph_release_page_vector(pages, num_pages);
> 1795 break;
> 1796 }
> 1797 }
> 1798
> 1799 /* Grab assert version. It must be non-zero. */
> 1800 assert_ver = req->r_version;
> 1801 WARN_ON_ONCE(ret > 0 && assert_ver == 0);
> 1802
> 1803 ceph_osdc_put_request(req);
> 1804 if (first) {
> 1805 ret = ceph_fscrypt_decrypt_block_inplace(inode,
> 1806 pages[0],
> 1807 CEPH_FSCRYPT_BLOCK_SIZE,
> 1808 offset_in_page(first_pos),
> 1809 first_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
> 1810 if (ret < 0) {
> 1811 ceph_release_page_vector(pages, num_pages);
> 1812 break;
> 1813 }
> 1814 }
> 1815 if (last) {
> 1816 ret = ceph_fscrypt_decrypt_block_inplace(inode,
> 1817 pages[num_pages - 1],
> 1818 CEPH_FSCRYPT_BLOCK_SIZE,
> 1819 offset_in_page(last_pos),
> 1820 last_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
> 1821 if (ret < 0) {
> 1822 ceph_release_page_vector(pages, num_pages);
> 1823 break;
> 1824 }
> 1825 }
> 1826 }
> 1827 }
> 1828
> 1829 left = len;
> 1830 off = offset_in_page(pos);
> 1831 for (n = 0; n < num_pages; n++) {
> 1832 size_t plen = min_t(size_t, left, PAGE_SIZE - off);
> 1833
> 1834 /* copy the data */
> 1835 ret = copy_page_from_iter(pages[n], off, plen, from);
> 1836 if (ret != plen) {
> 1837 ret = -EFAULT;
> 1838 break;
> 1839 }
> 1840 off = 0;
> 1841 left -= ret;
> 1842 }
> 1843 if (ret < 0) {
> 1844 dout("sync_write write failed with %d\n", ret);
> 1845 ceph_release_page_vector(pages, num_pages);
> 1846 break;
> 1847 }
> 1848
> 1849 if (IS_ENCRYPTED(inode)) {
> 1850 ret = ceph_fscrypt_encrypt_pages(inode, pages,
> 1851 write_pos, write_len,
> 1852 GFP_KERNEL);
> 1853 if (ret < 0) {
> 1854 dout("encryption failed with %d\n", ret);
> 1855 ceph_release_page_vector(pages, num_pages);
> 1856 break;
> 1857 }
> 1858 }
> 1859
> 1860 req = ceph_osdc_new_request(osdc, &ci->i_layout,
> 1861 ci->i_vino, write_pos, &write_len,
> 1862 rmw ? 1 : 0, rmw ? 2 : 1,
> 1863 CEPH_OSD_OP_WRITE,
> 1864 CEPH_OSD_FLAG_WRITE,
> 1865 snapc, ci->i_truncate_seq,
> 1866 ci->i_truncate_size, false);
> 1867 if (IS_ERR(req)) {
> 1868 ret = PTR_ERR(req);
> 1869 ceph_release_page_vector(pages, num_pages);
> 1870 break;
> 1871 }
> 1872
> 1873 dout("sync_write write op %lld~%llu\n", write_pos, write_len);
> 1874 osd_req_op_extent_osd_data_pages(req, rmw ? 1 : 0, pages, write_len,
> 1875 offset_in_page(write_pos), false,
> 1876 true);
> 1877 req->r_inode = inode;
> 1878 req->r_mtime = mtime;
> 1879
> 1880 /* Set up the assertion */
> 1881 if (rmw) {
> 1882 /*
> 1883 * Set up the assertion. If we don't have a version number,
> 1884 * then the object doesn't exist yet. Use an exclusive create
> 1885 * instead of a version assertion in that case.
> 1886 */
> 1887 if (assert_ver) {
> 1888 osd_req_op_init(req, 0, CEPH_OSD_OP_ASSERT_VER, 0);
> 1889 req->r_ops[0].assert_ver.ver = assert_ver;
> 1890 } else {
> 1891 osd_req_op_init(req, 0, CEPH_OSD_OP_CREATE,
> 1892 CEPH_OSD_OP_FLAG_EXCL);
> 1893 }
> 1894 }
> 1895
> 1896 ceph_osdc_start_request(osdc, req, false);
> 1897
> 1898 ceph_update_write_metrics(&fsc->mdsc->metric, req->r_start_latency,
> 1899 req->r_end_latency, len, ret);
> 1900 ceph_osdc_put_request(req);
> 1901 if (ret != 0) {
> 1902 dout("sync_write osd write returned %d\n", ret);
> 1903 /* Version changed! Must re-do the rmw cycle */
> 1904 if ((assert_ver && (ret == -ERANGE || ret == -EOVERFLOW)) ||
> 1905 (!assert_ver && ret == -EEXIST)) {
> 1906 /* We should only ever see this on a rmw */
> 1907 WARN_ON_ONCE(!rmw);
> 1908
> 1909 /* The version should never go backward */
> 1910 WARN_ON_ONCE(ret == -EOVERFLOW);
> 1911
> 1912 *from = saved_iter;
> 1913
> 1914 /* FIXME: limit number of times we loop? */
> 1915 continue;
> 1916 }
> 1917 ceph_set_error_write(ci);
> 1918 break;
> 1919 }
> 1920 ceph_clear_error_write(ci);
> 1921 pos += len;
> 1922 written += len;
> 1923 dout("sync_write written %d\n", written);
> 1924 if (pos > i_size_read(inode)) {
> 1925 check_caps = ceph_inode_set_size(inode, pos);
> 1926 if (check_caps)
> 1927 ceph_check_caps(ceph_inode(inode),
> 1928 CHECK_CAPS_AUTHONLY,
> 1929 NULL);
> 1930 }
> 1931
> 1932 }
> 1933
> 1934 if (ret != -EOLDSNAPC && written > 0) {
> 1935 ret = written;
> 1936 iocb->ki_pos = pos;
> 1937 }
> 1938 dout("sync_write returning %d\n", ret);
> 1939 return ret;
> 1940 }
> 1941
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-07-06 12:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-06 11:04 [ceph-client:wip-fscrypt 48/59] fs/ceph/file.c:1727:45: error: too many arguments to function call, expected 2, have 3 kernel test robot
2022-07-06 12:44 ` Xiubo Li
2022-07-06 12:44 ` Xiubo Li
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.