Commit b6af1bcd8720cb3062c8c4d4c8ba02bee10ff03f

Authored by Nick Piggin
Committed by Linus Torvalds
1 parent f2b6a16eb8

ocfs2: convert to new aops

Plug ocfs2 into the ->write_begin and ->write_end aops.

A bunch of custom code is now gone - the iovec iteration stuff during write
and the ocfs2 splice write actor.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 22 additions and 266 deletions Side-by-side Diff

... ... @@ -1724,9 +1724,9 @@
1724 1724 return ret;
1725 1725 }
1726 1726  
1727   -int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1728   - loff_t pos, unsigned len, unsigned flags,
1729   - struct page **pagep, void **fsdata)
  1727 +static int ocfs2_write_begin(struct file *file, struct address_space *mapping,
  1728 + loff_t pos, unsigned len, unsigned flags,
  1729 + struct page **pagep, void **fsdata)
1730 1730 {
1731 1731 int ret;
1732 1732 struct buffer_head *di_bh = NULL;
... ... @@ -1877,9 +1877,9 @@
1877 1877 return copied;
1878 1878 }
1879 1879  
1880   -int ocfs2_write_end(struct file *file, struct address_space *mapping,
1881   - loff_t pos, unsigned len, unsigned copied,
1882   - struct page *page, void *fsdata)
  1880 +static int ocfs2_write_end(struct file *file, struct address_space *mapping,
  1881 + loff_t pos, unsigned len, unsigned copied,
  1882 + struct page *page, void *fsdata)
