From: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
To: Ryusuke Konishi
<konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v2 6/9] nilfs2: add tracking of block deletions and updates
Date: Sat, 09 May 2015 22:02:08 +0200 [thread overview]
Message-ID: <554E67C0.1050309@gmx.net> (raw)
In-Reply-To: <20150509.160512.1087140271092828536.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
On 2015-05-09 09:05, Ryusuke Konishi wrote:
> On Sun, 3 May 2015 12:05:19 +0200, Andreas Rohner wrote:
>> This patch adds tracking of block deletions and updates for all files.
>> It uses the fact, that for every block, NILFS2 keeps an entry in the
>> DAT file and stores the checkpoint where it was created, deleted or
>> overwritten. So whenever a block is deleted or overwritten
>> nilfs_dat_commit_end() is called to update the DAT entry. At this
>> point this patch simply decrements the su_nlive_blks field of the
>> corresponding segment. The value of su_nlive_blks is set at segment
>> creation time.
>>
>> The DAT file itself has of course no DAT entries for its own blocks, but
>> it still has to propagate deletions and updates to its btree. When this
>> happens this patch again decrements the su_nlive_blks field of the
>> corresponding segment.
>>
>> The new feature compatibility flag NILFS_FEATURE_COMPAT_TRACK_LIVE_BLKS
>> can be used to enable or disable the block tracking at any time.
>>
>> Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
>> ---
>> fs/nilfs2/btree.c | 33 ++++++++++++++++++++++++++++++---
>> fs/nilfs2/dat.c | 15 +++++++++++++--
>> fs/nilfs2/direct.c | 20 +++++++++++++++-----
>> fs/nilfs2/page.c | 6 ++++--
>> fs/nilfs2/page.h | 3 +++
>> fs/nilfs2/segbuf.c | 3 +++
>> fs/nilfs2/segbuf.h | 5 +++++
>> fs/nilfs2/segment.c | 48 +++++++++++++++++++++++++++++++++++++-----------
>> fs/nilfs2/sufile.c | 17 ++++++++++++++++-
>> fs/nilfs2/sufile.h | 3 ++-
>> 10 files changed, 128 insertions(+), 25 deletions(-)
>>
>> diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
>> index 059f371..d3b2763 100644
>> --- a/fs/nilfs2/btree.c
>> +++ b/fs/nilfs2/btree.c
>> @@ -30,6 +30,7 @@
>> #include "btree.h"
>> #include "alloc.h"
>> #include "dat.h"
>> +#include "sufile.h"
>>
>> static void __nilfs_btree_init(struct nilfs_bmap *bmap);
>>
>
>> @@ -1889,9 +1890,35 @@ static int nilfs_btree_propagate_p(struct nilfs_bmap *btree,
>> int level,
>> struct buffer_head *bh)
>> {
>> - while ((++level < nilfs_btree_height(btree) - 1) &&
>> - !buffer_dirty(path[level].bp_bh))
>> - mark_buffer_dirty(path[level].bp_bh);
>> + struct the_nilfs *nilfs = btree->b_inode->i_sb->s_fs_info;
>> + struct nilfs_btree_node *node;
>> + __u64 ptr, segnum;
>> + int ncmax, vol, counted;
>> +
>> + vol = buffer_nilfs_volatile(bh);
>> + counted = buffer_nilfs_counted(bh);
>> + set_buffer_nilfs_counted(bh);
>> +
>> + while (++level < nilfs_btree_height(btree)) {
>> + if (!vol && !counted && nilfs_feature_track_live_blks(nilfs)) {
>> + node = nilfs_btree_get_node(btree, path, level, &ncmax);
>> + ptr = nilfs_btree_node_get_ptr(node,
>> + path[level].bp_index,
>> + ncmax);
>> + segnum = nilfs_get_segnum_of_block(nilfs, ptr);
>> + nilfs_sufile_dec_nlive_blks(nilfs->ns_sufile, segnum);
>> + }
>> +
>> + if (path[level].bp_bh) {
>> + if (buffer_dirty(path[level].bp_bh))
>> + break;
>> +
>> + mark_buffer_dirty(path[level].bp_bh);
>> + vol = buffer_nilfs_volatile(path[level].bp_bh);
>> + counted = buffer_nilfs_counted(path[level].bp_bh);
>> + set_buffer_nilfs_counted(path[level].bp_bh);
>> + }
>> + }
>>
>> return 0;
>> }
>
> Consider the following comments:
>
> - Please use volatile flag also for the duplication check instead of
> adding nilfs_counted flag.
I thought volatile already means something else. I wasn't sure if could
use it. I will change it and remove the nilfs_counted flag.
> - btree.c, direct.c, and dat.c shouldn't refer SUFILE directly.
> Please add a wrapper function like "nilfs_dec_nlive_blks(nilfs, blocknr)"
> to the implementation of the_nilfs.c, and use it instead.
> - To clarify implementation separate function to update pointers
> like nilfs_btree_propagate_v() is doing.
Ok.
> - The return value of nilfs_sufile_dec_nlive_blks() looks to be ignored
> intentionally. Please add a comment explaining why you do so.
I just thought, that the block tracking isn't important enough to cause
a fatal error. I should at least use the WARN_ON() macro. Do you think I
should return possible errors?
> e.g.
>
> static void nilfs_btree_update_p(struct nilfs_bmap *btree,
> struct nilfs_btree_path *path, int level)
> {
> struct the_nilfs *nilfs = btree->b_inode->i_sb->s_fs_info;
> struct nilfs_btree_node *parent;
> __u64 ptr;
> int ncmax;
>
> if (nilfs_feature_track_live_blks(nilfs)) {
> parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
> ptr = nilfs_btree_node_get_ptr(parent,
> path[level + 1].bp_index,
> ncmax);
> nilfs_dec_nlive_blks(nilfs, ptr);
> /* (Please add a comment explaining why we ignore the return value) */
> }
> set_buffer_nilfs_volatile(path[level].bp_bh);
> }
>
> static int nilfs_btree_propagate_p(struct nilfs_bmap *btree,
> struct nilfs_btree_path *path,
> int level,
> struct buffer_head *bh)
> {
> /*
> * Update pointer to the given dirty buffer. If the buffer is
> * marked volatile, it shouldn't be updated because it's
> * either a newly created buffer or an already updated one.
> */
> if (!buffer_nilfs_volatile(path[level].bp_bh))
> nilfs_btree_update_p(btree, path, level);
>
> /*
> * Mark upper nodes dirty and update their pointers unless
> * they're already marked dirty.
> */
> while (++level < nilfs_btree_height(btree) - 1 &&
> !buffer_dirty(path[level].bp_bh)) {
>
> WARN_ON(buffer_nilfs_volatile(path[level].bp_bh));
> nilfs_btree_update_p(btree, path, level);
> mark_buffer_dirty(path[level].bp_bh);
> }
> return 0;
> }
>
>> diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
>> index 0d5fada..9c2fc32 100644
>> --- a/fs/nilfs2/dat.c
>> +++ b/fs/nilfs2/dat.c
>> @@ -28,6 +28,7 @@
>> #include "mdt.h"
>> #include "alloc.h"
>> #include "dat.h"
>> +#include "sufile.h"
>>
>>
>> #define NILFS_CNO_MIN ((__u64)1)
>> @@ -188,9 +189,10 @@ void nilfs_dat_commit_end(struct inode *dat, struct nilfs_palloc_req *req,
>> int dead)
>> {
>> struct nilfs_dat_entry *entry;
>> - __u64 start, end;
>> + __u64 start, end, segnum;
>> sector_t blocknr;
>> void *kaddr;
>> + struct the_nilfs *nilfs;
>>
>> kaddr = kmap_atomic(req->pr_entry_bh->b_page);
>> entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
>> @@ -206,8 +208,17 @@ void nilfs_dat_commit_end(struct inode *dat, struct nilfs_palloc_req *req,
>>
>> if (blocknr == 0)
>> nilfs_dat_commit_free(dat, req);
>> - else
>
> Add braces around nilfs_dat_commit_free() since you add multiple
> sentences in the else clause. See the chapter 3 of CodingStyle file.
Ok sorry for that.
>> + else {
>> nilfs_dat_commit_entry(dat, req);
>> +
>> + nilfs = dat->i_sb->s_fs_info;
>> +
>> + if (nilfs_feature_track_live_blks(nilfs)) {
>
>> + segnum = nilfs_get_segnum_of_block(nilfs, blocknr);
>> + nilfs_sufile_dec_nlive_blks(nilfs->ns_sufile, segnum);
>
> Ditto. Call nilfs_dec_nlive_blks(nilfs, blocknr) instead and do not
> to add dependency to SUFILE in dat.c.
>
>> + }
>> + }
>> +
>> }
>>
>> void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req)
>> diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
>> index ebf89fd..42704eb 100644
>> --- a/fs/nilfs2/direct.c
>> +++ b/fs/nilfs2/direct.c
>> @@ -26,6 +26,7 @@
>> #include "direct.h"
>> #include "alloc.h"
>> #include "dat.h"
>> +#include "sufile.h"
>>
>> static inline __le64 *nilfs_direct_dptrs(const struct nilfs_bmap *direct)
>> {
>> @@ -268,18 +269,27 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
>> static int nilfs_direct_propagate(struct nilfs_bmap *bmap,
>> struct buffer_head *bh)
>> {
>> + struct the_nilfs *nilfs = bmap->b_inode->i_sb->s_fs_info;
>> struct nilfs_palloc_req oldreq, newreq;
>> struct inode *dat;
>> - __u64 key;
>> - __u64 ptr;
>> + __u64 key, ptr, segnum;
>> int ret;
>>
>> - if (!NILFS_BMAP_USE_VBN(bmap))
>> - return 0;
>> -
>
>> dat = nilfs_bmap_get_dat(bmap);
>> key = nilfs_bmap_data_get_key(bmap, bh);
>> ptr = nilfs_direct_get_ptr(bmap, key);
>> +
>
>> + if (unlikely(!NILFS_BMAP_USE_VBN(bmap))) {
>> + if (!buffer_nilfs_volatile(bh) && !buffer_nilfs_counted(bh) &&
>> + nilfs_feature_track_live_blks(nilfs)) {
>> + set_buffer_nilfs_counted(bh);
>> + segnum = nilfs_get_segnum_of_block(nilfs, ptr);
>> +
>> + nilfs_sufile_dec_nlive_blks(nilfs->ns_sufile, segnum);
>> + }
>> + return 0;
>> + }
>
> Use the volatile flag also for duplication check, and do not use
> unlikely() marcro when testing "!NILFS_BMAP_USE_VBN(bmap)". It's
> not exceptional as error:
>
> if (!NILFS_BMAP_USE_VBN(bmap)) {
> if (!buffer_nilfs_volatile(bh)) {
> if (nilfs_feature_track_live_blks(nilfs))
> nilfs_dec_nlive_blks(nilfs, ptr);
> set_buffer_nilfs_volatile(bh);
> }
> return 0;
> }
During my tests, this was only called once directly after the first
bytes are written on a newly formatted volume. This can only be true for
the DAT-File and the DAT-File is very unlikely to be small enough to use
the direct bmap, except on a newly formatted volume. Do you mean, that
unlikely() should only be used for errors?
>> +
>> if (!buffer_nilfs_volatile(bh)) {
>> oldreq.pr_entry_nr = ptr;
>> newreq.pr_entry_nr = ptr;
>> diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
>> index 45d650a..fd21b43 100644
>> --- a/fs/nilfs2/page.c
>> +++ b/fs/nilfs2/page.c
>> @@ -92,7 +92,8 @@ void nilfs_forget_buffer(struct buffer_head *bh)
>> const unsigned long clear_bits =
>> (1 << BH_Uptodate | 1 << BH_Dirty | 1 << BH_Mapped |
>> 1 << BH_Async_Write | 1 << BH_NILFS_Volatile |
>> - 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected);
>> + 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected |
>
>> + 1 << BH_NILFS_Counted);
>
> You don't have to add nilfs_counted flag as I mentioned above. Remove
> this.
>
>>
>> lock_buffer(bh);
>> set_mask_bits(&bh->b_state, clear_bits, 0);
>> @@ -422,7 +423,8 @@ void nilfs_clear_dirty_page(struct page *page, bool silent)
>> const unsigned long clear_bits =
>> (1 << BH_Uptodate | 1 << BH_Dirty | 1 << BH_Mapped |
>> 1 << BH_Async_Write | 1 << BH_NILFS_Volatile |
>> - 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected);
>> + 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected |
>
>> + 1 << BH_NILFS_Counted);
>
> Ditto.
>
>>
>> bh = head = page_buffers(page);
>> do {
>> diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
>> index a43b828..4e35814 100644
>> --- a/fs/nilfs2/page.h
>> +++ b/fs/nilfs2/page.h
>> @@ -36,12 +36,15 @@ enum {
>> BH_NILFS_Volatile,
>> BH_NILFS_Checked,
>> BH_NILFS_Redirected,
>> + BH_NILFS_Counted,
>
> Ditto.
>
>> };
>>
>> BUFFER_FNS(NILFS_Node, nilfs_node) /* nilfs node buffers */
>> BUFFER_FNS(NILFS_Volatile, nilfs_volatile)
>> BUFFER_FNS(NILFS_Checked, nilfs_checked) /* buffer is verified */
>> BUFFER_FNS(NILFS_Redirected, nilfs_redirected) /* redirected to a copy */
>
>> +/* counted by propagate_p for segment usage */
>> +BUFFER_FNS(NILFS_Counted, nilfs_counted)
>
> Ditto.
>
>>
>>
>> int __nilfs_clear_page_dirty(struct page *);
>> diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
>> index dc3a9efd..dabb65b 100644
>> --- a/fs/nilfs2/segbuf.c
>> +++ b/fs/nilfs2/segbuf.c
>> @@ -57,6 +57,9 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
>> INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
>> INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
>> segbuf->sb_super_root = NULL;
>
>> + segbuf->sb_flags = 0;
>
> You don't have to add sb_flags. Use sci->sc_stage.flags instead
> because the flag is used to manage internal state of segment
> construction rather than the state of segbuf.
Yes that is true. I'll change that.
>> + segbuf->sb_nlive_blks = 0;
>> + segbuf->sb_nsnapshot_blks = 0;
>>
>> init_completion(&segbuf->sb_bio_event);
>> atomic_set(&segbuf->sb_err, 0);
>> diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
>> index b04f08c..a802f61 100644
>> --- a/fs/nilfs2/segbuf.h
>> +++ b/fs/nilfs2/segbuf.h
>> @@ -83,6 +83,9 @@ struct nilfs_segment_buffer {
>> sector_t sb_fseg_start, sb_fseg_end;
>> sector_t sb_pseg_start;
>> unsigned sb_rest_blocks;
>
>> + int sb_flags;
>
> ditto.
>
>> + __u32 sb_nlive_blks;
>> + __u32 sb_nsnapshot_blks;
>>
>> /* Buffers */
>> struct list_head sb_segsum_buffers;
>> @@ -95,6 +98,8 @@ struct nilfs_segment_buffer {
>> struct completion sb_bio_event;
>> };
>>
>> +#define NILFS_SEGBUF_SUSET BIT(0) /* segment usage has been set */
>> +
>
> Ditto.
>
>> #define NILFS_LIST_SEGBUF(head) \
>> list_entry((head), struct nilfs_segment_buffer, sb_list)
>> #define NILFS_NEXT_SEGBUF(segbuf) NILFS_LIST_SEGBUF((segbuf)->sb_list.next)
>> diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
>> index c6abbad9..14e76c3 100644
>> --- a/fs/nilfs2/segment.c
>> +++ b/fs/nilfs2/segment.c
>> @@ -762,7 +762,8 @@ static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
>> ret++;
>> if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile))
>> ret++;
>> - if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile))
>> + if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile) ||
>> + nilfs_sufile_cache_dirty(nilfs->ns_sufile))
>> ret++;
>> if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat))
>> ret++;
>> @@ -1368,36 +1369,49 @@ static void nilfs_free_incomplete_logs(struct list_head *logs,
>> }
>>
>> static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
>> - struct inode *sufile)
>> + struct the_nilfs *nilfs)
>
> Do not change the sufile argument to nilfs. It's not necessary
> for this change.
Ok.
>> {
>> struct nilfs_segment_buffer *segbuf;
>> - unsigned long live_blocks;
>> + struct inode *sufile = nilfs->ns_sufile;
>> + unsigned long nblocks;
>> int ret;
>>
>> list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
>> - live_blocks = segbuf->sb_sum.nblocks +
>> + nblocks = segbuf->sb_sum.nblocks +
>> (segbuf->sb_pseg_start - segbuf->sb_fseg_start);
>
>> ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
>> - live_blocks,
>> + nblocks,
>> + segbuf->sb_nlive_blks,
>> + segbuf->sb_nsnapshot_blks,
>> sci->sc_seg_ctime);
>
> With this change, two different semantics, "set" and "modify", are
> mixed up in the arguments of nilfs_sufile_set_segment_usage(). It's
> bad and confusing.
>
> Please change nilfs_sufile_set_segment_usage() function, for instance,
> to nilfs_sufile_modify_segment_usage() and rewrite the above part
> so that all counter arguments are passed with the "modify" semantics.
Ok.
>> WARN_ON(ret); /* always succeed because the segusage is dirty */
>> +
>> + segbuf->sb_flags |= NILFS_SEGBUF_SUSET;
>
> Use sci->sc_stage.flags adding NILFS_CF_SUMOD flag. Note that the
> flag must be added also to NILFS_CF_HISTORY_MASK so that the flag will
> be cleared every time a new cycle starts in the loop of
> nilfs_segctor_do_construct().
Ok.
>> }
>> }
>>
>> -static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile)
>> +static void nilfs_cancel_segusage(struct list_head *logs,
>> + struct the_nilfs *nilfs)
>
> Ditto. Do not change the sufile argument to the pointer to nilfs
> object.
>
>> {
>> struct nilfs_segment_buffer *segbuf;
>> + struct inode *sufile = nilfs->ns_sufile;
>> + __s64 nlive_blks = 0, nsnapshot_blks = 0;
>> int ret;
>>
>> segbuf = NILFS_FIRST_SEGBUF(logs);
>
>> + if (segbuf->sb_flags & NILFS_SEGBUF_SUSET) {
>
> Ditto.
>
>> + nlive_blks = -(__s64)segbuf->sb_nlive_blks;
>> + nsnapshot_blks = -(__s64)segbuf->sb_nsnapshot_blks;
>> + }
>> ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
>> segbuf->sb_pseg_start -
>> - segbuf->sb_fseg_start, 0);
>> + segbuf->sb_fseg_start,
>> + nlive_blks, nsnapshot_blks, 0);
>
> Ditto.
>
>> WARN_ON(ret); /* always succeed because the segusage is dirty */
>>
>> list_for_each_entry_continue(segbuf, logs, sb_list) {
>> ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
>> - 0, 0);
>> + 0, 0, 0, 0);
>> WARN_ON(ret); /* always succeed */
>> }
>> }
>> @@ -1499,6 +1513,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
>> if (!nfinfo)
>> goto out;
>>
>> + segbuf->sb_nlive_blks = segbuf->sb_sum.nfileblk;
>> blocknr = segbuf->sb_pseg_start + segbuf->sb_sum.nsumblk;
>> ssp.bh = NILFS_SEGBUF_FIRST_BH(&segbuf->sb_segsum_buffers);
>> ssp.offset = sizeof(struct nilfs_segment_summary);
>> @@ -1728,7 +1743,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
>> nilfs_abort_logs(&logs, ret ? : err);
>>
>> list_splice_tail_init(&sci->sc_segbufs, &logs);
>> - nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
>> + nilfs_cancel_segusage(&logs, nilfs);
>> nilfs_free_incomplete_logs(&logs, nilfs);
>>
>> if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
>> @@ -1790,7 +1805,8 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
>> const unsigned long clear_bits =
>> (1 << BH_Dirty | 1 << BH_Async_Write |
>> 1 << BH_Delay | 1 << BH_NILFS_Volatile |
>> - 1 << BH_NILFS_Redirected);
>> + 1 << BH_NILFS_Redirected |
>> + 1 << BH_NILFS_Counted);
>
> Ditto. Stop to add nilfs_counted flag.
>
>>
>> set_mask_bits(&bh->b_state, clear_bits, set_bits);
>> if (bh == segbuf->sb_super_root) {
>> @@ -1995,7 +2011,14 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
>>
>> nilfs_segctor_fill_in_super_root(sci, nilfs);
>> }
>> - nilfs_segctor_update_segusage(sci, nilfs->ns_sufile);
>> +
>> + if (nilfs_feature_track_live_blks(nilfs)) {
>> + err = nilfs_sufile_flush_cache(nilfs->ns_sufile, 0,
>> + NULL);
>> + if (unlikely(err))
>> + goto failed_to_write;
>> + }
>> + nilfs_segctor_update_segusage(sci, nilfs);
>>
>> /* Write partial segments */
>> nilfs_segctor_prepare_write(sci);
>> @@ -2022,6 +2045,9 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
>> }
>> } while (sci->sc_stage.scnt != NILFS_ST_DONE);
>>
>
>> + if (nilfs_feature_track_live_blks(nilfs))
>> + nilfs_sufile_shrink_cache(nilfs->ns_sufile);
>
> As I mentioned on ahead, this shrink cache function should be called
> from a destructor of sufile which doesn't exist at present.
>
>> +
>> out:
>> nilfs_segctor_drop_written_files(sci, nilfs);
>> return err;
>> diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
>> index 80bbd87..9cd8820d 100644
>> --- a/fs/nilfs2/sufile.c
>> +++ b/fs/nilfs2/sufile.c
>> @@ -527,10 +527,13 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
>> * @sufile: inode of segment usage file
>> * @segnum: segment number
>> * @nblocks: number of live blocks in the segment
>> + * @nlive_blks: number of live blocks to add to the su_nlive_blks field
>> + * @nsnapshot_blks: number of snapshot blocks to add to su_nsnapshot_blks
>> * @modtime: modification time (option)
>> */
>> int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
>> - unsigned long nblocks, time_t modtime)
>> + unsigned long nblocks, __s64 nlive_blks,
>> + __s64 nsnapshot_blks, time_t modtime)
>
> As I mentioned above, this function should be renamed to
> nilfs_sufile_modify_segment_usage() and the semantics of nblocks,
> nlive_blks, nsnapshot_blks arguments should be uniformed to "modify"
> semantics.
>
> Also the types of these three counter arguments is not uniformed.
I used signed types for nlive_blks, nsnapshot_blks to be able to pass
negative numbers in nilfs_cancel_segusage().
Regards,
Andreas Rohner
> Regards,
> Ryusuke Konishi
>
>> {
>> struct buffer_head *bh;
>> struct nilfs_segment_usage *su;
>> @@ -548,6 +551,18 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
>> if (modtime)
>> su->su_lastmod = cpu_to_le64(modtime);
>> su->su_nblocks = cpu_to_le32(nblocks);
>> +
>> + if (nilfs_sufile_live_blks_ext_supported(sufile)) {
>> + nsnapshot_blks += le32_to_cpu(su->su_nsnapshot_blks);
>> + nsnapshot_blks = min_t(__s64, max_t(__s64, nsnapshot_blks, 0),
>> + nblocks);
>> + su->su_nsnapshot_blks = cpu_to_le32(nsnapshot_blks);
>> +
>> + nlive_blks += le32_to_cpu(su->su_nlive_blks);
>> + nlive_blks = min_t(__s64, max_t(__s64, nlive_blks, 0), nblocks);
>> + su->su_nlive_blks = cpu_to_le32(nlive_blks);
>> + }
>> +
>> kunmap_atomic(kaddr);
>>
>> mark_buffer_dirty(bh);
>> diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
>> index 662ab56..3466abb 100644
>> --- a/fs/nilfs2/sufile.h
>> +++ b/fs/nilfs2/sufile.h
>> @@ -60,7 +60,8 @@ int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end);
>> int nilfs_sufile_alloc(struct inode *, __u64 *);
>> int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
>> int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
>> - unsigned long nblocks, time_t modtime);
>> + unsigned long nblocks, __s64 nlive_blks,
>> + __s64 nsnapshot_blks, time_t modtime);
>> int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
>> ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
>> size_t);
>> --
>> 2.3.7
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-05-09 20:02 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-03 10:05 [PATCH v2 0/9] nilfs2: implementation of cost-benefit GC policy Andreas Rohner
[not found] ` <1430647522-14304-1-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-03 10:05 ` [PATCH v2 1/9] nilfs2: copy file system feature flags to the nilfs object Andreas Rohner
[not found] ` <1430647522-14304-2-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-09 1:54 ` Ryusuke Konishi
[not found] ` <20150509.105445.1816655707671265145.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-09 18:41 ` Andreas Rohner
2015-05-03 10:05 ` [PATCH v2 2/9] nilfs2: extend SUFILE on-disk format to enable tracking of live blocks Andreas Rohner
[not found] ` <1430647522-14304-3-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-09 2:24 ` Ryusuke Konishi
[not found] ` <20150509.112403.380867861504859109.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-09 18:47 ` Andreas Rohner
2015-05-03 10:05 ` [PATCH v2 3/9] nilfs2: introduce new feature flag for tracking " Andreas Rohner
[not found] ` <1430647522-14304-4-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-09 2:28 ` Ryusuke Konishi
[not found] ` <20150509.112814.2026089040966346261.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-09 18:53 ` Andreas Rohner
2015-05-03 10:05 ` [PATCH v2 4/9] nilfs2: add kmem_cache for SUFILE cache nodes Andreas Rohner
[not found] ` <1430647522-14304-5-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-09 2:41 ` Ryusuke Konishi
[not found] ` <20150509.114149.1643183669812667339.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-09 19:10 ` Andreas Rohner
[not found] ` <554E5B9D.7070807-hi6Y0CQ0nG0@public.gmane.org>
2015-05-10 0:05 ` Ryusuke Konishi
2015-05-03 10:05 ` [PATCH v2 5/9] nilfs2: add SUFILE cache for changes to su_nlive_blks field Andreas Rohner
[not found] ` <1430647522-14304-6-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-09 4:09 ` Ryusuke Konishi
[not found] ` <20150509.130900.223492430584220355.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-09 19:39 ` Andreas Rohner
[not found] ` <554E626A.2030503-hi6Y0CQ0nG0@public.gmane.org>
2015-05-10 2:09 ` Ryusuke Konishi
2015-05-03 10:05 ` [PATCH v2 6/9] nilfs2: add tracking of block deletions and updates Andreas Rohner
[not found] ` <1430647522-14304-7-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-09 7:05 ` Ryusuke Konishi
[not found] ` <20150509.160512.1087140271092828536.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-09 15:58 ` Ryusuke Konishi
2015-05-09 20:02 ` Andreas Rohner [this message]
[not found] ` <554E67C0.1050309-hi6Y0CQ0nG0@public.gmane.org>
2015-05-10 3:17 ` Ryusuke Konishi
2015-05-03 10:05 ` [PATCH v2 7/9] nilfs2: ensure that all dirty blocks are written out Andreas Rohner
[not found] ` <1430647522-14304-8-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-09 12:17 ` Ryusuke Konishi
[not found] ` <20150509.211741.1463241033923032068.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-09 20:18 ` Andreas Rohner
[not found] ` <554E6B7E.8070000-hi6Y0CQ0nG0@public.gmane.org>
2015-05-10 3:31 ` Ryusuke Konishi
2015-05-10 11:04 ` Andreas Rohner
[not found] ` <554F3B32.5050004-hi6Y0CQ0nG0@public.gmane.org>
2015-06-01 4:13 ` Ryusuke Konishi
[not found] ` <20150601.131320.1075202804382267027.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-06-01 14:33 ` Andreas Rohner
2015-05-03 10:05 ` [PATCH v2 8/9] nilfs2: correct live block tracking for GC protection period Andreas Rohner
[not found] ` <1430647522-14304-9-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-10 18:15 ` Ryusuke Konishi
[not found] ` <20150511.031512.1036934606749624197.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-10 18:23 ` Ryusuke Konishi
[not found] ` <20150511.032323.1250231827423193240.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-11 2:07 ` Ryusuke Konishi
[not found] ` <20150511.110726.725667075147435663.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-11 12:32 ` Andreas Rohner
2015-05-11 13:00 ` Andreas Rohner
[not found] ` <5550A7FC.4050709-hi6Y0CQ0nG0@public.gmane.org>
2015-05-12 14:31 ` Ryusuke Konishi
[not found] ` <20150512.233126.2206330706583570566.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-12 15:37 ` Andreas Rohner
2015-05-03 10:05 ` [PATCH v2 9/9] nilfs2: prevent starvation of segments protected by snapshots Andreas Rohner
[not found] ` <1430647522-14304-10-git-send-email-andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2015-05-20 14:43 ` Ryusuke Konishi
[not found] ` <20150520.234335.542615158366069430.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-20 15:49 ` Ryusuke Konishi
2015-05-22 18:10 ` Andreas Rohner
[not found] ` <555F70FD.6090500-hi6Y0CQ0nG0@public.gmane.org>
2015-05-31 16:45 ` Ryusuke Konishi
[not found] ` <20150601.014550.269184778137708369.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-05-31 18:13 ` Andreas Rohner
[not found] ` <556B4F58.9080801-hi6Y0CQ0nG0@public.gmane.org>
2015-06-01 0:44 ` Ryusuke Konishi
[not found] ` <20150601.094441.24658496988941562.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2015-06-01 14:45 ` Andreas Rohner
2015-05-03 10:07 ` [PATCH v2 1/5] nilfs-utils: extend SUFILE on-disk format to enable track live blocks Andreas Rohner
2015-05-03 10:07 ` [PATCH v2 2/5] nilfs-utils: add additional flags for nilfs_vdesc Andreas Rohner
2015-05-03 10:07 ` [PATCH v2 3/5] nilfs-utils: add support for tracking live blocks Andreas Rohner
2015-05-03 10:07 ` [PATCH v2 4/5] nilfs-utils: implement the tracking of live blocks for set_suinfo Andreas Rohner
2015-05-03 10:07 ` [PATCH v2 5/5] nilfs-utils: add support for greedy/cost-benefit policies Andreas Rohner
2015-05-05 3:09 ` [PATCH v2 0/9] nilfs2: implementation of cost-benefit GC policy Ryusuke Konishi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=554E67C0.1050309@gmx.net \
--to=andreas.rohner-hi6y0cq0ng0@public.gmane.org \
--cc=konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org \
--cc=linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).