summaryrefslogtreecommitdiff
path: root/fs/f2fs/segment.c
diff options
context:
space:
mode:
authorSrinivasarao P <spathi@codeaurora.org>2018-08-02 10:10:30 +0530
committerSrinivasarao P <spathi@codeaurora.org>2018-08-03 16:59:20 +0530
commitc2e09fadec5ce348e125150e66a9a32b4af44756 (patch)
tree652cf573762608aecdb28c230363166a03a24f39 /fs/f2fs/segment.c
parent414b079b7f4ba955f4679cd87be64199b4e875c7 (diff)
parent8ec9fd8936b20ca2d18160f8b18acb4b732c2771 (diff)
Merge android-4.4.142 (8ec9fd8) into msm-4.4
* refs/heads/tmp-8ec9fd8 ANDROID: sdcardfs: Check stacked filesystem depth Fix backport of "tcp: detect malicious patterns in tcp_collapse_ofo_queue()" tcp: detect malicious patterns in tcp_collapse_ofo_queue() tcp: avoid collapses in tcp_prune_queue() if possible x86_64_cuttlefish_defconfig: Enable android-verity x86_64_cuttlefish_defconfig: enable verity cert Linux 4.4.142 perf tools: Move syscall number fallbacks from perf-sys.h to tools/arch/x86/include/asm/ x86/cpu: Probe CPUID leaf 6 even when cpuid_level == 6 Kbuild: fix # escaping in .cmd files for future Make ANDROID: Fix massive cpufreq_times memory leaks ANDROID: Reduce use of #ifdef CONFIG_CPU_FREQ_TIMES UPSTREAM: binder: replace "%p" with "%pK" UPSTREAM: binder: free memory on error UPSTREAM: binder: fix proc->files use-after-free UPSTREAM: Revert "FROMLIST: binder: fix proc->files use-after-free" UPSTREAM: ANDROID: binder: change down_write to down_read UPSTREAM: ANDROID: binder: correct the cmd print for BINDER_WORK_RETURN_ERROR UPSTREAM: ANDROID: binder: remove 32-bit binder interface. UPSTREAM: ANDROID: binder: re-order some conditions UPSTREAM: android: binder: use VM_ALLOC to get vm area UPSTREAM: android: binder: Use true and false for boolean values UPSTREAM: android: binder: Use octal permissions UPSTREAM: android: binder: Prefer __func__ to using hardcoded function name UPSTREAM: ANDROID: binder: make binder_alloc_new_buf_locked static and indent its arguments UPSTREAM: android: binder: Check for errors in binder_alloc_shrinker_init(). treewide: Use array_size in f2fs_kvzalloc() treewide: Use array_size() in f2fs_kzalloc() treewide: Use array_size() in f2fs_kmalloc() overflow.h: Add allocation size calculation helpers f2fs: fix to clear FI_VOLATILE_FILE correctly f2fs: let sync node IO interrupt async one f2fs: don't change wbc->sync_mode f2fs: fix to update mtime correctly fs: f2fs: insert space around that ':' and ', ' fs: f2fs: add missing blank lines after declarations fs: f2fs: changed variable type of offset "unsigned" to "loff_t" f2fs: clean up symbol namespace f2fs: make set_de_type() static f2fs: make __f2fs_write_data_pages() static f2fs: fix to avoid accessing cross the boundary f2fs: fix to let caller retry allocating block address disable loading f2fs module on PAGE_SIZE > 4KB f2fs: fix error path of move_data_page f2fs: don't drop dentry pages after fs shutdown f2fs: fix to avoid race during access gc_thread pointer f2fs: clean up with clear_radix_tree_dirty_tag f2fs: fix to don't trigger writeback during recovery f2fs: clear discard_wake earlier f2fs: let discard thread wait a little longer if dev is busy f2fs: avoid stucking GC due to atomic write f2fs: introduce sbi->gc_mode to determine the policy f2fs: keep migration IO order in LFS mode f2fs: fix to wait page writeback during revoking atomic write f2fs: Fix deadlock in shutdown ioctl f2fs: detect synchronous writeback more earlier mm: remove nr_pages argument from pagevec_lookup_{,range}_tag() ceph: use pagevec_lookup_range_nr_tag() mm: add variant of pagevec_lookup_range_tag() taking number of pages mm: use pagevec_lookup_range_tag() in write_cache_pages() mm: use pagevec_lookup_range_tag() in __filemap_fdatawait_range() nilfs2: use pagevec_lookup_range_tag() gfs2: use pagevec_lookup_range_tag() f2fs: use find_get_pages_tag() for looking up single page f2fs: simplify page iteration loops f2fs: use pagevec_lookup_range_tag() ext4: use pagevec_lookup_range_tag() ceph: use pagevec_lookup_range_tag() btrfs: use pagevec_lookup_range_tag() mm: implement find_get_pages_range_tag() f2fs: clean up with is_valid_blkaddr() f2fs: fix to initialize min_mtime with ULLONG_MAX f2fs: fix to let checkpoint guarantee atomic page persistence f2fs: fix to initialize i_current_depth according to inode type Revert "f2fs: add ovp valid_blocks check for bg gc victim to fg_gc" f2fs: don't drop any page on f2fs_cp_error() case f2fs: fix spelling mistake: "extenstion" -> "extension" f2fs: enhance sanity_check_raw_super() to avoid potential overflows f2fs: treat volatile file's data as hot one f2fs: introduce release_discard_addr() for cleanup f2fs: fix potential overflow f2fs: rename dio_rwsem to i_gc_rwsem f2fs: move mnt_want_write_file after range check f2fs: fix missing clear FI_NO_PREALLOC in some error case f2fs: enforce fsync_mode=strict for renamed directory f2fs: sanity check for total valid node blocks f2fs: sanity check on sit entry f2fs: avoid bug_on on corrupted inode f2fs: give message and set need_fsck given broken node id f2fs: clean up commit_inmem_pages() f2fs: do not check F2FS_INLINE_DOTS in recover f2fs: remove duplicated dquot_initialize and fix error handling f2fs: stop issue discard if something wrong with f2fs f2fs: fix return value in f2fs_ioc_commit_atomic_write f2fs: allocate hot_data for atomic write more strictly f2fs: check if inmem_pages list is empty correctly f2fs: fix race in between GC and atomic open f2fs: change le32 to le16 of f2fs_inode->i_extra_size f2fs: check cur_valid_map_mir & raw_sit block count when flush sit entries f2fs: correct return value of f2fs_trim_fs f2fs: fix to show missing bits in FS_IOC_GETFLAGS f2fs: remove unneeded F2FS_PROJINHERIT_FL f2fs: don't use GFP_ZERO for page caches f2fs: issue all big range discards in umount process f2fs: remove redundant block plug f2fs: remove unmatched zero_user_segment when convert inline dentry f2fs: introduce private inode status mapping fscrypt: log the crypto algorithm implementations crypto: api - Add crypto_type_has_alg helper crypto: skcipher - Add low-level skcipher interface crypto: skcipher - Add helper to retrieve driver name crypto: skcipher - Add default key size helper fscrypt: add Speck128/256 support fscrypt: only derive the needed portion of the key fscrypt: separate key lookup from key derivation fscrypt: use a common logging function fscrypt: remove internal key size constants fscrypt: remove unnecessary check for non-logon key type fscrypt: make fscrypt_operations.max_namelen an integer fscrypt: drop empty name check from fname_decrypt() fscrypt: drop max_namelen check from fname_decrypt() fscrypt: don't special-case EOPNOTSUPP from fscrypt_get_encryption_info() fscrypt: don't clear flags on crypto transform fscrypt: remove stale comment from fscrypt_d_revalidate() fscrypt: remove error messages for skcipher_request_alloc() failure fscrypt: remove unnecessary NULL check when allocating skcipher fscrypt: clean up after fscrypt_prepare_lookup() conversions fscrypt: use unbound workqueue for decryption f2fs: run fstrim asynchronously if runtime discard is on f2fs: turn down IO priority of discard from background f2fs: don't split checkpoint in fstrim f2fs: issue discard commands proactively in high fs utilization f2fs: add fsync_mode=nobarrier for non-atomic files f2fs: let fstrim issue discard commands in lower priority f2fs: avoid fsync() failure caused by EAGAIN in writepage() f2fs: clear PageError on writepage - part 2 f2fs: check cap_resource only for data blocks Revert "f2fs: introduce f2fs_set_page_dirty_nobuffer" f2fs: clear PageError on writepage f2fs: call unlock_new_inode() before d_instantiate() f2fs: refactor read path to allow multiple postprocessing steps fscrypt: allow synchronous bio decryption f2fs: remain written times to update inode during fsync f2fs: make assignment of t->dentry_bitmap more readable f2fs: truncate preallocated blocks in error case f2fs: fix a wrong condition in f2fs_skip_inode_update f2fs: reserve bits for fs-verity f2fs: Add a segment type check in inplace write f2fs: no need to initialize zero value for GFP_F2FS_ZERO f2fs: don't track new nat entry in nat set f2fs: clean up with F2FS_BLK_ALIGN f2fs: check blkaddr more accuratly before issue a bio f2fs: Set GF_NOFS in read_cache_page_gfp while doing f2fs_quota_read f2fs: introduce a new mount option test_dummy_encryption f2fs: introduce F2FS_FEATURE_LOST_FOUND feature f2fs: release locks before return in f2fs_ioc_gc_range() f2fs: align memory boundary for bitops f2fs: remove unneeded set_cold_node() f2fs: add nowait aio support f2fs: wrap all options with f2fs_sb_info.mount_opt f2fs: Don't overwrite all types of node to keep node chain f2fs: introduce mount option for fsync mode f2fs: fix to restore old mount option in ->remount_fs f2fs: wrap sb_rdonly with f2fs_readonly f2fs: avoid selinux denial on CAP_SYS_RESOURCE f2fs: support hot file extension f2fs: fix to avoid race in between atomic write and background GC f2fs: do gc in greedy mode for whole range if gc_urgent mode is set f2fs: issue discard aggressively in the gc_urgent mode f2fs: set readdir_ra by default f2fs: add auto tuning for small devices f2fs: add mount option for segment allocation policy f2fs: don't stop GC if GC is contended f2fs: expose extension_list sysfs entry f2fs: fix to set KEEP_SIZE bit in f2fs_zero_range f2fs: introduce sb_lock to make encrypt pwsalt update exclusive f2fs: remove redundant initialization of pointer 'p' f2fs: flush cp pack except cp pack 2 page at first f2fs: clean up f2fs_sb_has_xxx functions f2fs: remove redundant check of page type when submit bio f2fs: fix to handle looped node chain during recovery f2fs: handle quota for orphan inodes f2fs: support passing down write hints to block layer with F2FS policy f2fs: support passing down write hints given by users to block layer f2fs: fix to clear CP_TRIMMED_FLAG f2fs: support large nat bitmap f2fs: fix to check extent cache in f2fs_drop_extent_tree f2fs: restrict inline_xattr_size configuration f2fs: fix heap mode to reset it back f2fs: fix potential corruption in area before F2FS_SUPER_OFFSET fscrypt: fix build with pre-4.6 gcc versions fscrypt: fix up fscrypt_fname_encrypted_size() for internal use fscrypt: define fscrypt_fname_alloc_buffer() to be for presented names fscrypt: calculate NUL-padding length in one place only fscrypt: move fscrypt_symlink_data to fscrypt_private.h fscrypt: remove fscrypt_fname_usr_to_disk() f2fs: switch to fscrypt_get_symlink() f2fs: switch to fscrypt ->symlink() helper functions fscrypt: new helper function - fscrypt_get_symlink() fscrypt: new helper functions for ->symlink() fscrypt: trim down fscrypt.h includes fscrypt: move fscrypt_is_dot_dotdot() to fs/crypto/fname.c fscrypt: move fscrypt_valid_enc_modes() to fscrypt_private.h fscrypt: move fscrypt_operations declaration to fscrypt_supp.h fscrypt: split fscrypt_dummy_context_enabled() into supp/notsupp versions fscrypt: move fscrypt_ctx declaration to fscrypt_supp.h fscrypt: move fscrypt_info_cachep declaration to fscrypt_private.h fscrypt: move fscrypt_control_page() to supp/notsupp headers fscrypt: move fscrypt_has_encryption_key() to supp/notsupp headers f2fs: don't put dentry page in pagecache into highmem f2fs: support inode creation time f2fs: rebuild sit page from sit info in mem f2fs: stop issuing discard if fs is readonly f2fs: clean up duplicated assignment in init_discard_policy f2fs: use GFP_F2FS_ZERO for cleanup f2fs: allow to recover node blocks given updated checkpoint f2fs: recover some i_inline flags f2fs: correct removexattr behavior for null valued extended attribute f2fs: drop page cache after fs shutdown f2fs: stop gc/discard thread after fs shutdown f2fs: hanlde error case in f2fs_ioc_shutdown f2fs: split need_inplace_update f2fs: fix to update last_disk_size correctly f2fs: kill F2FS_INLINE_XATTR_ADDRS for cleanup f2fs: clean up error path of fill_super f2fs: avoid hungtask when GC encrypted block if io_bits is set f2fs: allow quota to use reserved blocks f2fs: fix to drop all inmem pages correctly f2fs: speed up defragment on sparse file f2fs: support F2FS_IOC_PRECACHE_EXTENTS f2fs: add an ioctl to disable GC for specific file f2fs: prevent newly created inode from being dirtied incorrectly f2fs: support FIEMAP_FLAG_XATTR f2fs: fix to cover f2fs_inline_data_fiemap with inode_lock f2fs: check node page again in write end io f2fs: fix to caclulate required free section correctly f2fs: handle newly created page when revoking inmem pages f2fs: add resgid and resuid to reserve root blocks f2fs: implement cgroup writeback support f2fs: remove unused pend_list_tag f2fs: avoid high cpu usage in discard thread f2fs: make local functions static f2fs: add reserved blocks for root user f2fs: check segment type in __f2fs_replace_block f2fs: update inode info to inode page for new file f2fs: show precise # of blocks that user/root can use f2fs: clean up unneeded declaration f2fs: continue to do direct IO if we only preallocate partial blocks f2fs: enable quota at remount from r to w f2fs: skip stop_checkpoint for user data writes f2fs: fix missing error number for xattr operation f2fs: recover directory operations by fsync f2fs: return error during fill_super f2fs: fix an error case of missing update inode page f2fs: fix potential hangtask in f2fs_trace_pid f2fs: no need return value in restore summary process f2fs: use unlikely for release case f2fs: don't return value in truncate_data_blocks_range f2fs: clean up f2fs_map_blocks f2fs: clean up hash codes f2fs: fix error handling in fill_super f2fs: spread f2fs_k{m,z}alloc f2fs: inject fault to kvmalloc f2fs: inject fault to kzalloc f2fs: remove a redundant conditional expression f2fs: apply write hints to select the type of segment for direct write f2fs: switch to fscrypt_prepare_setattr() f2fs: switch to fscrypt_prepare_lookup() f2fs: switch to fscrypt_prepare_rename() f2fs: switch to fscrypt_prepare_link() f2fs: switch to fscrypt_file_open() f2fs: remove repeated f2fs_bug_on f2fs: remove an excess variable f2fs: fix lock dependency in between dio_rwsem & i_mmap_sem f2fs: remove unused parameter f2fs: still write data if preallocate only partial blocks f2fs: introduce sysfs readdir_ra to readahead inode block in readdir f2fs: fix concurrent problem for updating free bitmap f2fs: remove unneeded memory footprint accounting f2fs: no need to read nat block if nat_block_bitmap is set f2fs: reserve nid resource for quota sysfile fscrypt: resolve some cherry-pick bugs fscrypt: move to generic async completion crypto: introduce crypto wait for async op fscrypt: lock mutex before checking for bounce page pool fscrypt: new helper function - fscrypt_prepare_setattr() fscrypt: new helper function - fscrypt_prepare_lookup() fscrypt: new helper function - fscrypt_prepare_rename() fscrypt: new helper function - fscrypt_prepare_link() fscrypt: new helper function - fscrypt_file_open() fscrypt: new helper function - fscrypt_require_key() fscrypt: remove unneeded empty fscrypt_operations structs fscrypt: remove ->is_encrypted() fscrypt: switch from ->is_encrypted() to IS_ENCRYPTED() fs, fscrypt: add an S_ENCRYPTED inode flag fscrypt: clean up include file mess fscrypt: fix dereference of NULL user_key_payload fscrypt: make ->dummy_context() return bool f2fs: deny accessing encryption policy if encryption is off f2fs: inject fault in inc_valid_node_count f2fs: fix to clear FI_NO_PREALLOC f2fs: expose quota information in debugfs f2fs: separate nat entry mem alloc from nat_tree_lock f2fs: validate before set/clear free nat bitmap f2fs: avoid opened loop codes in __add_ino_entry f2fs: apply write hints to select the type of segments for buffered write f2fs: introduce scan_curseg_cache for cleanup f2fs: optimize the way of traversing free_nid_bitmap f2fs: keep scanning until enough free nids are acquired f2fs: trace checkpoint reason in fsync() f2fs: keep isize once block is reserved cross EOF f2fs: avoid race in between GC and block exchange f2fs: save a multiplication for last_nid calculation f2fs: fix summary info corruption f2fs: remove dead code in update_meta_page f2fs: remove unneeded semicolon f2fs: don't bother with inode->i_version f2fs: check curseg space before foreground GC f2fs: use rw_semaphore to protect SIT cache f2fs: support quota sys files f2fs: add quota_ino feature infra f2fs: optimize __update_nat_bits f2fs: modify for accurate fggc node io stat Revert "f2fs: handle dirty segments inside refresh_sit_entry" f2fs: add a function to move nid f2fs: export SSR allocation threshold f2fs: give correct trimmed blocks in fstrim f2fs: support bio allocation error injection f2fs: support get_page error injection f2fs: add missing sysfs description f2fs: support soft block reservation f2fs: handle error case when adding xattr entry f2fs: support flexible inline xattr size f2fs: show current cp state f2fs: add missing quota_initialize f2fs: show # of dirty segments via sysfs f2fs: stop all the operations by cp_error flag f2fs: remove several redundant assignments f2fs: avoid using timespec f2fs: fix to correct no_fggc_candidate Revert "f2fs: return wrong error number on f2fs_quota_write" f2fs: remove obsolete pointer for truncate_xattr_node f2fs: retry ENOMEM for quota_read|write f2fs: limit # of inmemory pages f2fs: update ctx->pos correctly when hitting hole in directory f2fs: relocate readahead codes in readdir() f2fs: allow readdir() to be interrupted f2fs: trace f2fs_readdir f2fs: trace f2fs_lookup f2fs: skip searching non-exist range in truncate_hole f2fs: expose some sectors to user in inline data or dentry case f2fs: avoid stale fi->gdirty_list pointer f2fs/crypto: drop crypto key at evict_inode only f2fs: fix to avoid race when accessing last_disk_size f2fs: Fix bool initialization/comparison f2fs: give up CP_TRIMMED_FLAG if it drops discards f2fs: trace f2fs_remove_discard f2fs: reduce cmd_lock coverage in __issue_discard_cmd f2fs: split discard policy f2fs: wrap discard policy f2fs: support issuing/waiting discard in range f2fs: fix to flush multiple device in checkpoint f2fs: enhance multiple device flush f2fs: fix to show ino management cache size correctly f2fs: drop FI_UPDATE_WRITE tag after f2fs_issue_flush f2fs: obsolete ALLOC_NID_LIST list f2fs: convert inline data for direct I/O & FI_NO_PREALLOC f2fs: allow readpages with NULL file pointer f2fs: show flush list status in sysfs f2fs: introduce read_xattr_block f2fs: introduce read_inline_xattr Revert "f2fs: reuse nids more aggressively" Revert "f2fs: node segment is prior to data segment selected victim" f2fs: fix potential panic during fstrim f2fs: hurry up to issue discard after io interruption f2fs: fix to show correct discard_granularity in sysfs f2fs: detect dirty inode in evict_inode f2fs: clear radix tree dirty tag of pages whose dirty flag is cleared f2fs: speed up gc_urgent mode with SSR f2fs: better to wait for fstrim completion f2fs: avoid race in between read xattr & write xattr f2fs: make get_lock_data_page to handle encrypted inode f2fs: use generic terms used for encrypted block management f2fs: introduce f2fs_encrypted_file for clean-up Revert "f2fs: add a new function get_ssr_cost" f2fs: constify super_operations f2fs: fix to wake up all sleeping flusher f2fs: avoid race in between atomic_read & atomic_inc f2fs: remove unneeded parameter of change_curseg f2fs: update i_flags correctly f2fs: don't check inode's checksum if it was dirtied or writebacked f2fs: don't need to update inode checksum for recovery f2fs: trigger fdatasync for non-atomic_write file f2fs: fix to avoid race in between aio and gc f2fs: wake up discard_thread iff there is a candidate f2fs: return error when accessing insane flie offset f2fs: trigger normal fsync for non-atomic_write file f2fs: clear FI_HOT_DATA correctly f2fs: fix out-of-order execution in f2fs_issue_flush f2fs: issue discard commands if gc_urgent is set f2fs: introduce discard_granularity sysfs entry f2fs: remove unused function overprovision_sections f2fs: check hot_data for roll-forward recovery f2fs: add tracepoint for f2fs_gc f2fs: retry to revoke atomic commit in -ENOMEM case f2fs: let fill_super handle roll-forward errors f2fs: merge equivalent flags F2FS_GET_BLOCK_[READ|DIO] f2fs: support journalled quota f2fs: fix potential overflow when adjusting GC cycle f2fs: avoid unneeded sync on quota file f2fs: introduce gc_urgent mode for background GC f2fs: use IPU for cold files f2fs: fix the size value in __check_sit_bitmap f2fs: add app/fs io stat f2fs: do not change the valid_block value if cur_valid_map was wrongly set or cleared f2fs: update cur_valid_map_mir together with cur_valid_map f2fs: use printk_ratelimited for f2fs_msg f2fs: expose features to sysfs entry f2fs: support inode checksum f2fs: return wrong error number on f2fs_quota_write f2fs: provide f2fs_balance_fs to __write_node_page f2fs: introduce f2fs_statfs_project f2fs: don't need to wait for node writes for atomic write f2fs: avoid naming confusion of sysfs init f2fs: support project quota f2fs: record quota during dot{,dot} recovery f2fs: enhance on-disk inode structure scalability f2fs: make max inline size changeable f2fs: add ioctl to expose current features f2fs: make background threads of f2fs being aware of freezing f2fs: don't give partially written atomic data from process crash f2fs: give a try to do atomic write in -ENOMEM case f2fs: preserve i_mode if __f2fs_set_acl() fails f2fs: alloc new nids for xattr block in recovery f2fs: spread struct f2fs_dentry_ptr for inline path f2fs: remove unused input parameter f2fs: avoid cpu lockup f2fs: include seq_file.h for sysfs.c f2fs: Don't clear SGID when inheriting ACLs f2fs: remove extra inode_unlock() in error path fscrypt: add support for AES-128-CBC fscrypt: inline fscrypt_free_filename() f2fs: make more close to v4.13-rc1 f2fs: support plain user/group quota f2fs: avoid deadlock caused by lock order of page and lock_op f2fs: use spin_{,un}lock_irq{save,restore} f2fs: relax migratepage for atomic written page f2fs: don't count inode block in in-memory inode.i_blocks Revert "f2fs: fix to clean previous mount option when remount_fs" f2fs: do not set LOST_PINO for renamed dir f2fs: do not set LOST_PINO for newly created dir f2fs: skip ->writepages for {mete,node}_inode during recovery f2fs: introduce __check_sit_bitmap f2fs: stop gc/discard thread in prior during umount f2fs: introduce reserved_blocks in sysfs f2fs: avoid redundant f2fs_flush after remount f2fs: report # of free inodes more precisely f2fs: add ioctl to do gc with target block address f2fs: don't need to check encrypted inode for partial truncation f2fs: measure inode.i_blocks as generic filesystem f2fs: set CP_TRIMMED_FLAG correctly f2fs: require key for truncate(2) of encrypted file f2fs: move sysfs code from super.c to fs/f2fs/sysfs.c f2fs: clean up sysfs codes f2fs: fix wrong error number of fill_super f2fs: fix to show injection rate in ->show_options f2fs: Fix a return value in case of error in 'f2fs_fill_super' f2fs: use proper variable name f2fs: fix to avoid panic when encountering corrupt node f2fs: don't track newly allocated nat entry in list f2fs: add f2fs_bug_on in __remove_discard_cmd f2fs: introduce __wait_one_discard_bio f2fs: dax: fix races between page faults and truncating pages f2fs: simplify the way of calulating next nat address f2fs: sanity check size of nat and sit cache f2fs: fix a panic caused by NULL flush_cmd_control f2fs: remove the unnecessary cast for PTR_ERR f2fs: remove false-positive bug_on f2fs: Do not issue small discards in LFS mode f2fs: don't bother checking for encryption key in ->write_iter() f2fs: don't bother checking for encryption key in ->mmap() f2fs: wait discard IO completion without cmd_lock held f2fs: wake up all waiters in f2fs_submit_discard_endio f2fs: show more info if fail to issue discard f2fs: introduce io_list for serialize data/node IOs f2fs: split wio_mutex f2fs: combine huge num of discard rb tree consistence checks f2fs: fix a bug caused by NULL extent tree f2fs: try to freeze in gc and discard threads f2fs: add a new function get_ssr_cost f2fs: declare load_free_nid_bitmap static f2fs: avoid f2fs_lock_op for IPU writes f2fs: split bio cache f2fs: use fio instead of multiple parameters f2fs: remove unnecessary read cases in merged IO flow f2fs: use f2fs_submit_page_bio for ra_meta_pages f2fs: make sure f2fs_gc returns consistent errno f2fs: load inode's flag from disk f2fs: sanity check checkpoint segno and blkoff f2fs, block_dump: give WRITE direction to submit_bio fscrypt: correct collision claim for digested names f2fs: switch to using fscrypt_match_name() fscrypt: introduce helper function for filename matching fscrypt: fix context consistency check when key(s) unavailable fscrypt: Move key structure and constants to uapi fscrypt: remove fscrypt_symlink_data_len() fscrypt: remove unnecessary checks for NULL operations fscrypt: eliminate ->prepare_context() operation fscrypt: remove broken support for detecting keyring key revocation fscrypt: avoid collisions when presenting long encrypted filenames f2fs: check entire encrypted bigname when finding a dentry f2fs: sync f2fs_lookup() with ext4_lookup() f2fs: fix a mount fail for wrong next_scan_nid f2fs: relocate inode_{,un}lock in F2FS_IOC_SETFLAGS f2fs: show available_nids in f2fs/status f2fs: flush dirty nats periodically f2fs: introduce CP_TRIMMED_FLAG to avoid unneeded discard f2fs: allow cpc->reason to indicate more than one reason f2fs: release cp and dnode lock before IPU f2fs: shrink size of struct discard_cmd f2fs: don't hold cmd_lock during waiting discard command f2fs: nullify fio->encrypted_page for each writes f2fs: sanity check segment count f2fs: introduce valid_ipu_blkaddr to clean up f2fs: lookup extent cache first under IPU scenario f2fs: reconstruct code to write a data page f2fs: introduce __wait_discard_cmd f2fs: introduce __issue_discard_cmd f2fs: enable small discard by default f2fs: delay awaking discard thread f2fs: seperate read nat page from nat_tree_lock f2fs: fix multiple f2fs_add_link() having same name for inline dentry f2fs: skip encrypted inode in ASYNC IPU policy f2fs: fix out-of free segments f2fs: improve definition of statistic macros f2fs: assign allocation hint for warm/cold data f2fs: fix _IOW usage f2fs: add ioctl to flush data from faster device to cold area f2fs: introduce async IPU policy f2fs: add undiscard blocks stat f2fs: unlock cp_rwsem early for IPU writes f2fs: introduce __check_rb_tree_consistence f2fs: trace __submit_discard_cmd f2fs: in prior to issue big discard f2fs: clean up discard_cmd_control structure f2fs: use rb-tree to track pending discard commands f2fs: avoid dirty node pages in check_only recovery f2fs: fix not to set fsync/dentry mark f2fs: allocate hot_data for atomic writes f2fs: give time to flush dirty pages for checkpoint f2fs: fix fs corruption due to zero inode page f2fs: shrink blk plug region f2fs: extract rb-tree operation infrastructure f2fs: avoid frequent checkpoint during f2fs_gc f2fs: clean up some macros in terms of GET_SEGNO f2fs: clean up get_valid_blocks with consistent parameter f2fs: use segment number for get_valid_blocks f2fs: guard macro variables with braces f2fs: fix comment on f2fs_flush_merged_bios() after 86531d6b f2fs: prevent waiter encountering incorrect discard states f2fs: introduce f2fs_wait_discard_bios f2fs: split discard_cmd_list Revert "f2fs: put allocate_segment after refresh_sit_entry" f2fs: split make_dentry_ptr() into block and inline versions f2fs: submit bio of in-place-update pages f2fs: remove the redundant variable definition f2fs: avoid IO split due to mixed WB_SYNC_ALL and WB_SYNC_NONE f2fs: write small sized IO to hot log f2fs: use bitmap in discard_entry f2fs: clean up destroy_discard_cmd_control f2fs: count discard command entry f2fs: show issued flush/discard count f2fs: relax node version check for victim data in gc f2fs: start SSR much eariler to avoid FG_GC f2fs: allocate node and hot data in the beginning of partition f2fs: fix wrong max cost initialization f2fs: allow write page cache when writting cp f2fs: don't reserve additional space in xattr block f2fs: clean up xattr operation f2fs: don't track volatile file in dirty inode list f2fs: show the max number of volatile operations f2fs: fix race condition in between free nid allocator/initializer f2fs: use set_page_private marcro in f2fs_trace_pid f2fs: fix recording invalid last_victim f2fs: more reasonable mem_size calculating of ino_entry f2fs: calculate the f2fs_stat_info into base_mem f2fs: avoid stat_inc_atomic_write for non-atomic file f2fs: sanity check of crc_offset from raw checkpoint f2fs: cleanup the disk level filename updating f2fs: cover update_free_nid_bitmap with nid_list_lock f2fs: fix bad prefetchw of NULL page f2fs: clear FI_DATA_EXIST flag in truncate_inline_inode f2fs: move mnt_want_write_file after arguments checking f2fs: check new size by inode_newsize_ok in f2fs_insert_range f2fs: avoid copy date to user-space if move file range fail f2fs: drop duplicate new_size assign in f2fs_zero_range f2fs: adjust the way of calculating nat block f2fs: add fault injection on f2fs_truncate f2fs: check range before defragment f2fs: use parameter max_items instead of PIDVEC_SIZE f2fs: add a punch discard command function f2fs: allocate a bio for discarding when actually issuing it f2fs: skip writeback meta pages if cp_mutex acquire failed f2fs: show more precise message on orphan recovery failure f2fs: remove dead macro PGOFS_OF_NEXT_DNODE f2fs: drop duplicate radix tree lookup of nat_entry_set f2fs: make sure trace all f2fs_issue_flush f2fs: don't allow volatile writes for non-regular file f2fs: don't allow atomic writes for not regular files f2fs: fix stale ATOMIC_WRITTEN_PAGE private pointer f2fs: build stat_info before orphan inode recovery f2fs: fix the fault of calculating blkstart twice f2fs: fix the fault of checking F2FS_LINK_MAX for rename inode f2fs: don't allow to get pino when filename is encrypted f2fs: fix wrong error injection for evict_inode f2fs: le32_to_cpu for ckpt->cp_pack_total_block_count f2fs: le16_to_cpu for xattr->e_value_size f2fs: don't need to invalidate wrong node page f2fs: fix an error return value in truncate_partial_data_page f2fs: combine nat_bits and free_nid_bitmap cache f2fs: skip scanning free nid bitmap of full NAT blocks f2fs: use __set{__clear}_bit_le f2fs: update_free_nid_bitmap() can be static f2fs: __update_nat_bits() can be static f2fs: le16_to_cpu for xattr->e_value_size f2fs: don't overwrite node block by SSR f2fs: don't need to invalidate wrong node page f2fs: fix an error return value in truncate_partial_data_page fscrypt: catch up to v4.11-rc1 f2fs: avoid to flush nat journal entries f2fs: avoid to issue redundant discard commands f2fs: fix a plint compile warning f2fs: add f2fs_drop_inode tracepoint f2fs: Fix zoned block device support f2fs: remove redundant set_page_dirty() f2fs: fix to enlarge size of write_io_dummy mempool f2fs: fix memory leak of write_io_dummy mempool during umount f2fs: fix to update F2FS_{CP_}WB_DATA count correctly f2fs: use MAX_FREE_NIDS for the free nids target f2fs: introduce free nid bitmap f2fs: new helper cur_cp_crc() getting crc in f2fs_checkpoint f2fs: update the comment of default nr_pages to skipping f2fs: drop the duplicate pval in f2fs_getxattr f2fs: Don't update the xattr data that same as the exist f2fs: kill __is_extent_same f2fs: avoid bggc->fggc when enough free segments are avaliable after cp f2fs: select target segment with closer temperature in SSR mode f2fs: show simple call stack in fault injection message fscrypt: catch fscrypto_get_policy in v4.10-rc6 f2fs: use __clear_bit_le f2fs: no need lock_op in f2fs_write_inline_data f2fs: add bitmaps for empty or full NAT blocks f2fs: replace rw semaphore extent_tree_lock with mutex lock f2fs: avoid m_flags overlay when allocating more data blocks f2fs: remove unsafe bitmap checking f2fs: init local extent_info to avoid stale stack info in tp f2fs: remove unnecessary condition check for write_checkpoint in f2fs_gc f2fs: do SSR for node segments more aggresively f2fs: check discard alignment only for SEQWRITE zones f2fs: wait for discard completion after submission f2fs: much larger batched trim_fs job f2fs: avoid very large discard command f2fs: find data segments across all the types f2fs: do SSR in higher priority f2fs: do SSR for data when there is enough free space f2fs: node segment is prior to data segment selected victim f2fs: put allocate_segment after refresh_sit_entry f2fs: add ovp valid_blocks check for bg gc victim to fg_gc f2fs: do not wait for writeback in write_begin f2fs: replace __get_victim by dirty_segments in FG_GC f2fs: fix multiple f2fs_add_link() calls having same name f2fs: show actual device info in tracepoints f2fs: use SSR for warm node as well f2fs: enable inline_xattr by default f2fs: introduce noinline_xattr mount option f2fs: avoid reading NAT page by get_node_info f2fs: remove build_free_nids() during checkpoint f2fs: change recovery policy of xattr node block f2fs: super: constify fscrypt_operations structure f2fs: show checkpoint version at mount time f2fs: remove preflush for nobarrier case f2fs: check last page index in cached bio to decide submission f2fs: check io submission more precisely f2fs: fix trim_fs assignment Revert "f2fs: remove batched discard in f2fs_trim_fs" f2fs: fix missing bio_alloc(1) f2fs: call internal __write_data_page directly f2fs: avoid out-of-order execution of atomic writes f2fs: move write_node_page above fsync_node_pages f2fs: move flush tracepoint f2fs: show # of APPEND and UPDATE inodes f2fs: fix 446 coding style warnings in f2fs.h f2fs: fix 3 coding style errors in f2fs.h f2fs: declare missing static function f2fs: show the fault injection mount option f2fs: fix null pointer dereference when issuing flush in ->fsync f2fs: fix to avoid overflow when left shifting page offset f2fs: enhance lookup xattr f2fs: fix a dead loop in f2fs_fiemap() f2fs: do not preallocate blocks which has wrong buffer f2fs: show # of on-going flush and discard bios f2fs: add a kernel thread to issue discard commands asynchronously f2fs: factor out discard command info into discard_cmd_control f2fs: remove batched discard in f2fs_trim_fs f2fs: reorganize stat information f2fs: clean up flush/discard command namings f2fs: check in-memory sit version bitmap f2fs: check in-memory nat version bitmap f2fs: check in-memory block bitmap f2fs: introduce FI_ATOMIC_COMMIT f2fs: clean up with list_{first, last}_entry f2fs: return fs_trim if there is no candidate f2fs: avoid needless checkpoint in f2fs_trim_fs f2fs: relax async discard commands more f2fs: drop exist_data for inline_data when truncated to 0 f2fs: don't allow encrypted operations without keys f2fs: show the max number of atomic operations f2fs: get io size bit from mount option f2fs: support IO alignment for DATA and NODE writes f2fs: add submit_bio tracepoint f2fs: reassign new segment for mode=lfs f2fs: fix a missing discard prefree segments f2fs: use rb_entry_safe f2fs: add a case of no need to read a page in write begin f2fs: fix a problem of using memory after free f2fs: remove unneeded condition f2fs: don't cache nat entry if out of memory f2fs: remove unused values in recover_fsync_data f2fs: support async discard based on v4.9 f2fs: resolve op and op_flags confilcts f2fs: remove wrong backported codes f2fs: fix a missing size change in f2fs_setattr fs/super.c: fix race between freeze_super() and thaw_super() scripts/tags.sh: catch 4.9-rc6 f2fs: fix to access nullified flush_cmd_control pointer f2fs: free meta pages if sanity check for ckpt is failed f2fs: detect wrong layout f2fs: call sync_fs when f2fs is idle Revert "f2fs: use percpu_counter for # of dirty pages in inode" f2fs: return AOP_WRITEPAGE_ACTIVATE for writepage f2fs: do not activate auto_recovery for fallocated i_size f2fs: fix 32-bit build f2fs: set ->owner for debugfs status file's file_operations f2fs: fix incorrect free inode count in ->statfs f2fs: drop duplicate header timer.h f2fs: fix wrong AUTO_RECOVER condition f2fs: do not recover i_size if it's valid f2fs: fix fdatasync f2fs: fix to account total free nid correctly f2fs: fix an infinite loop when flush nodes in cp f2fs: don't wait writeback for datas during checkpoint f2fs: fix wrong written_valid_blocks counting f2fs: avoid BG_GC in f2fs_balance_fs f2fs: fix redundant block allocation f2fs: use err for f2fs_preallocate_blocks f2fs: support multiple devices f2fs: allow dio read for LFS mode f2fs: revert segment allocation for direct IO f2fs: return directly if block has been removed from the victim Revert "f2fs: do not recover from previous remained wrong dnodes" f2fs: remove checkpoint in f2fs_freeze f2fs: assign segments correctly for direct_io f2fs: fix wrong i_atime recovery f2fs: record inode updating status correctly f2fs: Trace reset zone events f2fs: Reset sequential zones on zoned block devices f2fs: Cache zoned block devices zone type f2fs: Do not allow adaptive mode for host-managed zoned block devices f2fs: Always enable discard for zoned blocks devices f2fs: Suppress discard warning message for zoned block devices f2fs: Check zoned block feature for host-managed zoned block devices f2fs: Use generic zoned block device terminology f2fs: Add missing break in switch-case f2fs: avoid infinite loop in the EIO case on recover_orphan_inodes f2fs: report error of f2fs_fill_dentries fs/crypto: catch up 4.9-rc6 f2fs: hide a maybe-uninitialized warning f2fs: remove percpu_count due to performance regression f2fs: make clean inodes when flushing inode page f2fs: keep dirty inodes selectively for checkpoint f2fs: Replace CURRENT_TIME_SEC with current_time() for inode timestamps f2fs: use BIO_MAX_PAGES for bio allocation f2fs: declare static function for __build_free_nids f2fs: call f2fs_balance_fs for setattr f2fs: count dirty inodes to flush node pages during checkpoint f2fs: avoid casted negative value as shrink count f2fs: don't interrupt free nids building during nid allocation f2fs: clean up free nid list operations f2fs: split free nid list f2fs: clear nlink if fail to add_link f2fs: fix sparse warnings f2fs: fix error handling in fsync_node_pages f2fs: fix to update largest extent under lock f2fs: be aware of extent beyond EOF in fiemap f2fs: don't miss any f2fs_balance_fs cases f2fs: add missing f2fs_balance_fs in f2fs_zero_range f2fs: give a chance to detach from dirty list f2fs: fix to release discard entries during checkpoint f2fs: exclude free nids building and allocation f2fs: fix to determine start_cp_addr by sbi->cur_cp_pack f2fs: fix overflow due to condition check order posix_acl: Clear SGID bit when setting file permissions f2fs: fix wrong sum_page pointer in f2fs_gc f2fs: backport from (4c1fad64 - Merge tag 'for-f2fs-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs) Change-Id: I6c7208efc63ce7b13f26f0ec1cd3c8aef410eff0 Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org> Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r--fs/f2fs/segment.c384
1 files changed, 236 insertions, 148 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index a02d5c1a7ed2..3d0c42ef0474 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -169,7 +169,7 @@ found:
return result - size + __reverse_ffz(tmp);
}
-bool need_SSR(struct f2fs_sb_info *sbi)
+bool f2fs_need_SSR(struct f2fs_sb_info *sbi)
{
int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES);
int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS);
@@ -177,14 +177,14 @@ bool need_SSR(struct f2fs_sb_info *sbi)
if (test_opt(sbi, LFS))
return false;
- if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
+ if (sbi->gc_mode == GC_URGENT)
return true;
return free_sections(sbi) <= (node_secs + 2 * dent_secs + imeta_secs +
SM_I(sbi)->min_ssr_sections + reserved_sections(sbi));
}
-void register_inmem_page(struct inode *inode, struct page *page)
+void f2fs_register_inmem_page(struct inode *inode, struct page *page)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -230,6 +230,8 @@ static int __revoke_inmem_pages(struct inode *inode,
lock_page(page);
+ f2fs_wait_on_page_writeback(page, DATA, true);
+
if (recover) {
struct dnode_of_data dn;
struct node_info ni;
@@ -237,7 +239,8 @@ static int __revoke_inmem_pages(struct inode *inode,
trace_f2fs_commit_inmem_page(page, INMEM_REVOKE);
retry:
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, page->index,
+ LOOKUP_NODE);
if (err) {
if (err == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);
@@ -247,9 +250,9 @@ retry:
err = -EAGAIN;
goto next;
}
- get_node_info(sbi, dn.nid, &ni);
+ f2fs_get_node_info(sbi, dn.nid, &ni);
if (cur->old_addr == NEW_ADDR) {
- invalidate_blocks(sbi, dn.data_blkaddr);
+ f2fs_invalidate_blocks(sbi, dn.data_blkaddr);
f2fs_update_data_blkaddr(&dn, NEW_ADDR);
} else
f2fs_replace_block(sbi, &dn, dn.data_blkaddr,
@@ -271,7 +274,7 @@ next:
return err;
}
-void drop_inmem_pages_all(struct f2fs_sb_info *sbi)
+void f2fs_drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure)
{
struct list_head *head = &sbi->inode_list[ATOMIC_FILE];
struct inode *inode;
@@ -287,15 +290,23 @@ next:
spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
if (inode) {
- drop_inmem_pages(inode);
+ if (gc_failure) {
+ if (fi->i_gc_failures[GC_FAILURE_ATOMIC])
+ goto drop;
+ goto skip;
+ }
+drop:
+ set_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+ f2fs_drop_inmem_pages(inode);
iput(inode);
}
+skip:
congestion_wait(BLK_RW_ASYNC, HZ/50);
cond_resched();
goto next;
}
-void drop_inmem_pages(struct inode *inode)
+void f2fs_drop_inmem_pages(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -309,11 +320,11 @@ void drop_inmem_pages(struct inode *inode)
mutex_unlock(&fi->inmem_lock);
clear_inode_flag(inode, FI_ATOMIC_FILE);
- clear_inode_flag(inode, FI_HOT_DATA);
+ fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
stat_dec_atomic_write(inode);
}
-void drop_inmem_page(struct inode *inode, struct page *page)
+void f2fs_drop_inmem_page(struct inode *inode, struct page *page)
{
struct f2fs_inode_info *fi = F2FS_I(inode);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -328,7 +339,7 @@ void drop_inmem_page(struct inode *inode, struct page *page)
break;
}
- f2fs_bug_on(sbi, !cur || cur->page != page);
+ f2fs_bug_on(sbi, list_empty(head) || cur->page != page);
list_del(&cur->list);
mutex_unlock(&fi->inmem_lock);
@@ -343,8 +354,7 @@ void drop_inmem_page(struct inode *inode, struct page *page)
trace_f2fs_commit_inmem_page(page, INMEM_INVALIDATE);
}
-static int __commit_inmem_pages(struct inode *inode,
- struct list_head *revoke_list)
+static int __f2fs_commit_inmem_pages(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -357,9 +367,12 @@ static int __commit_inmem_pages(struct inode *inode,
.op_flags = REQ_SYNC | REQ_PRIO,
.io_type = FS_DATA_IO,
};
+ struct list_head revoke_list;
pgoff_t last_idx = ULONG_MAX;
int err = 0;
+ INIT_LIST_HEAD(&revoke_list);
+
list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) {
struct page *page = cur->page;
@@ -371,14 +384,14 @@ static int __commit_inmem_pages(struct inode *inode,
f2fs_wait_on_page_writeback(page, DATA, true);
if (clear_page_dirty_for_io(page)) {
inode_dec_dirty_pages(inode);
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
}
retry:
fio.page = page;
fio.old_blkaddr = NULL_ADDR;
fio.encrypted_page = NULL;
fio.need_lock = LOCK_DONE;
- err = do_write_data_page(&fio);
+ err = f2fs_do_write_data_page(&fio);
if (err) {
if (err == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);
@@ -393,50 +406,46 @@ retry:
last_idx = page->index;
}
unlock_page(page);
- list_move_tail(&cur->list, revoke_list);
+ list_move_tail(&cur->list, &revoke_list);
}
if (last_idx != ULONG_MAX)
f2fs_submit_merged_write_cond(sbi, inode, 0, last_idx, DATA);
- if (!err)
- __revoke_inmem_pages(inode, revoke_list, false, false);
+ if (err) {
+ /*
+ * try to revoke all committed pages, but still we could fail
+ * due to no memory or other reason, if that happened, EAGAIN
+ * will be returned, which means in such case, transaction is
+ * already not integrity, caller should use journal to do the
+ * recovery or rewrite & commit last transaction. For other
+ * error number, revoking was done by filesystem itself.
+ */
+ err = __revoke_inmem_pages(inode, &revoke_list, false, true);
+
+ /* drop all uncommitted pages */
+ __revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
+ } else {
+ __revoke_inmem_pages(inode, &revoke_list, false, false);
+ }
return err;
}
-int commit_inmem_pages(struct inode *inode)
+int f2fs_commit_inmem_pages(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
- struct list_head revoke_list;
int err;
- INIT_LIST_HEAD(&revoke_list);
f2fs_balance_fs(sbi, true);
f2fs_lock_op(sbi);
set_inode_flag(inode, FI_ATOMIC_COMMIT);
mutex_lock(&fi->inmem_lock);
- err = __commit_inmem_pages(inode, &revoke_list);
- if (err) {
- int ret;
- /*
- * try to revoke all committed pages, but still we could fail
- * due to no memory or other reason, if that happened, EAGAIN
- * will be returned, which means in such case, transaction is
- * already not integrity, caller should use journal to do the
- * recovery or rewrite & commit last transaction. For other
- * error number, revoking was done by filesystem itself.
- */
- ret = __revoke_inmem_pages(inode, &revoke_list, false, true);
- if (ret)
- err = ret;
+ err = __f2fs_commit_inmem_pages(inode);
- /* drop all uncommitted pages */
- __revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
- }
spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
if (!list_empty(&fi->inmem_ilist))
list_del_init(&fi->inmem_ilist);
@@ -478,25 +487,28 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
{
+ if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
+ return;
+
/* try to shrink extent cache when there is no enough memory */
- if (!available_free_memory(sbi, EXTENT_CACHE))
+ if (!f2fs_available_free_memory(sbi, EXTENT_CACHE))
f2fs_shrink_extent_tree(sbi, EXTENT_CACHE_SHRINK_NUMBER);
/* check the # of cached NAT entries */
- if (!available_free_memory(sbi, NAT_ENTRIES))
- try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK);
+ if (!f2fs_available_free_memory(sbi, NAT_ENTRIES))
+ f2fs_try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK);
- if (!available_free_memory(sbi, FREE_NIDS))
- try_to_free_nids(sbi, MAX_FREE_NIDS);
+ if (!f2fs_available_free_memory(sbi, FREE_NIDS))
+ f2fs_try_to_free_nids(sbi, MAX_FREE_NIDS);
else
- build_free_nids(sbi, false, false);
+ f2fs_build_free_nids(sbi, false, false);
if (!is_idle(sbi) && !excess_dirty_nats(sbi))
return;
/* checkpoint is the only way to shrink partial cached entries */
- if (!available_free_memory(sbi, NAT_ENTRIES) ||
- !available_free_memory(sbi, INO_ENTRIES) ||
+ if (!f2fs_available_free_memory(sbi, NAT_ENTRIES) ||
+ !f2fs_available_free_memory(sbi, INO_ENTRIES) ||
excess_prefree_segs(sbi) ||
excess_dirty_nats(sbi) ||
f2fs_time_over(sbi, CP_TIME)) {
@@ -504,7 +516,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
struct blk_plug plug;
blk_start_plug(&plug);
- sync_dirty_inodes(sbi, FILE_INODE);
+ f2fs_sync_dirty_inodes(sbi, FILE_INODE);
blk_finish_plug(&plug);
}
f2fs_sync_fs(sbi->sb, true);
@@ -537,7 +549,7 @@ static int submit_flush_wait(struct f2fs_sb_info *sbi, nid_t ino)
return __submit_flush_wait(sbi, sbi->sb->s_bdev);
for (i = 0; i < sbi->s_ndevs; i++) {
- if (!is_dirty_device(sbi, ino, i, FLUSH_INO))
+ if (!f2fs_is_dirty_device(sbi, ino, i, FLUSH_INO))
continue;
ret = __submit_flush_wait(sbi, FDEV(i).bdev);
if (ret)
@@ -648,7 +660,7 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino)
return cmd.ret;
}
-int create_flush_cmd_control(struct f2fs_sb_info *sbi)
+int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi)
{
dev_t dev = sbi->sb->s_bdev->bd_dev;
struct flush_cmd_control *fcc;
@@ -685,7 +697,7 @@ init_thread:
return err;
}
-void destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free)
+void f2fs_destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free)
{
struct flush_cmd_control *fcc = SM_I(sbi)->fcc_info;
@@ -1010,6 +1022,7 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
if (discard_type == DPOLICY_BG) {
dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ dpolicy->mid_interval = DEF_MID_DISCARD_ISSUE_TIME;
dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
dpolicy->io_aware = true;
dpolicy->sync = false;
@@ -1019,11 +1032,13 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
}
} else if (discard_type == DPOLICY_FORCE) {
dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ dpolicy->mid_interval = DEF_MID_DISCARD_ISSUE_TIME;
dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
dpolicy->io_aware = false;
} else if (discard_type == DPOLICY_FSTRIM) {
dpolicy->io_aware = false;
} else if (discard_type == DPOLICY_UMOUNT) {
+ dpolicy->max_requests = UINT_MAX;
dpolicy->io_aware = false;
}
}
@@ -1043,6 +1058,9 @@ static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
if (dc->state != D_PREP)
return;
+ if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
+ return;
+
trace_f2fs_issue_discard(dc->bdev, dc->start, dc->len);
dc->error = __blkdev_issue_discard(dc->bdev,
@@ -1085,7 +1103,7 @@ static struct discard_cmd *__insert_discard_tree(struct f2fs_sb_info *sbi,
goto do_insert;
}
- p = __lookup_rb_tree_for_insert(sbi, &dcc->root, &parent, lstart);
+ p = f2fs_lookup_rb_tree_for_insert(sbi, &dcc->root, &parent, lstart);
do_insert:
dc = __attach_discard_cmd(sbi, bdev, lstart, start, len, parent, p);
if (!dc)
@@ -1150,7 +1168,7 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
mutex_lock(&dcc->cmd_lock);
- dc = (struct discard_cmd *)__lookup_rb_tree_ret(&dcc->root,
+ dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
NULL, lstart,
(struct rb_entry **)&prev_dc,
(struct rb_entry **)&next_dc,
@@ -1261,7 +1279,8 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
mutex_lock(&dcc->cmd_lock);
if (list_empty(pend_list))
goto next;
- f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root));
+ f2fs_bug_on(sbi,
+ !f2fs_check_rb_tree_consistence(sbi, &dcc->root));
blk_start_plug(&plug);
list_for_each_entry_safe(dc, tmp, pend_list, list) {
f2fs_bug_on(sbi, dc->state != D_PREP);
@@ -1314,7 +1333,7 @@ static bool __drop_discard_cmd(struct f2fs_sb_info *sbi)
return dropped;
}
-void drop_discard_cmd(struct f2fs_sb_info *sbi)
+void f2fs_drop_discard_cmd(struct f2fs_sb_info *sbi)
{
__drop_discard_cmd(sbi);
}
@@ -1405,7 +1424,8 @@ static void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
bool need_wait = false;
mutex_lock(&dcc->cmd_lock);
- dc = (struct discard_cmd *)__lookup_rb_tree(&dcc->root, NULL, blkaddr);
+ dc = (struct discard_cmd *)f2fs_lookup_rb_tree(&dcc->root,
+ NULL, blkaddr);
if (dc) {
if (dc->state == D_PREP) {
__punch_discard_cmd(sbi, dc, blkaddr);
@@ -1420,7 +1440,7 @@ static void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
__wait_one_discard_bio(sbi, dc);
}
-void stop_discard_thread(struct f2fs_sb_info *sbi)
+void f2fs_stop_discard_thread(struct f2fs_sb_info *sbi)
{
struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
@@ -1468,25 +1488,32 @@ static int issue_discard_thread(void *data)
kthread_should_stop() || freezing(current) ||
dcc->discard_wake,
msecs_to_jiffies(wait_ms));
+
+ if (dcc->discard_wake)
+ dcc->discard_wake = 0;
+
if (try_to_freeze())
continue;
if (f2fs_readonly(sbi->sb))
continue;
if (kthread_should_stop())
return 0;
+ if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) {
+ wait_ms = dpolicy.max_interval;
+ continue;
+ }
- if (dcc->discard_wake)
- dcc->discard_wake = 0;
-
- if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
+ if (sbi->gc_mode == GC_URGENT)
__init_discard_policy(sbi, &dpolicy, DPOLICY_FORCE, 1);
sb_start_intwrite(sbi->sb);
issued = __issue_discard_cmd(sbi, &dpolicy);
- if (issued) {
+ if (issued > 0) {
__wait_all_discard_cmd(sbi, &dpolicy);
wait_ms = dpolicy.min_interval;
+ } else if (issued == -1){
+ wait_ms = dpolicy.mid_interval;
} else {
wait_ms = dpolicy.max_interval;
}
@@ -1655,20 +1682,24 @@ static bool add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc,
return false;
}
-void release_discard_addrs(struct f2fs_sb_info *sbi)
+static void release_discard_addr(struct discard_entry *entry)
+{
+ list_del(&entry->list);
+ kmem_cache_free(discard_entry_slab, entry);
+}
+
+void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi)
{
struct list_head *head = &(SM_I(sbi)->dcc_info->entry_list);
struct discard_entry *entry, *this;
/* drop caches */
- list_for_each_entry_safe(entry, this, head, list) {
- list_del(&entry->list);
- kmem_cache_free(discard_entry_slab, entry);
- }
+ list_for_each_entry_safe(entry, this, head, list)
+ release_discard_addr(entry);
}
/*
- * Should call clear_prefree_segments after checkpoint is done.
+ * Should call f2fs_clear_prefree_segments after checkpoint is done.
*/
static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
{
@@ -1681,7 +1712,8 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
mutex_unlock(&dirty_i->seglist_lock);
}
-void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
+ struct cp_control *cpc)
{
struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
struct list_head *head = &dcc->entry_list;
@@ -1764,9 +1796,8 @@ skip:
if (cur_pos < sbi->blocks_per_seg)
goto find_next;
- list_del(&entry->list);
+ release_discard_addr(entry);
dcc->nr_discards -= total_len;
- kmem_cache_free(discard_entry_slab, entry);
}
wake_up_discard_thread(sbi, false);
@@ -1824,7 +1855,7 @@ static void destroy_discard_cmd_control(struct f2fs_sb_info *sbi)
if (!dcc)
return;
- stop_discard_thread(sbi);
+ f2fs_stop_discard_thread(sbi);
kfree(dcc);
SM_I(sbi)->dcc_info = NULL;
@@ -1871,8 +1902,9 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
(new_vblocks > sbi->blocks_per_seg)));
se->valid_blocks = new_vblocks;
- se->mtime = get_mtime(sbi);
- SIT_I(sbi)->max_mtime = se->mtime;
+ se->mtime = get_mtime(sbi, false);
+ if (se->mtime > SIT_I(sbi)->max_mtime)
+ SIT_I(sbi)->max_mtime = se->mtime;
/* Update valid block bitmap */
if (del > 0) {
@@ -1940,7 +1972,7 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
get_sec_entry(sbi, segno)->valid_blocks += del;
}
-void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
+void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
{
unsigned int segno = GET_SEGNO(sbi, addr);
struct sit_info *sit_i = SIT_I(sbi);
@@ -1960,14 +1992,14 @@ void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
up_write(&sit_i->sentry_lock);
}
-bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr)
+bool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr)
{
struct sit_info *sit_i = SIT_I(sbi);
unsigned int segno, offset;
struct seg_entry *se;
bool is_cp = false;
- if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
+ if (!is_valid_blkaddr(blkaddr))
return true;
down_read(&sit_i->sentry_lock);
@@ -1999,7 +2031,7 @@ static void __add_sum_entry(struct f2fs_sb_info *sbi, int type,
/*
* Calculate the number of current summary pages for writing
*/
-int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)
+int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)
{
int valid_sum_count = 0;
int i, sum_in_page;
@@ -2029,14 +2061,15 @@ int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)
/*
* Caller should put this summary page
*/
-struct page *get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno)
+struct page *f2fs_get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno)
{
- return get_meta_page(sbi, GET_SUM_BLOCK(sbi, segno));
+ return f2fs_get_meta_page(sbi, GET_SUM_BLOCK(sbi, segno));
}
-void update_meta_page(struct f2fs_sb_info *sbi, void *src, block_t blk_addr)
+void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
+ void *src, block_t blk_addr)
{
- struct page *page = grab_meta_page(sbi, blk_addr);
+ struct page *page = f2fs_grab_meta_page(sbi, blk_addr);
memcpy(page_address(page), src, PAGE_SIZE);
set_page_dirty(page);
@@ -2046,18 +2079,19 @@ void update_meta_page(struct f2fs_sb_info *sbi, void *src, block_t blk_addr)
static void write_sum_page(struct f2fs_sb_info *sbi,
struct f2fs_summary_block *sum_blk, block_t blk_addr)
{
- update_meta_page(sbi, (void *)sum_blk, blk_addr);
+ f2fs_update_meta_page(sbi, (void *)sum_blk, blk_addr);
}
static void write_current_sum_page(struct f2fs_sb_info *sbi,
int type, block_t blk_addr)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
- struct page *page = grab_meta_page(sbi, blk_addr);
+ struct page *page = f2fs_grab_meta_page(sbi, blk_addr);
struct f2fs_summary_block *src = curseg->sum_blk;
struct f2fs_summary_block *dst;
dst = (struct f2fs_summary_block *)page_address(page);
+ memset(dst, 0, PAGE_SIZE);
mutex_lock(&curseg->curseg_mutex);
@@ -2297,7 +2331,7 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)
curseg->alloc_type = SSR;
__next_free_blkoff(sbi, curseg, 0);
- sum_page = get_sum_page(sbi, new_segno);
+ sum_page = f2fs_get_sum_page(sbi, new_segno);
sum_node = (struct f2fs_summary_block *)page_address(sum_page);
memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
f2fs_put_page(sum_page, 1);
@@ -2311,7 +2345,7 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type)
int i, cnt;
bool reversed = false;
- /* need_SSR() already forces to do this */
+ /* f2fs_need_SSR() already forces to do this */
if (v_ops->get_victim(sbi, &segno, BG_GC, type, SSR)) {
curseg->next_segno = segno;
return 1;
@@ -2363,7 +2397,7 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
new_curseg(sbi, type, false);
else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
new_curseg(sbi, type, false);
- else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
+ else if (f2fs_need_SSR(sbi) && get_ssr_segment(sbi, type))
change_curseg(sbi, type);
else
new_curseg(sbi, type, false);
@@ -2371,7 +2405,7 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
stat_inc_seg_type(sbi, curseg);
}
-void allocate_new_segments(struct f2fs_sb_info *sbi)
+void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
{
struct curseg_info *curseg;
unsigned int old_segno;
@@ -2393,7 +2427,8 @@ static const struct segment_allocation default_salloc_ops = {
.allocate_segment = allocate_segment_by_default,
};
-bool exist_trim_candidates(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
+ struct cp_control *cpc)
{
__u64 trim_start = cpc->trim_start;
bool has_candidate = false;
@@ -2426,9 +2461,9 @@ next:
issued = 0;
mutex_lock(&dcc->cmd_lock);
- f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root));
+ f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi, &dcc->root));
- dc = (struct discard_cmd *)__lookup_rb_tree_ret(&dcc->root,
+ dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
NULL, start,
(struct rb_entry **)&prev_dc,
(struct rb_entry **)&next_dc,
@@ -2487,12 +2522,12 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
return -EINVAL;
if (end <= MAIN_BLKADDR(sbi))
- goto out;
+ return -EINVAL;
if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) {
f2fs_msg(sbi->sb, KERN_WARNING,
"Found FS corruption, run fsck to fix.");
- goto out;
+ return -EIO;
}
/* start/end segment number in main_area */
@@ -2509,7 +2544,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
goto out;
mutex_lock(&sbi->gc_mutex);
- err = write_checkpoint(sbi, &cpc);
+ err = f2fs_write_checkpoint(sbi, &cpc);
mutex_unlock(&sbi->gc_mutex);
if (err)
goto out;
@@ -2543,7 +2578,7 @@ static bool __has_curseg_space(struct f2fs_sb_info *sbi, int type)
return false;
}
-int rw_hint_to_seg_type(enum rw_hint hint)
+int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
{
switch (hint) {
case WRITE_LIFE_SHORT:
@@ -2616,7 +2651,7 @@ int rw_hint_to_seg_type(enum rw_hint hint)
* WRITE_LIFE_LONG " WRITE_LIFE_LONG
*/
-enum rw_hint io_type_to_rw_hint(struct f2fs_sb_info *sbi,
+enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
enum page_type type, enum temp_type temp)
{
if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER) {
@@ -2683,9 +2718,11 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
if (is_cold_data(fio->page) || file_is_cold(inode))
return CURSEG_COLD_DATA;
if (file_is_hot(inode) ||
- is_inode_flag_set(inode, FI_HOT_DATA))
+ is_inode_flag_set(inode, FI_HOT_DATA) ||
+ is_inode_flag_set(inode, FI_ATOMIC_FILE) ||
+ is_inode_flag_set(inode, FI_VOLATILE_FILE))
return CURSEG_HOT_DATA;
- /* rw_hint_to_seg_type(inode->i_write_hint); */
+ /* f2fs_rw_hint_to_seg_type(inode->i_write_hint); */
return CURSEG_WARM_DATA;
} else {
if (IS_DNODE(fio->page))
@@ -2722,7 +2759,7 @@ static int __get_segment_type(struct f2fs_io_info *fio)
return type;
}
-void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
block_t old_blkaddr, block_t *new_blkaddr,
struct f2fs_summary *sum, int type,
struct f2fs_io_info *fio, bool add_list)
@@ -2782,6 +2819,7 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
INIT_LIST_HEAD(&fio->list);
fio->in_list = true;
+ fio->retry = false;
io = sbi->write_io[fio->type] + fio->temp;
spin_lock(&io->io_lock);
list_add_tail(&fio->list, &io->io_list);
@@ -2804,7 +2842,7 @@ static void update_device_state(struct f2fs_io_info *fio)
devidx = f2fs_target_device_index(sbi, fio->new_blkaddr);
/* update device state for fsync */
- set_dirty_device(sbi, fio->ino, devidx, FLUSH_INO);
+ f2fs_set_dirty_device(sbi, fio->ino, devidx, FLUSH_INO);
/* update device state for checkpoint */
if (!f2fs_test_bit(devidx, (char *)&sbi->dirty_device)) {
@@ -2817,23 +2855,28 @@ static void update_device_state(struct f2fs_io_info *fio)
static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
{
int type = __get_segment_type(fio);
- int err;
+ bool keep_order = (test_opt(fio->sbi, LFS) && type == CURSEG_COLD_DATA);
+ if (keep_order)
+ down_read(&fio->sbi->io_order_lock);
reallocate:
- allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
+ f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
&fio->new_blkaddr, sum, type, fio, true);
/* writeout dirty page into bdev */
- err = f2fs_submit_page_write(fio);
- if (err == -EAGAIN) {
+ f2fs_submit_page_write(fio);
+ if (fio->retry) {
fio->old_blkaddr = fio->new_blkaddr;
goto reallocate;
- } else if (!err) {
- update_device_state(fio);
}
+
+ update_device_state(fio);
+
+ if (keep_order)
+ up_read(&fio->sbi->io_order_lock);
}
-void write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
+void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
enum iostat_type io_type)
{
struct f2fs_io_info fio = {
@@ -2859,7 +2902,7 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
f2fs_update_iostat(sbi, io_type, F2FS_BLKSIZE);
}
-void write_node_page(unsigned int nid, struct f2fs_io_info *fio)
+void f2fs_do_write_node_page(unsigned int nid, struct f2fs_io_info *fio)
{
struct f2fs_summary sum;
@@ -2869,14 +2912,15 @@ void write_node_page(unsigned int nid, struct f2fs_io_info *fio)
f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE);
}
-void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio)
+void f2fs_outplace_write_data(struct dnode_of_data *dn,
+ struct f2fs_io_info *fio)
{
struct f2fs_sb_info *sbi = fio->sbi;
struct f2fs_summary sum;
struct node_info ni;
f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR);
- get_node_info(sbi, dn->nid, &ni);
+ f2fs_get_node_info(sbi, dn->nid, &ni);
set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
do_write_page(&sum, fio);
f2fs_update_data_blkaddr(dn, fio->new_blkaddr);
@@ -2884,7 +2928,7 @@ void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio)
f2fs_update_iostat(sbi, fio->io_type, F2FS_BLKSIZE);
}
-int rewrite_data_page(struct f2fs_io_info *fio)
+int f2fs_inplace_write_data(struct f2fs_io_info *fio)
{
int err;
struct f2fs_sb_info *sbi = fio->sbi;
@@ -2919,7 +2963,7 @@ static inline int __f2fs_get_curseg(struct f2fs_sb_info *sbi,
return i;
}
-void __f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
block_t old_blkaddr, block_t new_blkaddr,
bool recover_curseg, bool recover_newaddr)
{
@@ -3004,7 +3048,7 @@ void f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
set_summary(&sum, dn->nid, dn->ofs_in_node, version);
- __f2fs_replace_block(sbi, &sum, old_addr, new_addr,
+ f2fs_do_replace_block(sbi, &sum, old_addr, new_addr,
recover_curseg, recover_newaddr);
f2fs_update_data_blkaddr(dn, new_addr);
@@ -3029,7 +3073,7 @@ void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr)
{
struct page *cpage;
- if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
+ if (!is_valid_blkaddr(blkaddr))
return;
cpage = find_lock_page(META_MAPPING(sbi), blkaddr);
@@ -3050,7 +3094,7 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
start = start_sum_block(sbi);
- page = get_meta_page(sbi, start++);
+ page = f2fs_get_meta_page(sbi, start++);
kaddr = (unsigned char *)page_address(page);
/* Step 1: restore nat cache */
@@ -3090,7 +3134,7 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
f2fs_put_page(page, 1);
page = NULL;
- page = get_meta_page(sbi, start++);
+ page = f2fs_get_meta_page(sbi, start++);
kaddr = (unsigned char *)page_address(page);
offset = 0;
}
@@ -3129,7 +3173,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
blk_addr = GET_SUM_BLOCK(sbi, segno);
}
- new = get_meta_page(sbi, blk_addr);
+ new = f2fs_get_meta_page(sbi, blk_addr);
sum = (struct f2fs_summary_block *)page_address(new);
if (IS_NODESEG(type)) {
@@ -3141,7 +3185,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
ns->ofs_in_node = 0;
}
} else {
- restore_node_summary(sbi, segno, sum);
+ f2fs_restore_node_summary(sbi, segno, sum);
}
}
@@ -3173,10 +3217,10 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
int err;
if (is_set_ckpt_flags(sbi, CP_COMPACT_SUM_FLAG)) {
- int npages = npages_for_summary_flush(sbi, true);
+ int npages = f2fs_npages_for_summary_flush(sbi, true);
if (npages >= 2)
- ra_meta_pages(sbi, start_sum_block(sbi), npages,
+ f2fs_ra_meta_pages(sbi, start_sum_block(sbi), npages,
META_CP, true);
/* restore for compacted data summary */
@@ -3185,7 +3229,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
}
if (__exist_node_summaries(sbi))
- ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
+ f2fs_ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
NR_CURSEG_TYPE - type, META_CP, true);
for (; type <= CURSEG_COLD_NODE; type++) {
@@ -3211,8 +3255,9 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr)
int written_size = 0;
int i, j;
- page = grab_meta_page(sbi, blkaddr++);
+ page = f2fs_grab_meta_page(sbi, blkaddr++);
kaddr = (unsigned char *)page_address(page);
+ memset(kaddr, 0, PAGE_SIZE);
/* Step 1: write nat cache */
seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA);
@@ -3235,8 +3280,9 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr)
for (j = 0; j < blkoff; j++) {
if (!page) {
- page = grab_meta_page(sbi, blkaddr++);
+ page = f2fs_grab_meta_page(sbi, blkaddr++);
kaddr = (unsigned char *)page_address(page);
+ memset(kaddr, 0, PAGE_SIZE);
written_size = 0;
}
summary = (struct f2fs_summary *)(kaddr + written_size);
@@ -3271,7 +3317,7 @@ static void write_normal_summaries(struct f2fs_sb_info *sbi,
write_current_sum_page(sbi, i, blkaddr + (i - type));
}
-void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
+void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
{
if (is_set_ckpt_flags(sbi, CP_COMPACT_SUM_FLAG))
write_compacted_summaries(sbi, start_blk);
@@ -3279,12 +3325,12 @@ void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
write_normal_summaries(sbi, start_blk, CURSEG_HOT_DATA);
}
-void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
+void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
{
write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE);
}
-int lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
+int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
unsigned int val, int alloc)
{
int i;
@@ -3309,7 +3355,7 @@ int lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
static struct page *get_current_sit_page(struct f2fs_sb_info *sbi,
unsigned int segno)
{
- return get_meta_page(sbi, current_sit_addr(sbi, segno));
+ return f2fs_get_meta_page(sbi, current_sit_addr(sbi, segno));
}
static struct page *get_next_sit_page(struct f2fs_sb_info *sbi,
@@ -3322,7 +3368,7 @@ static struct page *get_next_sit_page(struct f2fs_sb_info *sbi,
src_off = current_sit_addr(sbi, start);
dst_off = next_sit_addr(sbi, src_off);
- page = grab_meta_page(sbi, dst_off);
+ page = f2fs_grab_meta_page(sbi, dst_off);
seg_info_to_sit_page(sbi, page, start);
set_page_dirty(page);
@@ -3418,7 +3464,7 @@ static void remove_sits_in_journal(struct f2fs_sb_info *sbi)
* CP calls this function, which flushes SIT entries including sit_journal,
* and moves prefree segs to free segs.
*/
-void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
{
struct sit_info *sit_i = SIT_I(sbi);
unsigned long *bitmap = sit_i->dirty_sentries_bitmap;
@@ -3477,6 +3523,11 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
int offset, sit_offset;
se = get_seg_entry(sbi, segno);
+#ifdef CONFIG_F2FS_CHECK_FS
+ if (memcmp(se->cur_valid_map, se->cur_valid_map_mir,
+ SIT_VBLOCK_MAP_SIZE))
+ f2fs_bug_on(sbi, 1);
+#endif
/* add discard candidates */
if (!(cpc->reason & CP_DISCARD)) {
@@ -3485,17 +3536,21 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
}
if (to_journal) {
- offset = lookup_journal_in_cursum(journal,
+ offset = f2fs_lookup_journal_in_cursum(journal,
SIT_JOURNAL, segno, 1);
f2fs_bug_on(sbi, offset < 0);
segno_in_journal(journal, offset) =
cpu_to_le32(segno);
seg_info_to_raw_sit(se,
&sit_in_journal(journal, offset));
+ check_block_count(sbi, segno,
+ &sit_in_journal(journal, offset));
} else {
sit_offset = SIT_ENTRY_OFFSET(sit_i, segno);
seg_info_to_raw_sit(se,
&raw_sit->entries[sit_offset]);
+ check_block_count(sbi, segno,
+ &raw_sit->entries[sit_offset]);
}
__clear_bit(segno, bitmap);
@@ -3543,8 +3598,10 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
SM_I(sbi)->sit_info = sit_i;
- sit_i->sentries = f2fs_kvzalloc(sbi, MAIN_SEGS(sbi) *
- sizeof(struct seg_entry), GFP_KERNEL);
+ sit_i->sentries =
+ f2fs_kvzalloc(sbi, array_size(sizeof(struct seg_entry),
+ MAIN_SEGS(sbi)),
+ GFP_KERNEL);
if (!sit_i->sentries)
return -ENOMEM;
@@ -3584,8 +3641,10 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
return -ENOMEM;
if (sbi->segs_per_sec > 1) {
- sit_i->sec_entries = f2fs_kvzalloc(sbi, MAIN_SECS(sbi) *
- sizeof(struct sec_entry), GFP_KERNEL);
+ sit_i->sec_entries =
+ f2fs_kvzalloc(sbi, array_size(sizeof(struct sec_entry),
+ MAIN_SECS(sbi)),
+ GFP_KERNEL);
if (!sit_i->sec_entries)
return -ENOMEM;
}
@@ -3661,7 +3720,8 @@ static int build_curseg(struct f2fs_sb_info *sbi)
struct curseg_info *array;
int i;
- array = f2fs_kzalloc(sbi, sizeof(*array) * NR_CURSEG_TYPE, GFP_KERNEL);
+ array = f2fs_kzalloc(sbi, array_size(NR_CURSEG_TYPE, sizeof(*array)),
+ GFP_KERNEL);
if (!array)
return -ENOMEM;
@@ -3694,9 +3754,10 @@ static int build_sit_entries(struct f2fs_sb_info *sbi)
unsigned int i, start, end;
unsigned int readed, start_blk = 0;
int err = 0;
+ block_t total_node_blocks = 0;
do {
- readed = ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES,
+ readed = f2fs_ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES,
META_SIT, true);
start = start_blk * sit_i->sents_per_block;
@@ -3716,6 +3777,8 @@ static int build_sit_entries(struct f2fs_sb_info *sbi)
if (err)
return err;
seg_info_from_raw_sit(se, &sit);
+ if (IS_NODESEG(se->type))
+ total_node_blocks += se->valid_blocks;
/* build discard map only one time */
if (f2fs_discard_en(sbi)) {
@@ -3744,15 +3807,28 @@ static int build_sit_entries(struct f2fs_sb_info *sbi)
unsigned int old_valid_blocks;
start = le32_to_cpu(segno_in_journal(journal, i));
+ if (start >= MAIN_SEGS(sbi)) {
+ f2fs_msg(sbi->sb, KERN_ERR,
+ "Wrong journal entry on segno %u",
+ start);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ err = -EINVAL;
+ break;
+ }
+
se = &sit_i->sentries[start];
sit = sit_in_journal(journal, i);
old_valid_blocks = se->valid_blocks;
+ if (IS_NODESEG(se->type))
+ total_node_blocks -= old_valid_blocks;
err = check_block_count(sbi, start, &sit);
if (err)
break;
seg_info_from_raw_sit(se, &sit);
+ if (IS_NODESEG(se->type))
+ total_node_blocks += se->valid_blocks;
if (f2fs_discard_en(sbi)) {
if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) {
@@ -3761,16 +3837,28 @@ static int build_sit_entries(struct f2fs_sb_info *sbi)
} else {
memcpy(se->discard_map, se->cur_valid_map,
SIT_VBLOCK_MAP_SIZE);
- sbi->discard_blks += old_valid_blocks -
- se->valid_blocks;
+ sbi->discard_blks += old_valid_blocks;
+ sbi->discard_blks -= se->valid_blocks;
}
}
- if (sbi->segs_per_sec > 1)
+ if (sbi->segs_per_sec > 1) {
get_sec_entry(sbi, start)->valid_blocks +=
- se->valid_blocks - old_valid_blocks;
+ se->valid_blocks;
+ get_sec_entry(sbi, start)->valid_blocks -=
+ old_valid_blocks;
+ }
}
up_read(&curseg->journal_rwsem);
+
+ if (!err && total_node_blocks != valid_node_count(sbi)) {
+ f2fs_msg(sbi->sb, KERN_ERR,
+ "SIT is corrupted node# %u vs %u",
+ total_node_blocks, valid_node_count(sbi));
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ err = -EINVAL;
+ }
+
return err;
}
@@ -3869,7 +3957,7 @@ static void init_min_max_mtime(struct f2fs_sb_info *sbi)
down_write(&sit_i->sentry_lock);
- sit_i->min_mtime = LLONG_MAX;
+ sit_i->min_mtime = ULLONG_MAX;
for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) {
unsigned int i;
@@ -3883,11 +3971,11 @@ static void init_min_max_mtime(struct f2fs_sb_info *sbi)
if (sit_i->min_mtime > mtime)
sit_i->min_mtime = mtime;
}
- sit_i->max_mtime = get_mtime(sbi);
+ sit_i->max_mtime = get_mtime(sbi, false);
up_write(&sit_i->sentry_lock);
}
-int build_segment_manager(struct f2fs_sb_info *sbi)
+int f2fs_build_segment_manager(struct f2fs_sb_info *sbi)
{
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
@@ -3924,7 +4012,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
init_rwsem(&sm_info->curseg_lock);
if (!f2fs_readonly(sbi->sb)) {
- err = create_flush_cmd_control(sbi);
+ err = f2fs_create_flush_cmd_control(sbi);
if (err)
return err;
}
@@ -4049,13 +4137,13 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi)
kfree(sit_i);
}
-void destroy_segment_manager(struct f2fs_sb_info *sbi)
+void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi)
{
struct f2fs_sm_info *sm_info = SM_I(sbi);
if (!sm_info)
return;
- destroy_flush_cmd_control(sbi, true);
+ f2fs_destroy_flush_cmd_control(sbi, true);
destroy_discard_cmd_control(sbi);
destroy_dirty_segmap(sbi);
destroy_curseg(sbi);
@@ -4065,7 +4153,7 @@ void destroy_segment_manager(struct f2fs_sb_info *sbi)
kfree(sm_info);
}
-int __init create_segment_manager_caches(void)
+int __init f2fs_create_segment_manager_caches(void)
{
discard_entry_slab = f2fs_kmem_cache_create("discard_entry",
sizeof(struct discard_entry));
@@ -4098,7 +4186,7 @@ fail:
return -ENOMEM;
}
-void destroy_segment_manager_caches(void)
+void f2fs_destroy_segment_manager_caches(void)
{
kmem_cache_destroy(sit_entry_set_slab);
kmem_cache_destroy(discard_cmd_slab);