1883 1883 {
1884 1884 int ret;
1885 1885 struct inode *inode = mapping->host;
... ... @@ -1896,6 +1896,8 @@
1896 1896 const struct address_space_operations ocfs2_aops = {
1897 1897 .readpage = ocfs2_readpage,
1898 1898 .writepage = ocfs2_writepage,
  1899 + .write_begin = ocfs2_write_begin,
  1900 + .write_end = ocfs2_write_end,
1899 1901 .bmap = ocfs2_bmap,
1900 1902 .sync_page = block_sync_page,
1901 1903 .direct_IO = ocfs2_direct_IO,
... ... @@ -44,14 +44,6 @@
44 44 int (*fn)( handle_t *handle,
45 45 struct buffer_head *bh));
46 46  
47   -int ocfs2_write_begin(struct file *file, struct address_space *mapping,
48   - loff_t pos, unsigned len, unsigned flags,
49   - struct page **pagep, void **fsdata);
50   -
51   -int ocfs2_write_end(struct file *file, struct address_space *mapping,
52   - loff_t pos, unsigned len, unsigned copied,
53   - struct page *page, void *fsdata);
54   -
55 47 int ocfs2_write_end_nolock(struct address_space *mapping,
56 48 loff_t pos, unsigned len, unsigned copied,
57 49 struct page *page, void *fsdata);
... ... @@ -1881,143 +1881,13 @@
1881 1881 return ret;
1882 1882 }
1883 1883  
1884   -static inline void
1885   -ocfs2_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
1886   -{
1887   - const struct iovec *iov = *iovp;
1888   - size_t base = *basep;
1889   -
1890   - do {
1891   - int copy = min(bytes, iov->iov_len - base);
1892   -
1893   - bytes -= copy;
1894   - base += copy;
1895   - if (iov->iov_len == base) {
1896   - iov++;
1897   - base = 0;
1898   - }
1899   - } while (bytes);
1900   - *iovp = iov;
1901   - *basep = base;
1902   -}
1903   -
1904   -static struct page * ocfs2_get_write_source(char **ret_src_buf,
1905   - const struct iovec *cur_iov,
1906   - size_t iov_offset)
1907   -{
1908   - int ret;
1909   - char *buf = cur_iov->iov_base + iov_offset;
1910   - struct page *src_page = NULL;
1911   - unsigned long off;
1912   -
1913   - off = (unsigned long)(buf) & ~PAGE_CACHE_MASK;
1914   -
1915   - if (!segment_eq(get_fs(), KERNEL_DS)) {
1916   - /*
1917   - * Pull in the user page. We want to do this outside
1918   - * of the meta data locks in order to preserve locking
1919   - * order in case of page fault.
1920   - */
1921   - ret = get_user_pages(current, current->mm,
1922   - (unsigned long)buf & PAGE_CACHE_MASK, 1,
1923   - 0, 0, &src_page, NULL);
1924   - if (ret == 1)
1925   - *ret_src_buf = kmap(src_page) + off;
1926   - else
1927   - src_page = ERR_PTR(-EFAULT);
1928   - } else {
1929   - *ret_src_buf = buf;
1930   - }
1931   -
1932   - return src_page;
1933   -}
1934   -
1935   -static void ocfs2_put_write_source(struct page *page)
1936   -{
1937   - if (page) {
1938   - kunmap(page);
1939   - page_cache_release(page);
1940   - }
1941   -}
1942   -
1943   -static ssize_t ocfs2_file_buffered_write(struct file *file, loff_t *ppos,
1944   - const struct iovec *iov,
1945   - unsigned long nr_segs,
1946   - size_t count,
1947   - ssize_t o_direct_written)
1948   -{
1949   - int ret = 0;
1950   - ssize_t copied, total = 0;
1951   - size_t iov_offset = 0, bytes;
1952   - loff_t pos;
1953   - const struct iovec *cur_iov = iov;
1954   - struct page *user_page, *page;
1955   - char * uninitialized_var(buf);
1956   - char *dst;
1957   - void *fsdata;
1958   -
1959   - /*
1960   - * handle partial DIO write. Adjust cur_iov if needed.
1961   - */
1962   - ocfs2_set_next_iovec(&cur_iov, &iov_offset, o_direct_written);
1963   -
1964   - do {
1965   - pos = *ppos;
1966   -
1967   - user_page = ocfs2_get_write_source(&buf, cur_iov, iov_offset);
1968   - if (IS_ERR(user_page)) {
1969   - ret = PTR_ERR(user_page);
1970   - goto out;
1971   - }
1972   -
1973   - /* Stay within our page boundaries */
1974   - bytes = min((PAGE_CACHE_SIZE - ((unsigned long)pos & ~PAGE_CACHE_MASK)),
1975   - (PAGE_CACHE_SIZE - ((unsigned long)buf & ~PAGE_CACHE_MASK)));
1976   - /* Stay within the vector boundary */
1977   - bytes = min_t(size_t, bytes, cur_iov->iov_len - iov_offset);
1978   - /* Stay within count */
1979   - bytes = min(bytes, count);
1980   -
1981   - page = NULL;
1982   - ret = ocfs2_write_begin(file, file->f_mapping, pos, bytes, 0,
1983   - &page, &fsdata);
1984   - if (ret) {
1985   - mlog_errno(ret);
1986   - goto out;
1987   - }
1988   -
1989   - dst = kmap_atomic(page, KM_USER0);
1990   - memcpy(dst + (pos & (loff_t)(PAGE_CACHE_SIZE - 1)), buf, bytes);
1991   - kunmap_atomic(dst, KM_USER0);
1992   - flush_dcache_page(page);
1993   - ocfs2_put_write_source(user_page);
1994   -
1995   - copied = ocfs2_write_end(file, file->f_mapping, pos, bytes,
1996   - bytes, page, fsdata);
1997   - if (copied < 0) {
1998   - mlog_errno(copied);
1999   - ret = copied;
2000   - goto out;
2001   - }
2002   -
2003   - total += copied;
2004   - *ppos = pos + copied;
2005   - count -= copied;
2006   -
2007   - ocfs2_set_next_iovec(&cur_iov, &iov_offset, copied);
2008   - } while(count);
2009   -
2010   -out:
2011   - return total ? total : ret;
2012   -}
2013   -
2014 1884 static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2015 1885 const struct iovec *iov,
2016 1886 unsigned long nr_segs,
2017 1887 loff_t pos)
2018 1888 {
2019 1889 int ret, direct_io, appending, rw_level, have_alloc_sem = 0;
2020   - int can_do_direct, sync = 0;
  1890 + int can_do_direct;
2021 1891 ssize_t written = 0;
2022 1892 size_t ocount; /* original count */
2023 1893 size_t count; /* after file limit checks */
... ... @@ -2033,12 +1903,6 @@
2033 1903 if (iocb->ki_left == 0)
2034 1904 return 0;
2035 1905  
2036   - ret = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
2037   - if (ret)
2038   - return ret;
2039   -
2040   - count = ocount;
2041   -
2042 1906 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
2043 1907  
2044 1908 appending = file->f_flags & O_APPEND ? 1 : 0;
2045 1909  
2046 1910  
... ... @@ -2082,33 +1946,23 @@
2082 1946 rw_level = -1;
2083 1947  
2084 1948 direct_io = 0;
2085   - sync = 1;
2086 1949 goto relock;
2087 1950 }
2088 1951  
2089   - if (!sync && ((file->f_flags & O_SYNC) || IS_SYNC(inode)))
2090   - sync = 1;
2091   -
2092   - /*
2093   - * XXX: Is it ok to execute these checks a second time?
2094   - */
2095   - ret = generic_write_checks(file, ppos, &count, S_ISBLK(inode->i_mode));
2096   - if (ret)
2097   - goto out;
2098   -
2099   - /*
2100   - * Set pos so that sync_page_range_nolock() below understands
2101   - * where to start from. We might've moved it around via the
2102   - * calls above. The range we want to actually sync starts from
2103   - * *ppos here.
2104   - *
2105   - */
2106   - pos = *ppos;
2107   -
2108 1952 /* communicate with ocfs2_dio_end_io */
2109 1953 ocfs2_iocb_set_rw_locked(iocb, rw_level);
2110 1954  
2111 1955 if (direct_io) {
  1956 + ret = generic_segment_checks(iov, &nr_segs, &ocount,
  1957 + VERIFY_READ);
  1958 + if (ret)
  1959 + goto out_dio;
  1960 +
  1961 + ret = generic_write_checks(file, ppos, &count,
  1962 + S_ISBLK(inode->i_mode));
  1963 + if (ret)
  1964 + goto out_dio;
  1965 +
2112 1966 written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
2113 1967 ppos, count, ocount);
2114 1968 if (written < 0) {
... ... @@ -2116,14 +1970,8 @@
2116 1970 goto out_dio;
2117 1971 }
2118 1972 } else {
2119   - written = ocfs2_file_buffered_write(file, ppos, iov, nr_segs,
2120   - count, written);
2121   - if (written < 0) {
2122   - ret = written;
2123   - if (ret != -EFAULT || ret != -ENOSPC)
2124   - mlog_errno(ret);
2125   - goto out;
2126   - }
  1973 + written = generic_file_aio_write_nolock(iocb, iov, nr_segs,
  1974 + *ppos);
2127 1975 }
2128 1976  
2129 1977 out_dio:
2130 1978  
... ... @@ -2153,97 +2001,12 @@
2153 2001 if (have_alloc_sem)
2154 2002 up_read(&inode->i_alloc_sem);
2155 2003  
2156   - if (written > 0 && sync) {
2157   - ssize_t err;
2158   -
2159   - err = sync_page_range_nolock(inode, file->f_mapping, pos, count);
2160   - if (err < 0)
2161   - written = err;
2162   - }
2163   -
2164 2004 mutex_unlock(&inode->i_mutex);
2165 2005  
2166 2006 mlog_exit(ret);
2167 2007 return written ? written : ret;
2168 2008 }
2169 2009  
2170   -static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
2171   - struct pipe_buffer *buf,
2172   - struct splice_desc *sd)
2173   -{
2174   - int ret, count;
2175   - ssize_t copied = 0;
2176   - struct file *file = sd->u.file;
2177   - unsigned int offset;
2178   - struct page *page = NULL;
2179   - void *fsdata;
2180   - char *src, *dst;
2181   -
2182   - ret = buf->ops->confirm(pipe, buf);
2183   - if (ret)
2184   - goto out;
2185   -
2186   - offset = sd->pos & ~PAGE_CACHE_MASK;
2187   - count = sd->len;
2188   - if (count + offset > PAGE_CACHE_SIZE)
2189   - count = PAGE_CACHE_SIZE - offset;
2190   -
2191   - ret = ocfs2_write_begin(file, file->f_mapping, sd->pos, count, 0,
2192   - &page, &fsdata);
2193   - if (ret) {
2194   - mlog_errno(ret);
2195   - goto out;
2196   - }
2197   -
2198   - src = buf->ops->map(pipe, buf, 1);
2199   - dst = kmap_atomic(page, KM_USER1);
2200   - memcpy(dst + offset, src + buf->offset, count);
2201   - kunmap_atomic(dst, KM_USER1);
2202   - buf->ops->unmap(pipe, buf, src);
2203   -
2204   - copied = ocfs2_write_end(file, file->f_mapping, sd->pos, count, count,
2205   - page, fsdata);
2206   - if (copied < 0) {
2207   - mlog_errno(copied);
2208   - ret = copied;
2209   - goto out;
2210   - }
2211   -out:
2212   -
2213   - return copied ? copied : ret;
2214   -}
2215   -
2216   -static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
2217   - struct file *out,
2218   - loff_t *ppos,
2219   - size_t len,
2220   - unsigned int flags)
2221   -{
2222   - int ret, err;
2223   - struct address_space *mapping = out->f_mapping;
2224   - struct inode *inode = mapping->host;
2225   - struct splice_desc sd = {
2226   - .total_len = len,
2227   - .flags = flags,
2228   - .pos = *ppos,
2229   - .u.file = out,
2230   - };
2231   -
2232   - ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor);
2233   - if (ret > 0) {
2234   - *ppos += ret;
2235   -
2236   - if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
2237   - err = generic_osync_inode(inode, mapping,
2238   - OSYNC_METADATA|OSYNC_DATA);
2239   - if (err)
2240   - ret = err;
2241   - }
2242   - }
2243   -
2244   - return ret;
2245   -}
2246   -
2247 2010 static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
2248 2011 struct file *out,
2249 2012 loff_t *ppos,
... ... @@ -2273,8 +2036,7 @@
2273 2036 goto out_unlock;
2274 2037 }
2275 2038  
2276   - /* ok, we're done with i_size and alloc work */
2277   - ret = __ocfs2_file_splice_write(pipe, out, ppos, len, flags);
  2039 + ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
2278 2040  
2279 2041 out_unlock:
2280 2042 ocfs2_rw_unlock(inode, 1);