One more comment.
On Sat, 14 Mar 2015 12:51:09 +0900 (JST), Ryusuke Konishi wrote:
> On Tue, 24 Feb 2015 20:01:44 +0100, Andreas Rohner wrote:
>> @@ -1050,6 +1069,85 @@ ssize_t nilfs_sufile_set_suinfo(struct inode *sufile,
>> void *buf,
>> }
>>
>> /**
>> + * nilfs_sufile_fix_starving_segs - fix potentially starving segments
>> + * @sufile: inode of segment usage file
>> + *
>> + * Description: Scans for segments, which are potentially starving and
>> + * reduces the number of live blocks to less than half of the maximum
>> + * number of blocks in a segment. This way the segment is more likely to be
>> + * chosen by the GC. A segment is marked as potentially starving, if more
>> + * than half of the blocks it contains are protected by snapshots.
>> + *
>> + * Return Value: On success, 0 is returned and on error, one of the
>> + * following negative error codes is returned.
>> + *
>> + * %-EIO - I/O error.
>> + *
>> + * %-ENOMEM - Insufficient amount of memory available.
>> + */
>> +int nilfs_sufile_fix_starving_segs(struct inode *sufile)
>> +{
>> + struct buffer_head *su_bh;
>> + struct nilfs_segment_usage *su;
>> + size_t n, i, susz = NILFS_MDT(sufile)->mi_entry_size;
>> + struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
>> + void *kaddr;
>> + unsigned long nsegs, segusages_per_block;
>> + __u32 max_segblks = nilfs->ns_blocks_per_segment / 2;
>> + __u64 segnum = 0;
>> + int ret = 0, blkdirty, dirty = 0;
>> +
>> + down_write(&NILFS_MDT(sufile)->mi_sem);
>> +
>> + segusages_per_block = nilfs_sufile_segment_usages_per_block(sufile);
>> + nsegs = nilfs_sufile_get_nsegments(sufile);
>> +
>> + while (segnum < nsegs) {
>> + n = nilfs_sufile_segment_usages_in_block(sufile, segnum,
>> + nsegs - 1);
>> +
>> + ret = nilfs_sufile_get_segment_usage_block(sufile, segnum,
>> + 0, &su_bh);
>> + if (ret < 0) {
>> + if (ret != -ENOENT)
>> + goto out;
>> + /* hole */
>> + segnum += n;
>> + continue;
>> + }
>> +
>> + kaddr = kmap_atomic(su_bh->b_page);
>> + su = nilfs_sufile_block_get_segment_usage(sufile, segnum,
>> + su_bh, kaddr);
>> + blkdirty = 0;
>> + for (i = 0; i < n; ++i, ++segnum, su = (void *)su + susz) {
>> + if (le32_to_cpu(su->su_nsnapshot_blks) <= max_segblks)
>> + continue;
>> +
>> + if (su->su_nlive_blks <= max_segblks)
>> + continue;
>> +
>> + su->su_nlive_blks = max_segblks;
>> + blkdirty = 1;
>> + }
>> +
>> + kunmap_atomic(kaddr);
>> + if (blkdirty) {
>> + mark_buffer_dirty(su_bh);
>> + dirty = 1;
>> + }
>> + put_bh(su_bh);
Insert cond_resched() here to mitigate latency issue (mainly for the
environment in which voluntary preemption is turned off).
Regards,
Ryusuke Konishi
>> + }
>> +
>> +out:
>> + if (dirty)
>> + nilfs_mdt_mark_dirty(sufile);
>> +
>> + up_write(&NILFS_MDT(sufile)->mi_sem);
>> + return ret;
>> +}
>> +
>> +/**
>> * nilfs_sufile_trim_fs() - trim ioctl handle function
>> * @sufile: inode of segment usage file
>> * @range: fstrim_range structure
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html