@@ -4026,6 +4026,185 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
4026
4026
return ret ;
4027
4027
}
4028
4028
4029
+ static int redirty_blocks (struct inode * inode , pgoff_t page_idx , int len )
4030
+ {
4031
+ DEFINE_READAHEAD (ractl , NULL , inode -> i_mapping , page_idx );
4032
+ struct address_space * mapping = inode -> i_mapping ;
4033
+ struct page * page ;
4034
+ pgoff_t redirty_idx = page_idx ;
4035
+ int i , page_len = 0 , ret = 0 ;
4036
+
4037
+ page_cache_ra_unbounded (& ractl , len , 0 );
4038
+
4039
+ for (i = 0 ; i < len ; i ++ , page_idx ++ ) {
4040
+ page = read_cache_page (mapping , page_idx , NULL , NULL );
4041
+ if (IS_ERR (page )) {
4042
+ ret = PTR_ERR (page );
4043
+ break ;
4044
+ }
4045
+ page_len ++ ;
4046
+ }
4047
+
4048
+ for (i = 0 ; i < page_len ; i ++ , redirty_idx ++ ) {
4049
+ page = find_lock_page (mapping , redirty_idx );
4050
+ if (!page )
4051
+ ret = - ENOENT ;
4052
+ set_page_dirty (page );
4053
+ f2fs_put_page (page , 1 );
4054
+ f2fs_put_page (page , 0 );
4055
+ }
4056
+
4057
+ return ret ;
4058
+ }
4059
+
4060
+ static int f2fs_ioc_decompress_file (struct file * filp , unsigned long arg )
4061
+ {
4062
+ struct inode * inode = file_inode (filp );
4063
+ struct f2fs_sb_info * sbi = F2FS_I_SB (inode );
4064
+ struct f2fs_inode_info * fi = F2FS_I (inode );
4065
+ pgoff_t page_idx = 0 , last_idx ;
4066
+ unsigned int blk_per_seg = sbi -> blocks_per_seg ;
4067
+ int cluster_size = F2FS_I (inode )-> i_cluster_size ;
4068
+ int count , ret ;
4069
+
4070
+ if (!f2fs_sb_has_compression (sbi ) ||
4071
+ F2FS_OPTION (sbi ).compress_mode != COMPR_MODE_USER )
4072
+ return - EOPNOTSUPP ;
4073
+
4074
+ if (!(filp -> f_mode & FMODE_WRITE ))
4075
+ return - EBADF ;
4076
+
4077
+ if (!f2fs_compressed_file (inode ))
4078
+ return - EINVAL ;
4079
+
4080
+ f2fs_balance_fs (F2FS_I_SB (inode ), true);
4081
+
4082
+ file_start_write (filp );
4083
+ inode_lock (inode );
4084
+
4085
+ if (!f2fs_is_compress_backend_ready (inode )) {
4086
+ ret = - EOPNOTSUPP ;
4087
+ goto out ;
4088
+ }
4089
+
4090
+ if (f2fs_is_mmap_file (inode )) {
4091
+ ret = - EBUSY ;
4092
+ goto out ;
4093
+ }
4094
+
4095
+ ret = filemap_write_and_wait_range (inode -> i_mapping , 0 , LLONG_MAX );
4096
+ if (ret )
4097
+ goto out ;
4098
+
4099
+ if (!atomic_read (& fi -> i_compr_blocks ))
4100
+ goto out ;
4101
+
4102
+ last_idx = DIV_ROUND_UP (i_size_read (inode ), PAGE_SIZE );
4103
+
4104
+ count = last_idx - page_idx ;
4105
+ while (count ) {
4106
+ int len = min (cluster_size , count );
4107
+
4108
+ ret = redirty_blocks (inode , page_idx , len );
4109
+ if (ret < 0 )
4110
+ break ;
4111
+
4112
+ if (get_dirty_pages (inode ) >= blk_per_seg )
4113
+ filemap_fdatawrite (inode -> i_mapping );
4114
+
4115
+ count -= len ;
4116
+ page_idx += len ;
4117
+ }
4118
+
4119
+ if (!ret )
4120
+ ret = filemap_write_and_wait_range (inode -> i_mapping , 0 ,
4121
+ LLONG_MAX );
4122
+
4123
+ if (ret )
4124
+ f2fs_warn (sbi , "%s: The file might be partially decompressed "
4125
+ "(errno=%d). Please delete the file.\n" ,
4126
+ __func__ , ret );
4127
+ out :
4128
+ inode_unlock (inode );
4129
+ file_end_write (filp );
4130
+
4131
+ return ret ;
4132
+ }
4133
+
4134
+ static int f2fs_ioc_compress_file (struct file * filp , unsigned long arg )
4135
+ {
4136
+ struct inode * inode = file_inode (filp );
4137
+ struct f2fs_sb_info * sbi = F2FS_I_SB (inode );
4138
+ pgoff_t page_idx = 0 , last_idx ;
4139
+ unsigned int blk_per_seg = sbi -> blocks_per_seg ;
4140
+ int cluster_size = F2FS_I (inode )-> i_cluster_size ;
4141
+ int count , ret ;
4142
+
4143
+ if (!f2fs_sb_has_compression (sbi ) ||
4144
+ F2FS_OPTION (sbi ).compress_mode != COMPR_MODE_USER )
4145
+ return - EOPNOTSUPP ;
4146
+
4147
+ if (!(filp -> f_mode & FMODE_WRITE ))
4148
+ return - EBADF ;
4149
+
4150
+ if (!f2fs_compressed_file (inode ))
4151
+ return - EINVAL ;
4152
+
4153
+ f2fs_balance_fs (F2FS_I_SB (inode ), true);
4154
+
4155
+ file_start_write (filp );
4156
+ inode_lock (inode );
4157
+
4158
+ if (!f2fs_is_compress_backend_ready (inode )) {
4159
+ ret = - EOPNOTSUPP ;
4160
+ goto out ;
4161
+ }
4162
+
4163
+ if (f2fs_is_mmap_file (inode )) {
4164
+ ret = - EBUSY ;
4165
+ goto out ;
4166
+ }
4167
+
4168
+ ret = filemap_write_and_wait_range (inode -> i_mapping , 0 , LLONG_MAX );
4169
+ if (ret )
4170
+ goto out ;
4171
+
4172
+ set_inode_flag (inode , FI_ENABLE_COMPRESS );
4173
+
4174
+ last_idx = DIV_ROUND_UP (i_size_read (inode ), PAGE_SIZE );
4175
+
4176
+ count = last_idx - page_idx ;
4177
+ while (count ) {
4178
+ int len = min (cluster_size , count );
4179
+
4180
+ ret = redirty_blocks (inode , page_idx , len );
4181
+ if (ret < 0 )
4182
+ break ;
4183
+
4184
+ if (get_dirty_pages (inode ) >= blk_per_seg )
4185
+ filemap_fdatawrite (inode -> i_mapping );
4186
+
4187
+ count -= len ;
4188
+ page_idx += len ;
4189
+ }
4190
+
4191
+ if (!ret )
4192
+ ret = filemap_write_and_wait_range (inode -> i_mapping , 0 ,
4193
+ LLONG_MAX );
4194
+
4195
+ clear_inode_flag (inode , FI_ENABLE_COMPRESS );
4196
+
4197
+ if (ret )
4198
+ f2fs_warn (sbi , "%s: The file might be partially compressed "
4199
+ "(errno=%d). Please delete the file.\n" ,
4200
+ __func__ , ret );
4201
+ out :
4202
+ inode_unlock (inode );
4203
+ file_end_write (filp );
4204
+
4205
+ return ret ;
4206
+ }
4207
+
4029
4208
static long __f2fs_ioctl (struct file * filp , unsigned int cmd , unsigned long arg )
4030
4209
{
4031
4210
switch (cmd ) {
@@ -4113,6 +4292,10 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
4113
4292
return f2fs_ioc_get_compress_option (filp , arg );
4114
4293
case F2FS_IOC_SET_COMPRESS_OPTION :
4115
4294
return f2fs_ioc_set_compress_option (filp , arg );
4295
+ case F2FS_IOC_DECOMPRESS_FILE :
4296
+ return f2fs_ioc_decompress_file (filp , arg );
4297
+ case F2FS_IOC_COMPRESS_FILE :
4298
+ return f2fs_ioc_compress_file (filp , arg );
4116
4299
default :
4117
4300
return - ENOTTY ;
4118
4301
}
@@ -4352,6 +4535,8 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
4352
4535
case F2FS_IOC_SEC_TRIM_FILE :
4353
4536
case F2FS_IOC_GET_COMPRESS_OPTION :
4354
4537
case F2FS_IOC_SET_COMPRESS_OPTION :
4538
+ case F2FS_IOC_DECOMPRESS_FILE :
4539
+ case F2FS_IOC_COMPRESS_FILE :
4355
4540
break ;
4356
4541
default :
4357
4542
return - ENOIOCTLCMD ;
0 commit comments