aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-04 12:14:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-04 12:14:01 -0400
commite1cc485262846dcad931bf85ee655cbbb815bfe6 (patch)
tree5b3ae42ce41f9fe0149ad49e9811ac8f8e8b2016 /fs/udf
parent4d6d367232813af09d9a1d90e3259e3ac42ee8a8 (diff)
parent09e05d4805e6c524c1af74e524e5d0528bb3fef3 (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.c9
-rw-r--r--fs/udf/inode.c59
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
121static 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
121const struct address_space_operations udf_adinicb_aops = { 129const 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
128static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 137static 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
98static 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
98static int udf_writepage(struct page *page, struct writeback_control *wbc) 114static 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
119static int udf_writepages(struct address_space *mapping,
120 struct writeback_control *wbc)
121{
122 return mpage_writepages(mapping, wbc, udf_get_block);
123}
124
103static int udf_readpage(struct file *file, struct page *page) 125static 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
148static 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