summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <ngkaho1234@gmail.com>2015-09-20 16:22:17 +0000
committerroot <ngkaho1234@gmail.com>2015-09-20 16:22:17 +0000
commit01c6151eb539b10954a8459193482524f4365242 (patch)
treee8e84a8d87d077de560e3a0d0f11456fecd7068c
parentc879d4700facd0ce86ad3781432f01bb0952e4bb (diff)
ext4_ftruncate being separated into two parts: ext4_ftruncate_no_lock and ext4_ftruncate.
-rw-r--r--lwext4/ext4.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/lwext4/ext4.c b/lwext4/ext4.c
index 77e6e51..d278063 100644
--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -1113,17 +1113,11 @@ int ext4_fclose(ext4_file *f)
return EOK;
}
-int ext4_ftruncate(ext4_file *f, uint64_t size)
+static int ext4_ftruncate_no_lock(ext4_file *f, uint64_t size)
{
struct ext4_inode_ref ref;
int r;
- ext4_assert(f && f->mp);
-
- if (f->flags & O_RDONLY)
- return EPERM;
-
- EXT4_MP_LOCK(f->mp);
r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
if (r != EOK) {
@@ -1138,6 +1132,23 @@ int ext4_ftruncate(ext4_file *f, uint64_t size)
goto Finish;
}
+ if ((ext4_inode_get_mode(&f->mp->fs.sb, ref.inode) & EXT4_INODE_MODE_SOFTLINK)
+ == EXT4_INODE_MODE_SOFTLINK
+ && f->fsize < sizeof(ref.inode->blocks)
+ && !ext4_inode_get_blocks_count(&f->mp->fs.sb, ref.inode)) {
+ char *content = (char *)ref.inode->blocks;
+ memset(content + size, 0, sizeof(ref.inode->blocks) - size);
+ ext4_inode_set_size(ref.inode, size);
+ ref.dirty = true;
+
+ f->fsize = size;
+ if (f->fpos > size)
+ f->fpos = size;
+
+ r = EOK;
+ goto Finish;
+ }
+
/*Start write back cache mode.*/
r = ext4_block_cache_write_back(f->mp->fs.bdev, 1);
if (r != EOK)
@@ -1159,6 +1170,22 @@ int ext4_ftruncate(ext4_file *f, uint64_t size)
Finish:
ext4_fs_put_inode_ref(&ref);
+ return r;
+
+}
+
+int ext4_ftruncate(ext4_file *f, uint64_t size)
+{
+ int r;
+ ext4_assert(f && f->mp);
+
+ if (f->flags & O_RDONLY)
+ return EPERM;
+
+ EXT4_MP_LOCK(f->mp);
+
+ r = ext4_ftruncate_no_lock(f, size);
+
EXT4_MP_UNLOCK(f->mp);
return r;
}