aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-10-16 04:25:24 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:58 -0400
commitb6af1bcd8720cb3062c8c4d4c8ba02bee10ff03f (patch)
treee6cb27498f649dd3addc48fb4d92ac20ae8de7cb /fs/ocfs2/file.c
parentf2b6a16eb8f5b4851b01625a21e0c71207c2ce77 (diff)
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>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r--fs/ocfs2/file.c266
1 files changed, 14 insertions, 252 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index a62b14eb4065..f92fe91ff260 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1881,143 +1881,13 @@ out:
1881 return ret; 1881 return ret;
1882} 1882}
1883 1883
1884static inline void
1885ocfs2_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
1904static 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
1935static void ocfs2_put_write_source(struct page *page)
1936{
1937 if (page) {
1938 kunmap(page);
1939 page_cache_release(page);
1940 }
1941}
1942
1943static 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
2010out:
2011 return total ? total : ret;
2012}
2013
2014static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, 1884static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2015 const struct iovec *iov, 1885 const struct iovec *iov,
2016 unsigned long nr_segs, 1886 unsigned long nr_segs,
2017 loff_t pos) 1887 loff_t pos)
2018{ 1888{
2019 int ret, direct_io, appending, rw_level, have_alloc_sem = 0; 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 ssize_t written = 0; 1891 ssize_t written = 0;
2022 size_t ocount; /* original count */ 1892 size_t ocount; /* original count */
2023 size_t count; /* after file limit checks */ 1893 size_t count; /* after file limit checks */
@@ -2033,12 +1903,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2033 if (iocb->ki_left == 0) 1903 if (iocb->ki_left == 0)
2034 return 0; 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 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); 1906 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
2043 1907
2044 appending = file->f_flags & O_APPEND ? 1 : 0; 1908 appending = file->f_flags & O_APPEND ? 1 : 0;
@@ -2082,33 +1946,23 @@ relock:
2082 rw_level = -1; 1946 rw_level = -1;
2083 1947
2084 direct_io = 0; 1948 direct_io = 0;
2085 sync = 1;
2086 goto relock; 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 /* communicate with ocfs2_dio_end_io */ 1952 /* communicate with ocfs2_dio_end_io */
2109 ocfs2_iocb_set_rw_locked(iocb, rw_level); 1953 ocfs2_iocb_set_rw_locked(iocb, rw_level);
2110 1954
2111 if (direct_io) { 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 written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, 1966 written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
2113 ppos, count, ocount); 1967 ppos, count, ocount);
2114 if (written < 0) { 1968 if (written < 0) {
@@ -2116,14 +1970,8 @@ relock:
2116 goto out_dio; 1970 goto out_dio;
2117 } 1971 }
2118 } else { 1972 } else {
2119 written = ocfs2_file_buffered_write(file, ppos, iov, nr_segs, 1973 written = generic_file_aio_write_nolock(iocb, iov, nr_segs,
2120 count, written); 1974 *ppos);
2121 if (written < 0) {
2122 ret = written;
2123 if (ret != -EFAULT || ret != -ENOSPC)
2124 mlog_errno(ret);
2125 goto out;
2126 }
2127 } 1975 }
2128 1976
2129out_dio: 1977out_dio:
@@ -2153,97 +2001,12 @@ out_sems:
2153 if (have_alloc_sem) 2001 if (have_alloc_sem)
2154 up_read(&inode->i_alloc_sem); 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 mutex_unlock(&inode->i_mutex); 2004 mutex_unlock(&inode->i_mutex);
2165 2005
2166 mlog_exit(ret); 2006 mlog_exit(ret);
2167 return written ? written : ret; 2007 return written ? written : ret;
2168} 2008}
2169 2009
2170static 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 }
2211out:
2212
2213 return copied ? copied : ret;
2214}
2215
2216static 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
2247static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, 2010static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
2248 struct file *out, 2011 struct file *out,
2249 loff_t *ppos, 2012 loff_t *ppos,
@@ -2273,8 +2036,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
2273 goto out_unlock; 2036 goto out_unlock;
2274 } 2037 }
2275 2038
2276 /* ok, we're done with i_size and alloc work */ 2039 ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
2277 ret = __ocfs2_file_splice_write(pipe, out, ppos, len, flags);
2278 2040
2279out_unlock: 2041out_unlock:
2280 ocfs2_rw_unlock(inode, 1); 2042 ocfs2_rw_unlock(inode, 1);