ext4_ftruncate being separated into two parts: ext4_ftruncate_no_lock and ext4_ftruncate.
authorroot <ngkaho1234@gmail.com>
Sun, 20 Sep 2015 16:22:17 +0000 (16:22 +0000)
committerroot <ngkaho1234@gmail.com>
Sun, 20 Sep 2015 16:22:17 +0000 (16:22 +0000)
lwext4/ext4.c

index 77e6e5191b7bc7cd0a41f88274ec7f228eafa624..d2780636ab85e25487363d6b6594a70cf2def686 100644 (file)
@@ -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;
 }