diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-04 12:14:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-04 12:14:01 -0400 |
commit | e1cc485262846dcad931bf85ee655cbbb815bfe6 (patch) | |
tree | 5b3ae42ce41f9fe0149ad49e9811ac8f8e8b2016 /fs/udf | |
parent | 4d6d367232813af09d9a1d90e3259e3ac42ee8a8 (diff) | |
parent | 09e05d4805e6c524c1af74e524e5d0528bb3fef3 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull ext3 & udf fixes from Jan Kara:
"Shortlog pretty much says it all.
The interesting bits are UDF support for direct IO and ext3 fix for a
long standing oops in data=journal mode."
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
jbd: Fix assertion failure in commit code due to lacking transaction credits
UDF: Add support for O_DIRECT
ext3: Replace 0 with NULL for pointer in super.c file
udf: add writepages support for udf
ext3: don't clear orphan list on ro mount with errors
reiserfs: Make reiserfs_xattr_handlers static
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/file.c | 9 | ||||
-rw-r--r-- | fs/udf/inode.c | 59 |
2 files changed, 52 insertions, 16 deletions
diff --git a/fs/udf/file.c b/fs/udf/file.c index d1c6093fd3d3..77b5953eaac8 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -118,11 +118,20 @@ static int udf_adinicb_write_end(struct file *file, | |||
118 | return simple_write_end(file, mapping, pos, len, copied, page, fsdata); | 118 | return simple_write_end(file, mapping, pos, len, copied, page, fsdata); |
119 | } | 119 | } |
120 | 120 | ||
121 | static ssize_t udf_adinicb_direct_IO(int rw, struct kiocb *iocb, | ||
122 | const struct iovec *iov, | ||
123 | loff_t offset, unsigned long nr_segs) | ||
124 | { | ||
125 | /* Fallback to buffered I/O. */ | ||
126 | return 0; | ||
127 | } | ||
128 | |||
121 | const struct address_space_operations udf_adinicb_aops = { | 129 | const struct address_space_operations udf_adinicb_aops = { |
122 | .readpage = udf_adinicb_readpage, | 130 | .readpage = udf_adinicb_readpage, |
123 | .writepage = udf_adinicb_writepage, | 131 | .writepage = udf_adinicb_writepage, |
124 | .write_begin = udf_adinicb_write_begin, | 132 | .write_begin = udf_adinicb_write_begin, |
125 | .write_end = udf_adinicb_write_end, | 133 | .write_end = udf_adinicb_write_end, |
134 | .direct_IO = udf_adinicb_direct_IO, | ||
126 | }; | 135 | }; |
127 | 136 | ||
128 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 137 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 287ef9f587b7..df88b957ccf0 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -95,11 +95,33 @@ void udf_evict_inode(struct inode *inode) | |||
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | static void udf_write_failed(struct address_space *mapping, loff_t to) | ||
99 | { | ||
100 | struct inode *inode = mapping->host; | ||
101 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
102 | loff_t isize = inode->i_size; | ||
103 | |||
104 | if (to > isize) { | ||
105 | truncate_pagecache(inode, to, isize); | ||
106 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||
107 | down_write(&iinfo->i_data_sem); | ||
108 | udf_truncate_extents(inode); | ||
109 | up_write(&iinfo->i_data_sem); | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
98 | static int udf_writepage(struct page *page, struct writeback_control *wbc) | 114 | static int udf_writepage(struct page *page, struct writeback_control *wbc) |
99 | { | 115 | { |
100 | return block_write_full_page(page, udf_get_block, wbc); | 116 | return block_write_full_page(page, udf_get_block, wbc); |
101 | } | 117 | } |
102 | 118 | ||
119 | static int udf_writepages(struct address_space *mapping, | ||
120 | struct writeback_control *wbc) | ||
121 | { | ||
122 | return mpage_writepages(mapping, wbc, udf_get_block); | ||
123 | } | ||
124 | |||
103 | static int udf_readpage(struct file *file, struct page *page) | 125 | static int udf_readpage(struct file *file, struct page *page) |
104 | { | 126 | { |
105 | return mpage_readpage(page, udf_get_block); | 127 | return mpage_readpage(page, udf_get_block); |
@@ -118,21 +140,24 @@ static int udf_write_begin(struct file *file, struct address_space *mapping, | |||
118 | int ret; | 140 | int ret; |
119 | 141 | ||
120 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); | 142 | ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block); |
121 | if (unlikely(ret)) { | 143 | if (unlikely(ret)) |
122 | struct inode *inode = mapping->host; | 144 | udf_write_failed(mapping, pos + len); |
123 | struct udf_inode_info *iinfo = UDF_I(inode); | 145 | return ret; |
124 | loff_t isize = inode->i_size; | 146 | } |
125 | |||
126 | if (pos + len > isize) { | ||
127 | truncate_pagecache(inode, pos + len, isize); | ||
128 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | ||
129 | down_write(&iinfo->i_data_sem); | ||
130 | udf_truncate_extents(inode); | ||
131 | up_write(&iinfo->i_data_sem); | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | 147 | ||
148 | static ssize_t udf_direct_IO(int rw, struct kiocb *iocb, | ||
149 | const struct iovec *iov, | ||
150 | loff_t offset, unsigned long nr_segs) | ||
151 | { | ||
152 | struct file *file = iocb->ki_filp; | ||
153 | struct address_space *mapping = file->f_mapping; | ||
154 | struct inode *inode = mapping->host; | ||
155 | ssize_t ret; | ||
156 | |||
157 | ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, | ||
158 | udf_get_block); | ||
159 | if (unlikely(ret < 0 && (rw & WRITE))) | ||
160 | udf_write_failed(mapping, offset + iov_length(iov, nr_segs)); | ||
136 | return ret; | 161 | return ret; |
137 | } | 162 | } |
138 | 163 | ||
@@ -145,8 +170,10 @@ const struct address_space_operations udf_aops = { | |||
145 | .readpage = udf_readpage, | 170 | .readpage = udf_readpage, |
146 | .readpages = udf_readpages, | 171 | .readpages = udf_readpages, |
147 | .writepage = udf_writepage, | 172 | .writepage = udf_writepage, |
148 | .write_begin = udf_write_begin, | 173 | .writepages = udf_writepages, |
149 | .write_end = generic_write_end, | 174 | .write_begin = udf_write_begin, |
175 | .write_end = generic_write_end, | ||
176 | .direct_IO = udf_direct_IO, | ||
150 | .bmap = udf_bmap, | 177 | .bmap = udf_bmap, |
151 | }; | 178 | }; |
152 | 179 | ||