linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: tytso@mit.edu, darrick.wong@oracle.com
Cc: linux-ext4@vger.kernel.org
Subject: [PATCH 28/37] libext2fs: provide a function to set inode size
Date: Thu, 01 May 2014 16:15:26 -0700	[thread overview]
Message-ID: <20140501231526.31890.13684.stgit@birch.djwong.org> (raw)
In-Reply-To: <20140501231222.31890.82860.stgit@birch.djwong.org>

Provide an API to set i_size in an inode and take care of all required
feature flag modifications.  Refactor the code to use this new
function.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c              |    9 ++++-----
 e2fsck/pass2.c              |   11 +++++++++--
 e2fsck/pass3.c              |    5 +++--
 e2fsck/rehash.c             |    5 ++++-
 lib/ext2fs/bb_inode.c       |    5 ++++-
 lib/ext2fs/ext2fs.h         |    2 ++
 lib/ext2fs/fileio.c         |   41 ++++++++++++++++++++++++++++-------------
 lib/ext2fs/mkjournal.c      |    8 +++-----
 lib/ext2fs/res_gdt.c        |    9 +++------
 lib/ext2fs/symlink.c        |    2 +-
 misc/create_inode.c         |    7 ++++++-
 tests/f_big_sparse/expect.1 |    5 -----
 12 files changed, 67 insertions(+), 42 deletions(-)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 376ee23..0705899 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -265,8 +265,7 @@ static void check_size(e2fsck_t ctx, struct problem_context *pctx)
 	if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
 		return;
 
-	inode->i_size = 0;
-	inode->i_size_high = 0;
+	ext2fs_inode_set_size(ctx->fs, inode, 0);
 	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
 }
 
@@ -2454,9 +2453,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		pctx->num = (pb.last_block+1) * fs->blocksize;
 		pctx->group = bad_size;
 		if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
-			inode->i_size = pctx->num;
-			if (!LINUX_S_ISDIR(inode->i_mode))
-				inode->i_size_high = pctx->num >> 32;
+			if (LINUX_S_ISDIR(inode->i_mode))
+				pctx->num &= 0xFFFFFFFFULL;
+			ext2fs_inode_set_size(fs, inode, pctx->num);
 			dirty_inode++;
 		}
 		pctx->num = 0;
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 4b19cb8..7a597de 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1768,8 +1768,15 @@ static int allocate_dir_block(e2fsck_t ctx,
 	 */
 	e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
 	ext2fs_iblk_add_blocks(fs, &inode, 1);
-	if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
-		inode.i_size = (db->blockcnt+1) * fs->blocksize;
+	if (EXT2_I_SIZE(&inode) < (db->blockcnt+1) * fs->blocksize) {
+		pctx->errcode = ext2fs_inode_set_size(fs, &inode,
+					(db->blockcnt+1) * fs->blocksize);
+		if (pctx->errcode) {
+			pctx->str = "ext2fs_inode_set_size";
+			fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
+			return 1;
+		}
+	}
 	e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
 
 	/*
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index efc0d49..324e398 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -865,8 +865,9 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
 		return retval;
 
 	sz = (es.last_block + 1) * fs->blocksize;
-	inode.i_size = sz;
-	inode.i_size_high = sz >> 32;
+	retval = ext2fs_inode_set_size(fs, &inode, sz);
+	if (retval)
+		return retval;
 	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 	quota_data_add(ctx->qctx, &inode, dir, es.newblocks * fs->blocksize);
 
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index 89708c2..09c55e5 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -783,7 +783,10 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
 		inode.i_flags &= ~EXT2_INDEX_FL;
 	else
 		inode.i_flags |= EXT2_INDEX_FL;
-	inode.i_size = outdir->num * fs->blocksize;
+	retval = ext2fs_inode_set_size(fs, &inode,
+				       outdir->num * fs->blocksize);
+	if (retval)
+		return retval;
 	ext2fs_iblk_sub_blocks(fs, &inode, wd.cleared);
 	e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
 
diff --git a/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c
index 268eecf..3d9132b 100644
--- a/lib/ext2fs/bb_inode.c
+++ b/lib/ext2fs/bb_inode.c
@@ -128,7 +128,10 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
 	if (!inode.i_ctime)
 		inode.i_ctime = fs->now ? fs->now : time(0);
 	ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
-	inode.i_size = rec.bad_block_count * fs->blocksize;
+	retval = ext2fs_inode_set_size(fs, &inode,
+				       rec.bad_block_count * fs->blocksize);
+	if (retval)
+		goto cleanup;
 
 	retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
 	if (retval)
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index ca35d24..3d7374e 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1245,6 +1245,8 @@ errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size);
 extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
 extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
 extern errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size);
+errcode_t ext2fs_inode_set_size(ext2_filsys fs, struct ext2_inode *inode,
+				ext2_off64_t size);
 
 /* finddev.c */
 extern char *ext2fs_find_block_device(dev_t device);
diff --git a/lib/ext2fs/fileio.c b/lib/ext2fs/fileio.c
index 1e386f8..55affb4 100644
--- a/lib/ext2fs/fileio.c
+++ b/lib/ext2fs/fileio.c
@@ -567,6 +567,31 @@ out:
 	return retval;
 }
 
