lkml.org 
[lkml]   [2018]   [Mar]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC v2 44/83] Log operation: invalidate log entries
    Date
    From: Andiry Xu <jix024@cs.ucsd.edu>

    After new log entries are appended to the log, old log entries
    can be marked invalid to faciliate garbage collection.

    Signed-off-by: Andiry Xu <jix024@cs.ucsd.edu>
    ---
    fs/nova/log.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    fs/nova/log.h | 4 ++
    fs/nova/nova.h | 12 +++++
    3 files changed, 176 insertions(+)

    diff --git a/fs/nova/log.c b/fs/nova/log.c
    index c8b7d2e..d150f2e 100644
    --- a/fs/nova/log.c
    +++ b/fs/nova/log.c
    @@ -20,6 +20,88 @@
    #include "inode.h"
    #include "log.h"

    +static int nova_execute_invalidate_reassign_logentry(struct super_block *sb,
    + void *entry, enum nova_entry_type type, int reassign,
    + unsigned int num_free)
    +{
    + struct nova_file_write_entry *fw_entry;
    + int invalid = 0;
    +
    + switch (type) {
    + case FILE_WRITE:
    + fw_entry = (struct nova_file_write_entry *)entry;
    + if (reassign)
    + fw_entry->reassigned = 1;
    + if (num_free)
    + fw_entry->invalid_pages += num_free;
    + if (fw_entry->invalid_pages == fw_entry->num_pages)
    + invalid = 1;
    + break;
    + case DIR_LOG:
    + if (reassign) {
    + ((struct nova_dentry *)entry)->reassigned = 1;
    + } else {
    + ((struct nova_dentry *)entry)->invalid = 1;
    + invalid = 1;
    + }
    + break;
    + case SET_ATTR:
    + ((struct nova_setattr_logentry *)entry)->invalid = 1;
    + invalid = 1;
    + break;
    + case LINK_CHANGE:
    + ((struct nova_link_change_entry *)entry)->invalid = 1;
    + invalid = 1;
    + break;
    + default:
    + break;
    + }
    +
    + if (invalid) {
    + u64 addr = nova_get_addr_off(NOVA_SB(sb), entry);
    +
    + nova_inc_page_invalid_entries(sb, addr);
    + }
    +
    + nova_persist_entry(entry);
    + return 0;
    +}
    +
    +static int nova_invalidate_reassign_logentry(struct super_block *sb,
    + void *entry, enum nova_entry_type type, int reassign,
    + unsigned int num_free)
    +{
    + nova_execute_invalidate_reassign_logentry(sb, entry, type,
    + reassign, num_free);
    + return 0;
    +}
    +
    +static int nova_invalidate_logentry(struct super_block *sb, void *entry,
    + enum nova_entry_type type, unsigned int num_free)
    +{
    + return nova_invalidate_reassign_logentry(sb, entry, type, 0, num_free);
    +}
    +
    +static int nova_reassign_logentry(struct super_block *sb, void *entry,
    + enum nova_entry_type type)
    +{
    + return nova_invalidate_reassign_logentry(sb, entry, type, 1, 0);
    +}
    +
    +static inline int nova_invalidate_write_entry(struct super_block *sb,
    + struct nova_file_write_entry *entry, int reassign,
    + unsigned int num_free)
    +{
    + if (!entry)
    + return 0;
    +
    + if (num_free == 0 && entry->reassigned == 1)
    + return 0;
    +
    + return nova_invalidate_reassign_logentry(sb, entry, FILE_WRITE,
    + reassign, num_free);
    +}
    +
    static void nova_update_setattr_entry(struct inode *inode,
    struct nova_setattr_logentry *entry,
    struct nova_log_entry_info *entry_info)
    @@ -279,6 +361,27 @@ static int nova_append_setattr_entry(struct super_block *sb,
    return ret;
    }

    +/* Invalidate old setattr entry */
    +static int nova_invalidate_setattr_entry(struct super_block *sb,
    + u64 last_setattr)
    +{
    + struct nova_setattr_logentry *old_entry;
    + void *addr;
    + int ret;
    +
    + addr = (void *)nova_get_block(sb, last_setattr);
    + old_entry = (struct nova_setattr_logentry *)addr;
    +
    + /* Do not invalidate setsize entries */
    + if (!old_entry_freeable(sb, old_entry->epoch_id) ||
    + (old_entry->attr & ATTR_SIZE))
    + return 0;
    +
    + ret = nova_invalidate_logentry(sb, old_entry, SET_ATTR, 0);
    +
    + return ret;
    +}
    +
    static int nova_can_inplace_update_setattr(struct super_block *sb,
    struct nova_inode_info_header *sih, u64 epoch_id)
    {
    @@ -358,9 +461,35 @@ int nova_handle_setattr_operation(struct super_block *sb, struct inode *inode,
    nova_update_inode(sb, inode, pi, &update);
    }

    + /* Invalidate old setattr entry */
    + if (last_setattr)
    + nova_invalidate_setattr_entry(sb, last_setattr);
    +
    return 0;
    }

    +/* Invalidate old link change entry */
    +int nova_invalidate_link_change_entry(struct super_block *sb,
    + u64 old_link_change)
    +{
    + struct nova_link_change_entry *old_entry;
    + void *addr;
    + int ret;
    +
    + if (old_link_change == 0)
    + return 0;
    +
    + addr = (void *)nova_get_block(sb, old_link_change);
    + old_entry = (struct nova_link_change_entry *)addr;
    +
    + if (!old_entry_freeable(sb, old_entry->epoch_id))
    + return 0;
    +
    + ret = nova_invalidate_logentry(sb, old_entry, LINK_CHANGE, 0);
    +
    + return ret;
    +}
    +
    static int nova_can_inplace_update_lcentry(struct super_block *sb,
    struct nova_inode_info_header *sih, u64 epoch_id)
    {
    @@ -481,6 +610,37 @@ int nova_append_file_write_entry(struct super_block *sb, struct nova_inode *pi,
    return ret;
    }

    +/* Create dentry and delete dentry must be invalidated together */
    +int nova_invalidate_dentries(struct super_block *sb,
    + struct nova_inode_update *update)
    +{
    + struct nova_sb_info *sbi = NOVA_SB(sb);
    + struct nova_dentry *create_dentry;
    + struct nova_dentry *delete_dentry;
    + u64 create_curr, delete_curr;
    + int ret;
    +
    + create_dentry = update->create_dentry;
    + delete_dentry = update->delete_dentry;
    +
    + if (!create_dentry)
    + return 0;
    +
    + nova_reassign_logentry(sb, create_dentry, DIR_LOG);
    +
    + if (!old_entry_freeable(sb, create_dentry->epoch_id))
    + return 0;
    +
    + create_curr = nova_get_addr_off(sbi, create_dentry);
    + delete_curr = nova_get_addr_off(sbi, delete_dentry);
    +
    + nova_invalidate_logentry(sb, create_dentry, DIR_LOG, 0);
    +
    + ret = nova_invalidate_logentry(sb, delete_dentry, DIR_LOG, 0);
    +
    + return ret;
    +}
    +
    int nova_inplace_update_dentry(struct super_block *sb,
    struct inode *dir, struct nova_dentry *dentry, int link_change,
    u64 epoch_id)
    diff --git a/fs/nova/log.h b/fs/nova/log.h
    index 74891b3..2548083 100644
    --- a/fs/nova/log.h
    +++ b/fs/nova/log.h
    @@ -367,6 +367,8 @@ static inline int is_dir_init_entry(struct super_block *sb,
    int nova_handle_setattr_operation(struct super_block *sb, struct inode *inode,
    struct nova_inode *pi, unsigned int ia_valid, struct iattr *attr,
    u64 epoch_id);
    +int nova_invalidate_link_change_entry(struct super_block *sb,
    + u64 old_link_change);
    int nova_append_link_change_entry(struct super_block *sb,
    struct nova_inode *pi, struct inode *inode,
    struct nova_inode_update *update, u64 *old_linkc, u64 epoch_id);
    @@ -376,6 +378,8 @@ int nova_inplace_update_write_entry(struct super_block *sb,
    int nova_append_file_write_entry(struct super_block *sb, struct nova_inode *pi,
    struct inode *inode, struct nova_file_write_item *item,
    struct nova_inode_update *update);
    +int nova_invalidate_dentries(struct super_block *sb,
    + struct nova_inode_update *update);
    int nova_inplace_update_dentry(struct super_block *sb,
    struct inode *dir, struct nova_dentry *dentry, int link_change,
    u64 epoch_id);
    diff --git a/fs/nova/nova.h b/fs/nova/nova.h
    index 03c4991..6cf3c33 100644
    --- a/fs/nova/nova.h
    +++ b/fs/nova/nova.h
    @@ -328,6 +328,18 @@ struct inode_map {
    int freed;
    };

    +
    +/* Old entry is freeable if it is appended after the latest snapshot */
    +static inline int old_entry_freeable(struct super_block *sb, u64 epoch_id)
    +{
    + struct nova_sb_info *sbi = NOVA_SB(sb);
    +
    + if (epoch_id == sbi->s_epoch_id)
    + return 1;
    +
    + return 0;
    +}
    +
    #include "balloc.h"

    static inline unsigned long
    --
    2.7.4
    \
     
     \ /
      Last update: 2018-03-10 19:34    [W:5.782 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site