aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ntfs/ChangeLog29
-rw-r--r--fs/ntfs/Makefile2
-rw-r--r--fs/ntfs/attrib.c6
-rw-r--r--fs/ntfs/file.c2
-rw-r--r--fs/ntfs/lcnalloc.c8
-rw-r--r--fs/ntfs/logfile.c5
6 files changed, 31 insertions, 21 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 1d2ad15f15..6d2a99c13d 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -2,20 +2,18 @@ ToDo/Notes:
2 - Find and fix bugs. 2 - Find and fix bugs.
3 - Checkpoint or disable the user space journal ($UsnJrnl). 3 - Checkpoint or disable the user space journal ($UsnJrnl).
4 - In between ntfs_prepare/commit_write, need exclusion between 4 - In between ntfs_prepare/commit_write, need exclusion between
5 simultaneous file extensions. Need perhaps an NInoResizeUnderway() 5 simultaneous file extensions. This is given to us by holding i_sem
6 flag which we can set in ntfs_prepare_write() and clear again in 6 on the inode. The only places in the kernel when a file is resized
7 ntfs_commit_write(). Just have to be careful in readpage/writepage, 7 are prepare/commit write and truncate for both of which i_sem is
8 as well as in truncate, that we play nice... We might need to have 8 held. Just have to be careful in readpage/writepage and all other
9 a data_size field in the ntfs_inode to store the real attribute 9 helpers not running under i_sem that we play nice...
10 length. Also need to be careful with initialized_size extention in 10 Also need to be careful with initialized_size extention in
11 ntfs_prepare_write. Basically, just be _very_ careful in this code... 11 ntfs_prepare_write. Basically, just be _very_ careful in this code...
12 OTOH, perhaps i_sem, which is held accross generic_file_write is 12 UPDATE: The only things that need to be checked are read/writepage
13 sufficient for synchronisation here. We then just need to make sure 13 which do not hold i_sem. Note writepage cannot change i_size but it
14 ntfs_readpage/writepage/truncate interoperate properly with us. 14 needs to cope with a concurrent i_size change, just like readpage.
15 UPDATE: The above is all ok as it is due to i_sem held. The only 15 Also both need to cope with concurrent changes to the other sizes,
16 thing that needs to be checked is ntfs_writepage() which does not 16 i.e. initialized/allocated/compressed size, as well.
17 hold i_sem. It cannot change i_size but it needs to cope with a
18 concurrent i_size change.
19 - Implement mft.c::sync_mft_mirror_umount(). We currently will just 17 - Implement mft.c::sync_mft_mirror_umount(). We currently will just
20 leave the volume dirty on umount if the final iput(vol->mft_ino) 18 leave the volume dirty on umount if the final iput(vol->mft_ino)
21 causes a write of any mirrored mft records due to the mft mirror 19 causes a write of any mirrored mft records due to the mft mirror
@@ -31,6 +29,11 @@ ToDo/Notes:
31 compiled without debug. This avoids a possible denial of service 29 compiled without debug. This avoids a possible denial of service
32 attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this 30 attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this
33 out. 31 out.
32 - Use i_size_read() in fs/ntfs/attrib.c::ntfs_attr_set().
33 - Use i_size_read() in fs/ntfs/logfile.c::ntfs_{check,empty}_logfile().
34 - Use i_size_read() once and then use the cached value in
35 fs/ntfs/lcnalloc.c::ntfs_cluster_alloc().
36 - Use i_size_read() in fs/ntfs/file.c::ntfs_file_open().
34 37
352.1.22 - Many bug and race fixes and error handling improvements. 382.1.22 - Many bug and race fixes and error handling improvements.
36 39
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
index 7b66381a0b..f8c97d4122 100644
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ 6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
7 unistr.o upcase.o 7 unistr.o upcase.o
8 8
9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.22\" 9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.23-WIP\"
10 10
11ifeq ($(CONFIG_NTFS_DEBUG),y) 11ifeq ($(CONFIG_NTFS_DEBUG),y)
12EXTRA_CFLAGS += -DDEBUG 12EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 1ff7f90a18..7d668466dc 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1127,6 +1127,10 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
1127 * byte offset @ofs inside the attribute with the constant byte @val. 1127 * byte offset @ofs inside the attribute with the constant byte @val.
1128 * 1128 *
1129 * This function is effectively like memset() applied to an ntfs attribute. 1129 * This function is effectively like memset() applied to an ntfs attribute.
1130 * Note thie function actually only operates on the page cache pages belonging
1131 * to the ntfs attribute and it marks them dirty after doing the memset().
1132 * Thus it relies on the vm dirty page write code paths to cause the modified
1133 * pages to be written to the mft record/disk.
1130 * 1134 *
1131 * Return 0 on success and -errno on error. An error code of -ESPIPE means 1135 * Return 0 on success and -errno on error. An error code of -ESPIPE means
1132 * that @ofs + @cnt were outside the end of the attribute and no write was 1136 * that @ofs + @cnt were outside the end of the attribute and no write was
@@ -1155,7 +1159,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
1155 end = ofs + cnt; 1159 end = ofs + cnt;
1156 end_ofs = end & ~PAGE_CACHE_MASK; 1160 end_ofs = end & ~PAGE_CACHE_MASK;
1157 /* If the end is outside the inode size return -ESPIPE. */ 1161 /* If the end is outside the inode size return -ESPIPE. */
1158 if (unlikely(end > VFS_I(ni)->i_size)) { 1162 if (unlikely(end > i_size_read(VFS_I(ni)))) {
1159 ntfs_error(vol->sb, "Request exceeds end of attribute."); 1163 ntfs_error(vol->sb, "Request exceeds end of attribute.");
1160 return -ESPIPE; 1164 return -ESPIPE;
1161 } 1165 }
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index db8713ea0d..e0f530ce6b 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -47,7 +47,7 @@
47static int ntfs_file_open(struct inode *vi, struct file *filp) 47static int ntfs_file_open(struct inode *vi, struct file *filp)
48{ 48{
49 if (sizeof(unsigned long) < 8) { 49 if (sizeof(unsigned long) < 8) {
50 if (vi->i_size > MAX_LFS_FILESIZE) 50 if (i_size_read(vi) > MAX_LFS_FILESIZE)
51 return -EFBIG; 51 return -EFBIG;
52 } 52 }
53 return generic_file_open(vi, filp); 53 return generic_file_open(vi, filp);
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index 23fd911078..5346596fa8 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -140,6 +140,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
140 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; 140 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
141 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; 141 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
142 s64 clusters; 142 s64 clusters;
143 loff_t i_size;
143 struct inode *lcnbmp_vi; 144 struct inode *lcnbmp_vi;
144 runlist_element *rl = NULL; 145 runlist_element *rl = NULL;
145 struct address_space *mapping; 146 struct address_space *mapping;
@@ -249,6 +250,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
249 clusters = count; 250 clusters = count;
250 rlpos = rlsize = 0; 251 rlpos = rlsize = 0;
251 mapping = lcnbmp_vi->i_mapping; 252 mapping = lcnbmp_vi->i_mapping;
253 i_size = i_size_read(lcnbmp_vi);
252 while (1) { 254 while (1) {
253 ntfs_debug("Start of outer while loop: done_zones 0x%x, " 255 ntfs_debug("Start of outer while loop: done_zones 0x%x, "
254 "search_zone %i, pass %i, zone_start 0x%llx, " 256 "search_zone %i, pass %i, zone_start 0x%llx, "
@@ -263,7 +265,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
263 last_read_pos = bmp_pos >> 3; 265 last_read_pos = bmp_pos >> 3;
264 ntfs_debug("last_read_pos 0x%llx.", 266 ntfs_debug("last_read_pos 0x%llx.",
265 (unsigned long long)last_read_pos); 267 (unsigned long long)last_read_pos);
266 if (last_read_pos > lcnbmp_vi->i_size) { 268 if (last_read_pos > i_size) {
267 ntfs_debug("End of attribute reached. " 269 ntfs_debug("End of attribute reached. "
268 "Skipping to zone_pass_done."); 270 "Skipping to zone_pass_done.");
269 goto zone_pass_done; 271 goto zone_pass_done;
@@ -287,8 +289,8 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
287 buf_size = last_read_pos & ~PAGE_CACHE_MASK; 289 buf_size = last_read_pos & ~PAGE_CACHE_MASK;
288 buf = page_address(page) + buf_size; 290 buf = page_address(page) + buf_size;
289 buf_size = PAGE_CACHE_SIZE - buf_size; 291 buf_size = PAGE_CACHE_SIZE - buf_size;
290 if (unlikely(last_read_pos + buf_size > lcnbmp_vi->i_size)) 292 if (unlikely(last_read_pos + buf_size > i_size))
291 buf_size = lcnbmp_vi->i_size - last_read_pos; 293 buf_size = i_size - last_read_pos;
292 buf_size <<= 3; 294 buf_size <<= 3;
293 lcn = bmp_pos & 7; 295 lcn = bmp_pos & 7;
294 bmp_pos &= ~7; 296 bmp_pos &= ~7;
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
index 5e280abafa..e680dd0cdb 100644
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -443,7 +443,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi)
443 /* An empty $LogFile must have been clean before it got emptied. */ 443 /* An empty $LogFile must have been clean before it got emptied. */
444 if (NVolLogFileEmpty(vol)) 444 if (NVolLogFileEmpty(vol))
445 goto is_empty; 445 goto is_empty;
446 size = log_vi->i_size; 446 size = i_size_read(log_vi);
447 /* Make sure the file doesn't exceed the maximum allowed size. */ 447 /* Make sure the file doesn't exceed the maximum allowed size. */
448 if (size > MaxLogFileSize) 448 if (size > MaxLogFileSize)
449 size = MaxLogFileSize; 449 size = MaxLogFileSize;
@@ -689,7 +689,8 @@ BOOL ntfs_empty_logfile(struct inode *log_vi)
689 if (!NVolLogFileEmpty(vol)) { 689 if (!NVolLogFileEmpty(vol)) {
690 int err; 690 int err;
691 691
692 err = ntfs_attr_set(NTFS_I(log_vi), 0, log_vi->i_size, 0xff); 692 err = ntfs_attr_set(NTFS_I(log_vi), 0, i_size_read(log_vi),
693 0xff);
693 if (unlikely(err)) { 694 if (unlikely(err)) {
694 ntfs_error(vol->sb, "Failed to fill $LogFile with " 695 ntfs_error(vol->sb, "Failed to fill $LogFile with "
695 "0xff bytes (error code %i).", err); 696 "0xff bytes (error code %i).", err);