remarkable-linux/fs
Dmitri Monakhov 0f64415d42 fs: truncate blocks outside i_size after O_DIRECT write error
In case of error extending write may have instantiated a few blocks
outside i_size.  We need to trim these blocks.  We have to do it
*regardless* to blocksize.  At least ext2, ext3 and reiserfs interpret
(i_size < biggest block) condition as error.  Fsck will complain about
wrong i_size.  Then fsck will fix the error by changing i_size according
to the biggest block.  This is bad because this blocks contain garbage
from previous write attempt.  And result in data corruption.

####TESTCASE_BEGIN
$touch /mnt/test/BIG_FILE
## at this moment /mnt/test/BIG_FILE size and blocks equal to zero
open("/mnt/test/BIG_FILE", O_WRONLY|O_CREAT|O_DIRECT, 0666) = 3
write(3, "aaaaaaaaaaaa"..., 104857600) = -1 ENOSPC (No space left on device)
## size and block sould't be changed because write op failed.
$stat /mnt/test/BIG_FILE
File: `/mnt/test/BIG_FILE'
Size: 0 Blocks: 110896 IO Block: 1024 regular empty file
<<<<<<<<^^^^^^^^^^^^^^^^^^^^^^^^^^^^^file size is less than biggest block idx
Device: fe07h/65031d Inode: 14 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2007-01-24 20:03:38.000000000 +0300
Modify: 2007-01-24 20:03:38.000000000 +0300
Change: 2007-01-24 20:03:39.000000000 +0300

#fsck.ext3 -f /dev/VG/test
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Inode 14, i_size is 0, should be 56556544. Fix<y>? yes
Pass 2: Checking directory structure
....
#####TESTCASE_ENDdiff --git a/fs/direct-io.c b/fs/direct-io.c
index af0558d..4e88bea 100644

[akpm@linux-foundation.org: use i_size_read()]
Signed-off-by: Dmitri Monakhov <dmonakhov@openvz.org>
Cc: Zach Brown <zach.brown@oracle.com>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Badari Pulavarty <pbadari@us.ibm.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 15:59:06 -08:00
..
9p Merge branch 'next' into for-linus 2008-12-25 11:40:09 +11:00
adfs
affs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2009-01-05 18:32:06 -08:00
afs fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
autofs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
autofs4 zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
befs befs: ensure fast symlinks are NUL-terminated 2008-12-31 18:07:40 -05:00
bfs CRED: Wrap task credential accesses in the BFS filesystem 2008-11-14 10:38:47 +11:00
cifs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2009-01-05 18:32:06 -08:00
coda add a vfs_fsync helper 2009-01-05 11:54:28 -05:00
configfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
cramfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
debugfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
devpts zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
dlm Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm 2009-01-05 19:02:09 -08:00
ecryptfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2009-01-05 18:32:06 -08:00
efs
exportfs Merge branch 'next' into for-linus 2008-12-25 11:40:09 +11:00
ext2 nfsd race fixes: ext2 2008-12-31 18:07:43 -05:00
ext3 ext3: Add default allocation routines for quota structures 2009-01-05 08:40:25 -08:00
ext4 ext4: Add default allocation routines for quota structures 2009-01-05 08:40:26 -08:00
fat Merge git://git.kernel.org/pub/scm/linux/kernel/git/hirofumi/fatfs-2.6 2008-12-30 20:33:34 -08:00
freevxfs freevxfs: ensure fast symlinks are NUL-terminated 2008-12-31 18:07:40 -05:00
fuse fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
gfs2 GFS2: Use DEFINE_SPINLOCK 2009-01-05 07:45:02 +00:00
hfs CRED: Wrap task credential accesses in the HFS filesystem 2008-11-14 10:38:54 +11:00
hfsplus CRED: Wrap task credential accesses in the HFSplus filesystem 2008-11-14 10:38:54 +11:00
hostfs fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
hpfs CRED: Wrap task credential accesses in the HPFS filesystem 2008-11-14 10:38:55 +11:00
hppfs CRED: Use creds in file structs 2008-11-14 10:39:25 +11:00
hugetlbfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
isofs isofs check for NULL ->i_op in root directory is dead code 2009-01-05 11:53:38 -05:00
jbd jbd: don't give up looking for space so easily in __log_wait_for_space 2008-11-06 22:37:59 -05:00
jbd2 jbd2: Add buffer triggers 2009-01-05 08:40:30 -08:00
jffs2 fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
jfs fix the treatment of jfs special inodes 2009-01-05 11:54:29 -05:00
lockd Merge branch 'devel' into next 2008-12-30 16:51:43 -05:00
minix CRED: Wrap task credential accesses in the Minix filesystem 2008-11-14 10:38:57 +11:00
ncpfs CRED: Wrap task credential accesses in the NCPFS filesystem 2008-11-14 10:38:58 +11:00
nfs fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
nfs_common SUNRPC: nfsacl_encode/nfsacl_decode should be exported as GPL-only 2008-12-23 15:21:32 -05:00
nfsd add a vfs_fsync helper 2009-01-05 11:54:28 -05:00
nls
notify inotify: fix type errors in interfaces 2009-01-05 11:54:29 -05:00
ntfs ntfs: don't NULL i_op 2009-01-05 11:54:27 -05:00
ocfs2 Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2 2009-01-05 18:32:43 -08:00
omfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
openpromfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
partitions block/md: fix md autodetection 2008-11-18 15:08:56 +01:00
proc mm: report the MMU pagesize in /proc/pid/smaps 2009-01-06 15:58:58 -08:00
qnx4
ramfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
reiserfs Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2 2009-01-05 18:32:43 -08:00
romfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
smbfs fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
sysfs zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
sysv sysv: ensure fast symlinks are NUL-terminated 2008-12-31 18:07:39 -05:00
ubifs fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
udf Merge branch 'master' into next 2008-12-04 17:16:36 +11:00
ufs CRED: Wrap task credential accesses in the UFS filesystem 2008-11-14 10:39:04 +11:00
xfs [XFS] Fix merge failures 2008-12-29 16:47:18 +11:00
aio.c aio: make the lookup_ioctx() lockless 2008-12-29 08:29:50 +01:00
anon_inodes.c anon_inodes: use fops->owner for module refcount 2008-12-31 16:55:44 +02:00
attr.c CRED: Wrap task credential accesses in the filesystem subsystem 2008-11-14 10:39:05 +11:00
bad_inode.c kill ->dir_notify() 2008-12-31 18:07:43 -05:00
binfmt_aout.c sanitize ifdefs in binfmt_aout 2009-01-03 11:45:54 -08:00
binfmt_elf.c Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6 2008-12-28 12:33:21 -08:00
binfmt_elf_fdpic.c CRED: Make execve() take advantage of copy-on-write credentials 2008-11-14 10:39:24 +11:00
binfmt_em86.c
binfmt_flat.c CRED: Make execve() take advantage of copy-on-write credentials 2008-11-14 10:39:24 +11:00
binfmt_misc.c zero i_uid/i_gid on inode allocation 2009-01-05 11:54:28 -05:00
binfmt_script.c
binfmt_som.c CRED: Make execve() take advantage of copy-on-write credentials 2008-11-14 10:39:24 +11:00
bio-integrity.c bio: allow individual slabs in the bio_set 2008-12-29 08:29:23 +01:00
bio.c bio: get rid of bio_vec clearing 2008-12-29 08:29:53 +01:00
block_dev.c fs/block_dev.c: __read_mostly improvement and sb_is_blkdev_sb utilization 2008-12-31 18:07:43 -05:00
buffer.c fs: symlink write_begin allocation context fix 2009-01-04 13:33:20 -08:00
char_dev.c
compat.c CRED: Make execve() take advantage of copy-on-write credentials 2008-11-14 10:39:24 +11:00
compat_binfmt_elf.c
compat_ioctl.c
dcache.c filp_cachep can be static in fs/file_table.c 2008-12-31 18:07:42 -05:00
dcookies.c shrink struct dentry 2008-12-31 18:07:38 -05:00
direct-io.c fs: truncate blocks outside i_size after O_DIRECT write error 2009-01-06 15:59:06 -08:00
dquot.c quota: Export dquot_alloc() and dquot_destroy() functions 2009-01-05 08:40:25 -08:00
drop_caches.c
eventfd.c
eventpoll.c epoll: introduce resource usage limits 2008-12-01 19:55:24 -08:00
exec.c sys_execve and sys_uselib do not call into fsnotify 2009-01-05 11:54:28 -05:00
fcntl.c Merge branch 'next' into for-linus 2008-12-25 11:40:09 +11:00
fifo.c
file.c
file_table.c filp_cachep can be static in fs/file_table.c 2008-12-31 18:07:42 -05:00
filesystems.c vfs: remove duplicate code in get_fs_type() 2009-01-05 11:54:29 -05:00
fs-writeback.c
generic_acl.c
inode.c mm: remove GFP_HIGHUSER_PAGECACHE 2009-01-06 15:59:01 -08:00
internal.h CRED: Make execve() take advantage of copy-on-write credentials 2008-11-14 10:39:24 +11:00
ioctl.c GFS2: Support for FIEMAP ioctl 2009-01-05 07:38:46 +00:00
ioprio.c CRED: Use RCU to access another task's creds and to release a task's own creds 2008-11-14 10:39:19 +11:00
Kconfig ocfs2: Assign feature bits and system inodes to quota feature and quota files 2009-01-05 08:40:23 -08:00
Kconfig.binfmt
libfs.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2009-01-05 18:32:06 -08:00
locks.c CRED: Wrap task credential accesses in the filesystem subsystem 2008-11-14 10:39:05 +11:00
Makefile quota: Split off quota tree handling into a separate file 2009-01-05 08:40:21 -08:00
mbcache.c
mpage.c do_mpage_readpage(): remove useless clear_buffer_mapped() call 2009-01-06 15:59:01 -08:00
namei.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2009-01-05 18:32:06 -08:00
namespace.c fs/namespace.c: drop code after return 2008-12-31 18:07:38 -05:00
nfsctl.c pass a struct path * to may_open 2008-12-31 18:07:41 -05:00
no-block.c
open.c inode->i_op is never NULL 2009-01-05 11:54:28 -05:00
pipe.c sanitize audit_fd_pair() 2009-01-04 15:14:41 -05:00
pnode.c
pnode.h
posix_acl.c CRED: Wrap task credential accesses in the filesystem subsystem 2008-11-14 10:39:05 +11:00
quota.c quota: Introduce DQUOT_QUOTA_SYS_FILE flag 2009-01-05 08:36:57 -08:00
quota_tree.c quota: Split off quota tree handling into a separate file 2009-01-05 08:40:21 -08:00
quota_tree.h quota: Split off quota tree handling into a separate file 2009-01-05 08:40:21 -08:00
quota_v1.c quota: Move quotaio_v[12].h from include/linux/ to fs/ 2009-01-05 08:36:58 -08:00
quota_v2.c quota: Convert union in mem_dqinfo to a pointer 2009-01-05 08:40:21 -08:00
quotaio_v1.h quota: Move quotaio_v[12].h from include/linux/ to fs/ 2009-01-05 08:36:58 -08:00
quotaio_v2.h quota: Split off quota tree handling into a separate file 2009-01-05 08:40:21 -08:00
read_write.c vfs: lseek(fd, 0, SEEK_CUR) race condition 2009-01-05 11:53:07 -05:00
read_write.h
readdir.c
select.c select: deal with math overflow from borderline valid userland data 2008-10-26 11:22:08 -07:00
seq_file.c Merge branch 'cpus4096-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-01-03 12:04:39 -08:00
signalfd.c
splice.c fs: remove prepare_write/commit_write 2008-10-30 11:38:45 -07:00
stack.c
stat.c inode->i_op is never NULL 2009-01-05 11:54:28 -05:00
super.c security: pass mount flags to security_sb_kern_mount() 2008-12-20 09:02:39 +11:00
sync.c mm: do_sync_mapping_range integrity fix 2009-01-06 15:59:00 -08:00
timerfd.c
utimes.c
xattr.c inode->i_op is never NULL 2009-01-05 11:54:28 -05:00
xattr_acl.c