diff --git a/kmod/src/data.c b/kmod/src/data.c index b101fc48..07491291 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -1147,7 +1147,6 @@ static int scoutfs_write_begin(struct file *file, struct scoutfs_inode_info *si = SCOUTFS_I(inode); struct super_block *sb = inode->i_sb; struct write_begin_data *wbd; - u64 new_size; u64 ind_seq; int ret; @@ -1166,19 +1165,10 @@ static int scoutfs_write_begin(struct file *file, goto out; } - /* - * Lock a size update item assuming we perform the full write. - * If If the write is inside i_size then we don't lock and - * nothing will be updated. Lock granularity is larger than - * pages so any size update in this call will be covered by the - * lock. If there's an error and we don't change i_size then - * the item update won't happen and the lock will be unused. - */ - new_size = max(pos + len, i_size_read(inode)); do { ret = scoutfs_inode_index_start(sb, &ind_seq) ?: scoutfs_inode_index_prepare(sb, &wbd->ind_locks, inode, - new_size, true) ?: + true) ?: scoutfs_inode_index_try_lock_hold(sb, &wbd->ind_locks, ind_seq, SIC_WRITE_BEGIN()); diff --git a/kmod/src/dir.c b/kmod/src/dir.c index 07f3c062..5ae5cc8b 100644 --- a/kmod/src/dir.c +++ b/kmod/src/dir.c @@ -531,7 +531,6 @@ out: static struct inode *lock_hold_create(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev, const struct scoutfs_item_count cnt, - u64 dir_size, u64 inode_size, struct scoutfs_lock **dir_lock, struct scoutfs_lock **inode_lock, struct list_head *ind_locks) @@ -566,9 +565,8 @@ static struct inode *lock_hold_create(struct inode *dir, struct dentry *dentry, retry: ret = scoutfs_inode_index_start(sb, &ind_seq) ?: - scoutfs_inode_index_prepare(sb, ind_locks, dir, dir_size, true) ?: - scoutfs_inode_index_prepare_ino(sb, ind_locks, ino, mode, - inode_size) ?: + scoutfs_inode_index_prepare(sb, ind_locks, dir, true) ?: + scoutfs_inode_index_prepare_ino(sb, ind_locks, ino, mode) ?: scoutfs_inode_index_try_lock_hold(sb, ind_locks, ind_seq, cnt); if (ret > 0) goto retry; @@ -607,16 +605,14 @@ static int scoutfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, struct scoutfs_lock *dir_lock = NULL; struct scoutfs_lock *inode_lock = NULL; LIST_HEAD(ind_locks); - u64 dir_size; u64 pos; int ret; if (dentry->d_name.len > SCOUTFS_NAME_LEN) return -ENAMETOOLONG; - dir_size = i_size_read(dir) + dentry->d_name.len; inode = lock_hold_create(dir, dentry, mode, rdev, - SIC_MKNOD(dentry->d_name.len), dir_size, 0, + SIC_MKNOD(dentry->d_name.len), &dir_lock, &inode_lock, &ind_locks); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -631,7 +627,7 @@ static int scoutfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, update_dentry_info(dentry, pos); - i_size_write(dir, dir_size); + i_size_write(dir, i_size_read(dir) + dentry->d_name.len); dir->i_mtime = dir->i_ctime = CURRENT_TIME; inode->i_mtime = inode->i_atime = inode->i_ctime = dir->i_mtime; @@ -704,10 +700,8 @@ static int scoutfs_link(struct dentry *old_dentry, dir_size = i_size_read(dir) + dentry->d_name.len; retry: ret = scoutfs_inode_index_start(sb, &ind_seq) ?: - scoutfs_inode_index_prepare(sb, &ind_locks, dir, - dir_size, false) ?: - scoutfs_inode_index_prepare(sb, &ind_locks, inode, - i_size_read(inode), false) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, dir, false) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, inode, false) ?: scoutfs_inode_index_try_lock_hold(sb, &ind_locks, ind_seq, SIC_LINK(dentry->d_name.len)); if (ret > 0) @@ -770,7 +764,6 @@ static int scoutfs_unlink(struct inode *dir, struct dentry *dentry) struct scoutfs_lock *inode_lock = NULL; struct scoutfs_lock *dir_lock = NULL; LIST_HEAD(ind_locks); - u64 dir_size; u64 ind_seq; int ret = 0; @@ -785,13 +778,10 @@ static int scoutfs_unlink(struct inode *dir, struct dentry *dentry) goto unlock; } - dir_size = i_size_read(dir) - dentry->d_name.len; retry: ret = scoutfs_inode_index_start(sb, &ind_seq) ?: - scoutfs_inode_index_prepare(sb, &ind_locks, dir, - dir_size, false) ?: - scoutfs_inode_index_prepare(sb, &ind_locks, inode, - i_size_read(inode), false) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, dir, false) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, inode, false) ?: scoutfs_inode_index_try_lock_hold(sb, &ind_locks, ind_seq, SIC_UNLINK(dentry->d_name.len)); if (ret > 0) @@ -819,7 +809,7 @@ retry: dir->i_ctime = ts; dir->i_mtime = ts; - i_size_write(dir, dir_size); + i_size_write(dir, i_size_read(dir) - dentry->d_name.len); inode->i_ctime = ts; drop_nlink(inode); @@ -1000,7 +990,6 @@ static int scoutfs_symlink(struct inode *dir, struct dentry *dentry, struct scoutfs_lock *dir_lock = NULL; struct scoutfs_lock *inode_lock = NULL; LIST_HEAD(ind_locks); - u64 dir_size; u64 pos; int ret; @@ -1013,10 +1002,8 @@ static int scoutfs_symlink(struct inode *dir, struct dentry *dentry, if (ret) return ret; - dir_size = i_size_read(dir) + dentry->d_name.len; inode = lock_hold_create(dir, dentry, S_IFLNK|S_IRWXUGO, 0, SIC_SYMLINK(dentry->d_name.len, name_len), - dir_size, name_len, &dir_lock, &inode_lock, &ind_locks); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -1036,7 +1023,7 @@ static int scoutfs_symlink(struct inode *dir, struct dentry *dentry, update_dentry_info(dentry, pos); - i_size_write(dir, dir_size); + i_size_write(dir, i_size_read(dir) + dentry->d_name.len); dir->i_mtime = dir->i_ctime = CURRENT_TIME; inode->i_ctime = dir->i_mtime; @@ -1397,8 +1384,6 @@ static int scoutfs_rename(struct inode *old_dir, struct dentry *old_dentry, bool del_new = false; bool ins_old = false; LIST_HEAD(ind_locks); - u64 old_size; - u64 uninitialized_var(new_size); u64 ind_seq; u64 new_pos; int ret; @@ -1451,30 +1436,14 @@ static int scoutfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (ret) goto out_unlock; - old_size = i_size_read(old_dir) - old_dentry->d_name.len; - if (!new_inode) { - if (old_dir != new_dir) - new_size = i_size_read(new_dir) + - new_dentry->d_name.len; - else - old_size += new_dentry->d_name.len; - } else { - if (old_dir != new_dir) - new_size = i_size_read(new_dir); - } - retry: ret = scoutfs_inode_index_start(sb, &ind_seq) ?: - scoutfs_inode_index_prepare(sb, &ind_locks, old_dir, - old_size, false) ?: - scoutfs_inode_index_prepare(sb, &ind_locks, old_inode, - i_size_read(old_inode), false) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, old_dir, false) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, old_inode, false) ?: (new_dir == old_dir ? 0 : - scoutfs_inode_index_prepare(sb, &ind_locks, new_dir, - new_size, false)) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, new_dir, false)) ?: (new_inode == NULL ? 0 : - scoutfs_inode_index_prepare(sb, &ind_locks, new_inode, - i_size_read(new_inode), false)) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, new_inode, false)) ?: scoutfs_inode_index_try_lock_hold(sb, &ind_locks, ind_seq, SIC_RENAME(old_dentry->d_name.len, new_dentry->d_name.len)); @@ -1540,9 +1509,10 @@ retry: /* the caller will use d_move to move the old_dentry into place */ update_dentry_info(old_dentry, new_pos); - i_size_write(old_dir, old_size); - if (old_dir != new_dir) - i_size_write(new_dir, new_size); + i_size_write(old_dir, i_size_read(old_dir) - old_dentry->d_name.len); + if (!new_inode) + i_size_write(new_dir, i_size_read(new_dir) + + new_dentry->d_name.len); if (new_inode) { drop_nlink(new_inode); diff --git a/kmod/src/format.h b/kmod/src/format.h index 03e49d7c..90d1d4c7 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -237,10 +237,9 @@ struct scoutfs_segment_block { #define SCOUTFS_MAX_ZONE 4 /* power of 2 is efficient */ /* inode index zone */ -#define SCOUTFS_INODE_INDEX_SIZE_TYPE 1 -#define SCOUTFS_INODE_INDEX_META_SEQ_TYPE 2 -#define SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE 3 -#define SCOUTFS_INODE_INDEX_NR 4 /* don't forget to update */ +#define SCOUTFS_INODE_INDEX_META_SEQ_TYPE 1 +#define SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE 2 +#define SCOUTFS_INODE_INDEX_NR 3 /* don't forget to update */ /* node zone */ #define SCOUTFS_FREE_BITS_SEGNO_TYPE 1 diff --git a/kmod/src/inode.c b/kmod/src/inode.c index e9ebd9a0..209bd6f9 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -214,8 +214,6 @@ static void set_item_info(struct scoutfs_inode_info *si, memset(si->item_minors, 0, sizeof(si->item_minors)); si->have_item = true; - si->item_majors[SCOUTFS_INODE_INDEX_SIZE_TYPE] = - le64_to_cpu(sinode->size); si->item_majors[SCOUTFS_INODE_INDEX_META_SEQ_TYPE] = le64_to_cpu(sinode->meta_seq); si->item_majors[SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE] = @@ -340,7 +338,7 @@ static int set_inode_size(struct inode *inode, struct scoutfs_lock *lock, if (!S_ISREG(inode->i_mode)) return 0; - ret = scoutfs_inode_index_lock_hold(inode, &ind_locks, new_size, true, + ret = scoutfs_inode_index_lock_hold(inode, &ind_locks, true, SIC_DIRTY_INODE()); if (ret) return ret; @@ -365,8 +363,7 @@ static int clear_truncate_flag(struct inode *inode, struct scoutfs_lock *lock) LIST_HEAD(ind_locks); int ret; - ret = scoutfs_inode_index_lock_hold(inode, &ind_locks, - i_size_read(inode), false, + ret = scoutfs_inode_index_lock_hold(inode, &ind_locks, false, SIC_DIRTY_INODE()); if (ret) return ret; @@ -445,8 +442,7 @@ int scoutfs_setattr(struct dentry *dentry, struct iattr *attr) } } - ret = scoutfs_inode_index_lock_hold(inode, &ind_locks, - i_size_read(inode), false, + ret = scoutfs_inode_index_lock_hold(inode, &ind_locks, false, SIC_DIRTY_INODE()); if (ret) goto out; @@ -691,7 +687,6 @@ static bool will_ins_index(struct scoutfs_inode_info *si, static bool inode_has_index(umode_t mode, u8 type) { switch(type) { - case SCOUTFS_INODE_INDEX_SIZE_TYPE: case SCOUTFS_INODE_INDEX_META_SEQ_TYPE: return true; case SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE: @@ -821,8 +816,6 @@ static int update_indices(struct super_block *sb, u64 major; u32 minor; } *upd, upds[] = { - { SCOUTFS_INODE_INDEX_SIZE_TYPE, - le64_to_cpu(sinode->size), 0 }, { SCOUTFS_INODE_INDEX_META_SEQ_TYPE, le64_to_cpu(sinode->meta_seq), 0 }, { SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE, @@ -900,8 +893,8 @@ void scoutfs_update_inode_item(struct inode *inode, struct scoutfs_lock *lock, * We map the item to coarse locks here. This reduces the number of * locks we track and means that when we later try to find the lock that * covers an item we can deal with the item update changing a little - * (seq, size) while still being covered. It does mean we have to share - * some logic with lock naming. + * while still being covered. It does mean we have to share some logic + * with lock naming. */ static int add_index_lock(struct list_head *list, u64 ino, u8 type, u64 major, u32 minor) @@ -979,7 +972,7 @@ static u64 upd_data_seq(struct scoutfs_sb_info *sbi, */ static int prepare_indices(struct super_block *sb, struct list_head *list, struct scoutfs_inode_info *si, u64 ino, - umode_t mode, u64 new_size, bool set_data_seq) + umode_t mode, bool set_data_seq) { struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); struct index_update { @@ -987,7 +980,6 @@ static int prepare_indices(struct super_block *sb, struct list_head *list, u64 major; u32 minor; } *upd, upds[] = { - { SCOUTFS_INODE_INDEX_SIZE_TYPE, new_size, 0}, { SCOUTFS_INODE_INDEX_META_SEQ_TYPE, sbi->trans_seq, 0}, { SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE, upd_data_seq(sbi, si, set_data_seq), 0}, @@ -1009,13 +1001,12 @@ static int prepare_indices(struct super_block *sb, struct list_head *list, } int scoutfs_inode_index_prepare(struct super_block *sb, struct list_head *list, - struct inode *inode, u64 new_size, - bool set_data_seq) + struct inode *inode, bool set_data_seq) { struct scoutfs_inode_info *si = SCOUTFS_I(inode); return prepare_indices(sb, list, si, scoutfs_ino(inode), - inode->i_mode, new_size, set_data_seq); + inode->i_mode, set_data_seq); } /* @@ -1026,9 +1017,9 @@ int scoutfs_inode_index_prepare(struct super_block *sb, struct list_head *list, */ int scoutfs_inode_index_prepare_ino(struct super_block *sb, struct list_head *list, u64 ino, - umode_t mode, u64 new_size) + umode_t mode) { - return prepare_indices(sb, list, NULL, ino, mode, new_size, true); + return prepare_indices(sb, list, NULL, ino, mode, true); } /* @@ -1045,8 +1036,6 @@ static int prepare_index_deletion(struct super_block *sb, u64 major; u32 minor; } *ind, inds[] = { - { SCOUTFS_INODE_INDEX_SIZE_TYPE, - le64_to_cpu(sinode->size), 0 }, { SCOUTFS_INODE_INDEX_META_SEQ_TYPE, le64_to_cpu(sinode->meta_seq), 0 }, { SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE, @@ -1120,7 +1109,7 @@ out: } int scoutfs_inode_index_lock_hold(struct inode *inode, struct list_head *list, - u64 size, bool set_data_seq, + bool set_data_seq, const struct scoutfs_item_count cnt) { struct super_block *sb = inode->i_sb; @@ -1129,7 +1118,7 @@ int scoutfs_inode_index_lock_hold(struct inode *inode, struct list_head *list, do { ret = scoutfs_inode_index_start(sb, &seq) ?: - scoutfs_inode_index_prepare(sb, list, inode, size, + scoutfs_inode_index_prepare(sb, list, inode, set_data_seq) ?: scoutfs_inode_index_try_lock_hold(sb, list, seq, cnt); } while (ret > 0); @@ -1191,9 +1180,7 @@ static int remove_index_items(struct super_block *sb, u64 ino, umode_t mode = le32_to_cpu(sinode->mode); int ret; - ret = remove_index(sb, ino, SCOUTFS_INODE_INDEX_SIZE_TYPE, - le64_to_cpu(sinode->size), 0, ind_locks) ?: - remove_index(sb, ino, SCOUTFS_INODE_INDEX_META_SEQ_TYPE, + ret = remove_index(sb, ino, SCOUTFS_INODE_INDEX_META_SEQ_TYPE, le64_to_cpu(sinode->meta_seq), 0, ind_locks); if (ret == 0 && S_ISREG(mode)) ret = remove_index(sb, ino, SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE, diff --git a/kmod/src/inode.h b/kmod/src/inode.h index ca35e4ba..6e5309be 100644 --- a/kmod/src/inode.h +++ b/kmod/src/inode.h @@ -64,16 +64,15 @@ struct inode *scoutfs_ilookup(struct super_block *sb, u64 ino); int scoutfs_inode_index_start(struct super_block *sb, u64 *seq); int scoutfs_inode_index_prepare(struct super_block *sb, struct list_head *list, - struct inode *inode, u64 new_size, - bool set_data_seq); + struct inode *inode, bool set_data_seq); int scoutfs_inode_index_prepare_ino(struct super_block *sb, struct list_head *list, u64 ino, - umode_t mode, u64 new_size); + umode_t mode); int scoutfs_inode_index_try_lock_hold(struct super_block *sb, struct list_head *list, u64 seq, const struct scoutfs_item_count cnt); int scoutfs_inode_index_lock_hold(struct inode *inode, struct list_head *list, - u64 size, bool set_data_seq, + bool set_data_seq, const struct scoutfs_item_count cnt); void scoutfs_inode_index_unlock(struct super_block *sb, struct list_head *list); diff --git a/kmod/src/ioctl.c b/kmod/src/ioctl.c index 9906e617..cb86dfa4 100644 --- a/kmod/src/ioctl.c +++ b/kmod/src/ioctl.c @@ -71,9 +71,7 @@ static long scoutfs_ioc_walk_inodes(struct file *file, unsigned long arg) trace_scoutfs_ioc_walk_inodes(sb, &walk); - if (walk.index == SCOUTFS_IOC_WALK_INODES_SIZE) - type = SCOUTFS_INODE_INDEX_SIZE_TYPE; - else if (walk.index == SCOUTFS_IOC_WALK_INODES_META_SEQ) + if (walk.index == SCOUTFS_IOC_WALK_INODES_META_SEQ) type = SCOUTFS_INODE_INDEX_META_SEQ_TYPE; else if (walk.index == SCOUTFS_IOC_WALK_INODES_DATA_SEQ) type = SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE; diff --git a/kmod/src/ioctl.h b/kmod/src/ioctl.h index e9a78db0..34917a34 100644 --- a/kmod/src/ioctl.h +++ b/kmod/src/ioctl.h @@ -51,8 +51,7 @@ struct scoutfs_ioctl_walk_inodes { } __packed; enum { - SCOUTFS_IOC_WALK_INODES_SIZE = 0, - SCOUTFS_IOC_WALK_INODES_META_SEQ, + SCOUTFS_IOC_WALK_INODES_META_SEQ = 0, SCOUTFS_IOC_WALK_INODES_DATA_SEQ, SCOUTFS_IOC_WALK_INODES_UNKNOWN, }; diff --git a/kmod/src/key.c b/kmod/src/key.c index d3695ede..3683bba9 100644 --- a/kmod/src/key.c +++ b/kmod/src/key.c @@ -211,7 +211,6 @@ typedef int (*key_printer_t)(char *buf, struct scoutfs_key_buf *key, static int pr_ino_idx(char *buf, struct scoutfs_key_buf *key, size_t size) { static char *type_strings[] = { - [SCOUTFS_INODE_INDEX_SIZE_TYPE] = "siz", [SCOUTFS_INODE_INDEX_META_SEQ_TYPE] = "msq", [SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE] = "dsq", }; @@ -329,8 +328,6 @@ static int pr_block_mapping(char *buf, struct scoutfs_key_buf *key, size_t size) } const static key_printer_t key_printers[SCOUTFS_MAX_ZONE][SCOUTFS_MAX_TYPE] = { - [SCOUTFS_INODE_INDEX_ZONE][SCOUTFS_INODE_INDEX_SIZE_TYPE] = - pr_ino_idx, [SCOUTFS_INODE_INDEX_ZONE][SCOUTFS_INODE_INDEX_META_SEQ_TYPE] = pr_ino_idx, [SCOUTFS_INODE_INDEX_ZONE][SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE] = diff --git a/kmod/src/lock.c b/kmod/src/lock.c index 1ca89642..446a97bf 100644 --- a/kmod/src/lock.c +++ b/kmod/src/lock.c @@ -947,16 +947,6 @@ int scoutfs_lock_global(struct super_block *sb, int mode, int flags, int type, * The seq indexes have natural batching and limits on the number of * keys per major value. * - * The file size index is very different. We don't control the - * distribution of sizes amongst inodes. We map ranges of sizes to a - * small set of locks by rounding the size down to groups of sizes - * identified by their highest set bit and two next significant bits. - * This results in ranges that increase by quarters of powers of two. - * (small sizes don't have enough bits for this scheme, they're all - * mapped to a range from 0 to 15.) two (0 and 1 are mapped to 0). Each - * lock then covers all the sizes in their range and all the inodes with - * those sizes. - * * This can also be used to find items that are covered by the same lock * because their starting keys are the same. */ @@ -964,32 +954,11 @@ void scoutfs_lock_get_index_item_range(u8 type, u64 major, u64 ino, struct scoutfs_inode_index_key *start, struct scoutfs_inode_index_key *end) { - u64 start_major; - u64 end_major; - int bit; + u64 start_major = major & ~SCOUTFS_LOCK_SEQ_GROUP_MASK; + u64 end_major = major | SCOUTFS_LOCK_SEQ_GROUP_MASK; - switch(type) { - case SCOUTFS_INODE_INDEX_SIZE_TYPE: - bit = major ? fls64(major) : 0; - if (bit < 5) { - /* sizes [ 0 .. 15 ] are in their own lock */ - start_major = 0; - end_major = 15; - } else { - /* last bit, 2 lesser bits, mask */ - start_major = major & (7ULL << (bit - 3)); - end_major = start_major + (1ULL << (bit - 3)) - 1; - } - break; - - case SCOUTFS_INODE_INDEX_META_SEQ_TYPE: - case SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE: - start_major = major & ~SCOUTFS_LOCK_SEQ_GROUP_MASK; - end_major = major | SCOUTFS_LOCK_SEQ_GROUP_MASK; - break; - default: - BUG(); - } + BUG_ON(type != SCOUTFS_INODE_INDEX_META_SEQ_TYPE && + type != SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE); if (start) { start->zone = SCOUTFS_INODE_INDEX_ZONE; diff --git a/kmod/src/xattr.c b/kmod/src/xattr.c index d01b0640..a21fba4a 100644 --- a/kmod/src/xattr.c +++ b/kmod/src/xattr.c @@ -321,8 +321,7 @@ static int scoutfs_xattr_set(struct dentry *dentry, const char *name, retry: ret = scoutfs_inode_index_start(sb, &ind_seq) ?: - scoutfs_inode_index_prepare(sb, &ind_locks, inode, - i_size_read(inode), false) ?: + scoutfs_inode_index_prepare(sb, &ind_locks, inode, false) ?: scoutfs_inode_index_try_lock_hold(sb, &ind_locks, ind_seq, SIC_XATTR_SET(name_len, size)); if (ret > 0)