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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.