+errcode_t ext2fs_inode_set_size(ext2_filsys fs, struct ext2_inode *inode,
+				ext2_off64_t size)
+{
+	/* Only regular files get to be larger than 4GB */
+	if (!LINUX_S_ISREG(inode->i_mode) && (size >> 32))
+		return EXT2_ET_FILE_TOO_BIG;
+
+	/* If we're writing a large file, set the large_file flag */
+	if (LINUX_S_ISREG(inode->i_mode) &&
+	    ext2fs_needs_large_file_feature(size) &&
+	    (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
+	     fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
+		fs->super->s_feature_ro_compat |=
+					EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
+		ext2fs_update_dynamic_rev(fs);
+		ext2fs_mark_super_dirty(fs);
+	}
+
+	inode->i_size = size & 0xffffffff;
+	inode->i_size_high = (size >> 32);
+
+	return 0;
+}
+
 /*
  * This function sets the size of the file, truncating it if necessary
  *
@@ -588,20 +613,10 @@ errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
 	old_truncate = ((old_size + file->fs->blocksize - 1) >>
 		      EXT2_BLOCK_SIZE_BITS(file->fs->super));
 
-	/* If we're writing a large file, set the large_file flag */
-	if (LINUX_S_ISREG(file->inode.i_mode) &&
-	    ext2fs_needs_large_file_feature(EXT2_I_SIZE(&file->inode)) &&
-	    (!EXT2_HAS_RO_COMPAT_FEATURE(file->fs->super,
-					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
-	     file->fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
-		file->fs->super->s_feature_ro_compat |=
-				EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
-		ext2fs_update_dynamic_rev(file->fs);
-		ext2fs_mark_super_dirty(file->fs);
-	}
+	retval = ext2fs_inode_set_size(file->fs, &file->inode, size);
+	if (retval)
+		return retval;
 
-	file->inode.i_size = size & 0xffffffff;
-	file->inode.i_size_high = (size >> 32);
 	if (file->ino) {
 		retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
 		if (retval)
diff --git a/lib/ext2fs/mkjournal.c b/lib/ext2fs/mkjournal.c
index ecc3912..11f33ab 100644
--- a/lib/ext2fs/mkjournal.c
+++ b/lib/ext2fs/mkjournal.c
@@ -400,15 +400,13 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
 		goto errout;
 
 	inode_size = (unsigned long long)fs->blocksize * num_blocks;
-	inode.i_size = inode_size & 0xFFFFFFFF;
-	inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
-	if (ext2fs_needs_large_file_feature(inode_size))
-		fs->super->s_feature_ro_compat |=
-			EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
 	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 	inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
 	inode.i_links_count = 1;
 	inode.i_mode = LINUX_S_IFREG | 0600;
+	retval = ext2fs_inode_set_size(fs, &inode, inode_size);
+	if (retval)
+		goto errout;
 
 	if ((retval = ext2fs_write_new_inode(fs, journal_ino, &inode)))
 		goto errout;
diff --git a/lib/ext2fs/res_gdt.c b/lib/ext2fs/res_gdt.c
index e61c330..1343ce6 100644
--- a/lib/ext2fs/res_gdt.c
+++ b/lib/ext2fs/res_gdt.c
@@ -133,12 +133,9 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 		dindir_dirty = inode_dirty = 1;
 		inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
 		inode_size *= fs->blocksize;
-		inode.i_size = inode_size & 0xFFFFFFFF;
-		inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
-		if(inode.i_size_high) {
-			sb->s_feature_ro_compat |=
-				EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
-		}
+		retval = ext2fs_inode_set_size(fs, &inode, inode_size);
+		if (retval)
+			goto out_free;
 		inode.i_ctime = fs->now ? fs->now : time(0);
 	}
 
diff --git a/lib/ext2fs/symlink.c b/lib/ext2fs/symlink.c
index cb3a2e7..4147181 100644
--- a/lib/ext2fs/symlink.c
+++ b/lib/ext2fs/symlink.c
@@ -80,7 +80,7 @@ errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
 	inode.i_uid = inode.i_gid = 0;
 	ext2fs_iblk_set(fs, &inode, fastlink ? 0 : 1);
 	inode.i_links_count = 1;
-	inode.i_size = target_len;
+	ext2fs_inode_set_size(fs, &inode, target_len);
 	/* The time fields are set by ext2fs_write_new_inode() */
 
 	if (fastlink) {
diff --git a/misc/create_inode.c b/misc/create_inode.c
index e7faab1..ec98afe 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -405,7 +405,12 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
 	inode.i_atime = inode.i_ctime = inode.i_mtime =
 		fs->now ? fs->now : time(0);
 	inode.i_links_count = 1;
-	inode.i_size = statbuf.st_size;
+	retval = ext2fs_inode_set_size(fs, &inode, statbuf.st_size);
+	if (retval) {
+		com_err(dest, retval, 0);
+		close(fd);
+		return retval;
+	}
 	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
 				      EXT4_FEATURE_INCOMPAT_INLINE_DATA)) {
 		inode.i_flags |= EXT4_INLINE_DATA_FL;
diff --git a/tests/f_big_sparse/expect.1 b/tests/f_big_sparse/expect.1
index 437ade7..eac82ed 100644
--- a/tests/f_big_sparse/expect.1
+++ b/tests/f_big_sparse/expect.1
@@ -2,11 +2,6 @@ Pass 1: Checking inodes, blocks, and sizes
 Inode 12, i_size is 61440, should be 4398050758656.  Fix? yes
 
 Pass 2: Checking directory structure
-Filesystem contains large files, but lacks LARGE_FILE flag in superblock.
-Fix? yes
-
-Filesystem has feature flag(s) set, but is a revision 0 filesystem.  Fix? yes

  parent reply	other threads:[~2014-05-01 23:15 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-01 23:12 [PATCH 00/37] e2fsprogs patchbomb 5/14 Darrick J. Wong
2014-05-01 23:12 ` [PATCH 01/37] misc: create better-packaged static analysis reports Darrick J. Wong
2014-05-11 22:33   ` Theodore Ts'o
2014-05-01 23:12 ` [PATCH 02/37] misc: coverity fixes Darrick J. Wong
2014-05-02 11:17   ` Lukáš Czerner
2014-05-05 20:04     ` Darrick J. Wong
2014-05-11 22:40       ` Theodore Ts'o
2014-05-01 23:12 ` [PATCH 03/37] libext2fs: create sockets when populating filesystem Darrick J. Wong
2014-05-02 11:22   ` Lukáš Czerner
2014-05-05 20:08     ` Darrick J. Wong
2014-05-11 22:44       ` Theodore Ts'o
2014-05-01 23:12 ` [PATCH 04/37] mke2fs: always warn if 128-byte inode and inline_data Darrick J. Wong
2014-05-02 11:27   ` Lukáš Czerner
2014-05-05 20:10     ` Darrick J. Wong
2014-05-12  0:26       ` Theodore Ts'o
2014-05-01 23:12 ` [PATCH 05/37] debugfs: teach logdump to deal with 64bit revoke tables Darrick J. Wong
2014-05-02 11:38   ` Lukáš Czerner
2014-05-05 22:23     ` Darrick J. Wong
2014-05-06 11:35       ` Lukáš Czerner
2014-05-12  1:20         ` Theodore Ts'o
2014-05-01 23:13 ` [PATCH 06/37] debugfs: force logdump to display (old) journal contents Darrick J. Wong
2014-05-02 11:49   ` Lukáš Czerner
2014-05-06  0:24     ` Darrick J. Wong
2014-05-12  1:41       ` Theodore Ts'o
2014-05-12  3:31         ` Theodore Ts'o
2014-05-14  0:05         ` Darrick J. Wong
2014-05-01 23:13 ` [PATCH 07/37] resize2fs: fix check for collision between old GDT and superblock on sparse_super2 fs Darrick J. Wong
2014-05-12  3:35   ` Theodore Ts'o
2014-05-01 23:13 ` [PATCH 08/37] mke2fs: set gdt csum when creating packed fs Darrick J. Wong
2014-05-02 11:55   ` Lukáš Czerner
2014-05-12  4:22     ` Theodore Ts'o
2014-05-01 23:13 ` [PATCH 09/37] mke2fs: set error behavior at initialization time Darrick J. Wong
2014-05-02 12:13   ` Lukáš Czerner
2014-05-01 23:13 ` [PATCH 10/37] e2fsck: verify checksums after checking everything else Darrick J. Wong
2014-05-02 12:32   ` Lukáš Czerner
2014-05-05 22:56     ` Darrick J. Wong
2014-05-06 11:32       ` Lukáš Czerner
2014-05-08  0:05         ` Darrick J. Wong
2014-05-01 23:13 ` [PATCH 11/37] e2fsck: fix the extended attribute checksum error message Darrick J. Wong
2014-05-02 12:46   ` Lukáš Czerner
2014-05-05 23:08     ` Darrick J. Wong
2014-05-06 10:12       ` Lukáš Czerner
2014-05-01 23:13 ` [PATCH 12/37] e2fsck: insert a missing dirent tail for checksums if possible Darrick J. Wong
2014-05-02 12:54   ` Lukáš Czerner
2014-05-05 23:16     ` Darrick J. Wong
2014-05-01 23:13 ` [PATCH 13/37] e2fsck: write dir blocks after new inode when reconstructing root/lost+found Darrick J. Wong
2014-05-05 17:13   ` Lukáš Czerner
2014-05-01 23:13 ` [PATCH 14/37] dumpe2fs: add switch to disable checksum verification Darrick J. Wong
2014-05-05 17:20   ` Lukáš Czerner
2014-05-01 23:14 ` [PATCH 15/37] mke2fs: set block_validity as a default mount option Darrick J. Wong
2014-05-05 17:24   ` Lukáš Czerner
2014-05-01 23:14 ` [PATCH 16/37] libext2fs: support allocating uninit blocks in bmap2() Darrick J. Wong
2014-05-06 15:45   ` Lukáš Czerner
2014-05-06 19:59     ` Darrick J. Wong
2014-05-07 10:02       ` Lukáš Czerner
2014-05-07 21:37         ` Darrick J. Wong
2014-05-08  0:13           ` [PATCH 1/2] libext2fs: support BLKZEROOUT/FALLOC_FL_ZERO_RANGE in ext2fs_zero_blocks Darrick J. Wong
2014-05-13 11:11             ` Lukáš Czerner
2014-05-08  0:14           ` [PATCH 2/2] libext2fs: support allocating uninit blocks in bmap2() Darrick J. Wong
2014-05-27 16:28             ` Lukáš Czerner
2014-05-28 19:48               ` Darrick J. Wong
2014-05-01 23:14 ` [PATCH 17/37] libext2fs: file IO routines should handle uninit blocks Darrick J. Wong
2014-05-01 23:14 ` [PATCH 18/37] resize2fs: convert fs to and from 64bit mode Darrick J. Wong
2014-05-01 23:14 ` [PATCH 19/37] resize2fs: when toggling 64bit, don't free in-use bg data clusters Darrick J. Wong
2014-05-01 23:14 ` [PATCH 20/37] resize2fs: adjust reserved_gdt_blocks when changing group descriptor size Darrick J. Wong
2014-05-01 23:14 ` [PATCH 21/37] libext2fs: have UNIX IO manager use pread/pwrite Darrick J. Wong
2014-08-02 23:16   ` Theodore Ts'o
2014-05-01 23:14 ` [PATCH 22/37] ext2fs: add readahead method to improve scanning Darrick J. Wong
2014-05-01 23:14 ` [PATCH 23/37] e2fsck: provide routines to read-ahead metadata Darrick J. Wong
2014-05-01 23:14 ` [PATCH 24/37] e2fsck: read-ahead metadata during passes 1, 2, and 4 Darrick J. Wong
2014-07-28 22:25   ` Darrick J. Wong
2014-05-01 23:15 ` [PATCH 25/37] libext2fs: when appending to a file, don't split an index block in equal halves Darrick J. Wong
2014-08-02 23:43   ` Theodore Ts'o
2014-05-01 23:15 ` [PATCH 26/37] libext2fs: find inode goal when allocating blocks Darrick J. Wong
2014-05-01 23:15 ` [PATCH 27/37] libext2fs: find a range of empty blocks Darrick J. Wong
2014-05-01 23:15 ` Darrick J. Wong [this message]
2014-07-26 18:37   ` [PATCH 28/37] libext2fs: provide a function to set inode size Theodore Ts'o
2014-05-01 23:15 ` [PATCH 29/37] libext2fs: implement fallocate Darrick J. Wong
2014-05-01 23:15 ` [PATCH 31/37] fuse2fs: translate ACL structures Darrick J. Wong
2014-05-01 23:15 ` [PATCH 32/37] fuse2fs: handle 64-bit dates correctly Darrick J. Wong
2014-05-01 23:16 ` [PATCH 33/37] fuse2fs: implement fallocate Darrick J. Wong
2014-05-01 23:16 ` [PATCH 35/37] tests: enable using fuse2fs with metadata checksum test Darrick J. Wong
2014-05-01 23:16 ` [PATCH 36/37] tests: test date handling Darrick J. Wong
2014-05-01 23:16 ` [PATCH 37/37] ext5: define new subtype to add features and reduce testing complexity Darrick J. Wong
2014-05-02  9:45   ` Lukáš Czerner
2014-05-02 14:04     ` Theodore Ts'o
2014-05-06  1:59       ` Darrick J. Wong
2014-05-06  1:33     ` Darrick J. Wong
2014-05-06 12:50       ` Lukáš Czerner
2014-05-06 15:21         ` Theodore Ts'o
2014-05-06 15:30           ` Lukáš Czerner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140501231526.31890.13684.stgit@birch.djwong.org \
    --to=darrick.wong@oracle.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).