This will update the following files: Documentation/filesystems/ntfs.txt | 2 ++ fs/ntfs/ChangeLog | 14 +++++++++++++- fs/ntfs/Makefile | 2 +- fs/ntfs/compress.c | 29 ++++++++++++++++++++++------- 4 files changed, 38 insertions(+), 9 deletions(-) through these ChangeSets: (04/05/10 1.1611) NTFS: 2.1.9 release - Fix two bugs in the decompression engine in handling of corner cases. diff -Nru a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt --- a/Documentation/filesystems/ntfs.txt Mon May 10 10:09:16 2004 +++ b/Documentation/filesystems/ntfs.txt Mon May 10 10:09:16 2004 @@ -273,6 +273,8 @@ Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. +2.1.9: + - Fix two bugs in handling of corner cases in the decompression engine. 2.1.8: - Read the $MFT mirror and compare it to the $MFT and if the two do not match, force a read-only mount and do not allow read-write remounts. diff -Nru a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog --- a/fs/ntfs/ChangeLog Mon May 10 10:09:16 2004 +++ b/fs/ntfs/ChangeLog Mon May 10 10:09:16 2004 @@ -19,7 +19,19 @@ sufficient for synchronisation here. We then just need to make sure ntfs_readpage/writepage/truncate interoperate properly with us. -2.1.8 - Handle $MFT mirror and $LogFile, improve time ihandling, and cleanups. +2.1.9 - Fix two bugs in decompression engine. + + - Fix a bug where we would not always detect that we have reached the + end of a compression block because we were ending at minus one byte + which is effectively the same as being at the end. The fix is to + check whether the uncompressed buffer has been fully filled and if so + we assume we have reached the end of the compression block. A big + thank you to Marcin GibuĊ‚a for the bug report, the assistance in + tracking down the bug and testing the fix. + - Fix a possible bug where when a compressed read is truncated to the + end of the file, the offset inside the last page was not truncated. + +2.1.8 - Handle $MFT mirror and $LogFile, improve time handling, and cleanups. - Use get_bh() instead of manual atomic_inc() in fs/ntfs/compress.c. - Modify fs/ntfs/time.c::ntfs2utc(), get_current_ntfs_time(), and diff -Nru a/fs/ntfs/Makefile b/fs/ntfs/Makefile --- a/fs/ntfs/Makefile Mon May 10 10:09:16 2004 +++ b/fs/ntfs/Makefile Mon May 10 10:09:16 2004 @@ -5,7 +5,7 @@ ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o logfile.o \ mft.o mst.o namei.o super.o sysctl.o unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.8\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.9\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff -Nru a/fs/ntfs/compress.c b/fs/ntfs/compress.c --- a/fs/ntfs/compress.c Mon May 10 10:09:16 2004 +++ b/fs/ntfs/compress.c Mon May 10 10:09:16 2004 @@ -197,9 +197,15 @@ do_next_sb: ntfs_debug("Beginning sub-block at offset = 0x%x in the cb.", cb - cb_start); - - /* Have we reached the end of the compression block? */ - if (cb == cb_end || !le16_to_cpup((u16*)cb)) { + /* + * Have we reached the end of the compression block or the end of the + * decompressed data? The latter can happen for example if the current + * position in the compression block is one byte before its end so the + * first two checks do not detect it. + */ + if (cb == cb_end || !le16_to_cpup((u16*)cb) || + (*dest_index == dest_max_index && + *dest_ofs == dest_max_ofs)) { int i; ntfs_debug("Completed. Returning success (0)."); @@ -501,7 +507,7 @@ */ unsigned int nr_pages = (end_vcn - start_vcn) << vol->cluster_size_bits >> PAGE_CACHE_SHIFT; - unsigned int xpage, max_page, cur_page, cur_ofs, i; + unsigned int xpage, max_page, max_ofs, cur_page, cur_ofs, i; unsigned int cb_clusters, cb_max_ofs; int block, max_block, cb_max_page, bhs_size, nr_bhs, err = 0; struct page **pages; @@ -544,8 +550,11 @@ */ max_page = ((VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) - offset; - if (nr_pages < max_page) + max_ofs = (VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) & ~PAGE_CACHE_MASK; + if (nr_pages < max_page) { max_page = nr_pages; + max_ofs = 0; + } for (i = 0; i < max_page; i++, offset++) { if (i != xpage) pages[i] = grab_cache_page_nowait(mapping, offset); @@ -713,8 +722,14 @@ cb_max_page >>= PAGE_CACHE_SHIFT; /* Catch end of file inside a compression block. */ - if (cb_max_page > max_page) - cb_max_page = max_page; + if (cb_max_page >= max_page) { + if (cb_max_page > max_page) { + cb_max_page = max_page; + cb_max_ofs = max_ofs; + } else if (cb_max_ofs > max_ofs) { + cb_max_ofs = max_ofs; + } + } if (vcn == start_vcn - cb_clusters) { /* Sparse cb, zero out page range overlapping the cb. */ =================================================================== This BitKeeper patch contains the following changesets: 1.1611 ## Wrapped with gzip_uu ## M'XL( +Y> [U8Z6[;1A#^+3[%-"D"V[&D7=Y4*C>.KQB)$\-V@J(P("S) MI468(@7NRD>C]$??K>_5V:5N6:VO5!(DKPIRJB9RT34S89KX-XQDU$7KG@I6C7:L"8K M\K;/6[63O8,O'[=/#*/=AITNRR_X*9?0;ANR**]8%HNW3':S(F_(DN6BQR5K M1$5O.!$=FH28^':H9Q'''5*7V-XPHC&ES*8\)J;MN[:A;7\[M7D>P,;CA/AF M8#M#8EG4,W:!-JA+*1"[29PF)4""EN.VB/F:T!8AL @(KVVH$^,=/*_=.T8$ MG\[V3UM@-F@C@))GG D.==A/;T!>%Q .+@2D.<@NAYBCCG[)A4B+''A^D>8< M :H7RJ#R.$OS"R@2B(HRYR5$B"8:Q@>P+.(;Q],<&/4'O@R#,&)LP;L/PT3H M"F@>L4N>I!D?TL CA.+;(H$3# G>>,.$1S1TJ$/MF%CA'8@JTH-2R@L"95SJNA49T MEU:TD]HTB3R?>;%G,]-=K74&:3$%MF][NGG_.TZJJY\Q5]4$8^Z#GX/ M'2>P+-WLMCW?ZD[+]E>VNOFC6OU+/V:20U*4\_VN&K0JJ\]0+Z_U!SON^!Y1 M?T0?'YJ> Z:A+6@9M66N6<4C_\9##5TE2W4\*HI'-LIR#:QJE%'*_:&-67 K M?K>]!^2<6E"G_WO2J[9>2/J2CX_(\:YI L5,X[=59?J.9\K=>3P?EP13@G#= MY26':_P4@RR&O)# LFMV*_"XY)'$BF!2[7?9%4??6-3EL2H3HP:(&:LB8C"K M*,R*Z!)"'K&!J)"5!A15)8=8O30?""AR#N&MU##7W10GBE0 3_"I(M,KGMWJ M2A2LQX$)!!N=58N(U XPZL$OJ17=0IM2"@WQL%EH<#A"[1"\4 M&L\A&62H!%LNPTUL"$@3$!KH6JD4V)=W>3UV65TN.8UF;4.87B@4#%M^";?% M ,V#(U9&F)"#-!S\_1?3M:( 5/Q+WB]*N:GO46TJ),LCCNG3("6++I7K<7&= M3XXH:R474FW(*@R-:5+[!:*$&9_-;A<=GB8)/4&/8AVZ$H.$Y1LK*^>36B%G MO#*M2!*!?93F(HVY7LF8D-!G%PB/,55U,P%31::*TL>B?*_(AL//1_MGF/FR M1->5_3]CW>]K]!2-*C#(,NWQ"35M:J$(&RD?],4\^8SGB07N>="TLIIY%J:5 M"?'@M$("33R^]1#>^<&THP9S57^8/DT#BG6JP6H%ZXS]>PSI^(ISU-?>;V#TG?\U"P^N/@.3A8X3R=A!7*\["PMN?I M-*Q@5O'P^.U!L(\I&K,'D^YRP:DTX[ ZD0XQ)%"&R2*B4%) M6F*#]^CI\ M,W8=8BN6KGYJ RR/BQPCE^82;E1Q;((2GU[AP4T5I]&2NM)+Z1O$PA%;8>&/ M:=1&TLCW:U^1[0_7\G2]OI5V1/H'A]=PO'VPU]G9WGF_USD]_'T/ZY^NPROX M=@:LL""_NUV